From 69e6df07976a56b49e07c242cd6e5b2cbd2a578d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 23 Feb 2012 17:00:48 +1300 Subject: Move altoslib sources to top dir No sense having them live deep in the file system. Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 259 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 altoslib/AltosConvert.java (limited to 'altoslib/AltosConvert.java') diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java new file mode 100644 index 00000000..3527b575 --- /dev/null +++ b/altoslib/AltosConvert.java @@ -0,0 +1,259 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * Sensor data conversion functions + */ +package org.altusmetrum.AltosLib; + +public class AltosConvert { + /* + * Pressure Sensor Model, version 1.1 + * + * written by Holly Grimes + * + * Uses the International Standard Atmosphere as described in + * "A Quick Derivation relating altitude to air pressure" (version 1.03) + * from the Portland State Aerospace Society, except that the atmosphere + * is divided into layers with each layer having a different lapse rate. + * + * Lapse rate data for each layer was obtained from Wikipedia on Sept. 1, 2007 + * at site MAXIMUM_ALTITUDE) /* FIX ME: use sensor data to improve model */ + return 0; + + /* calculate the base temperature and pressure for the atmospheric layer + associated with the inputted altitude */ + for(layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1 && altitude > base_altitude[layer_number + 1]; layer_number++) { + delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number]; + if (lapse_rate[layer_number] == 0.0) { + exponent = GRAVITATIONAL_ACCELERATION * delta_z + / AIR_GAS_CONSTANT / base_temperature; + base_pressure *= Math.exp(exponent); + } + else { + base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; + exponent = GRAVITATIONAL_ACCELERATION / + (AIR_GAS_CONSTANT * lapse_rate[layer_number]); + base_pressure *= Math.pow(base, exponent); + } + base_temperature += delta_z * lapse_rate[layer_number]; + } + + /* calculate the pressure at the inputted altitude */ + delta_z = altitude - base_altitude[layer_number]; + if (lapse_rate[layer_number] == 0.0) { + exponent = GRAVITATIONAL_ACCELERATION * delta_z + / AIR_GAS_CONSTANT / base_temperature; + pressure = base_pressure * Math.exp(exponent); + } + else { + base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; + exponent = GRAVITATIONAL_ACCELERATION / + (AIR_GAS_CONSTANT * lapse_rate[layer_number]); + pressure = base_pressure * Math.pow(base, exponent); + } + + return pressure; + } + + +/* outputs the altitude associated with the given pressure. the altitude + returned is measured with respect to the mean sea level */ + public static double + pressure_to_altitude(double pressure) + { + + double next_base_temperature = LAYER0_BASE_TEMPERATURE; + double next_base_pressure = LAYER0_BASE_PRESSURE; + + double altitude; + double base_pressure; + double base_temperature; + double base; /* base for function to determine base pressure of next layer */ + double exponent; /* exponent for function to determine base pressure + of next layer */ + double coefficient; + int layer_number; /* identifies layer in the atmosphere */ + int delta_z; /* difference between two altitudes */ + + if (pressure < 0) /* illegal pressure */ + return -1; + if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */ + return MAXIMUM_ALTITUDE; + + /* calculate the base temperature and pressure for the atmospheric layer + associated with the inputted pressure. */ + layer_number = -1; + do { + layer_number++; + base_pressure = next_base_pressure; + base_temperature = next_base_temperature; + delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number]; + if (lapse_rate[layer_number] == 0.0) { + exponent = GRAVITATIONAL_ACCELERATION * delta_z + / AIR_GAS_CONSTANT / base_temperature; + next_base_pressure *= Math.exp(exponent); + } + else { + base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0; + exponent = GRAVITATIONAL_ACCELERATION / + (AIR_GAS_CONSTANT * lapse_rate[layer_number]); + next_base_pressure *= Math.pow(base, exponent); + } + next_base_temperature += delta_z * lapse_rate[layer_number]; + } + while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure); + + /* calculate the altitude associated with the inputted pressure */ + if (lapse_rate[layer_number] == 0.0) { + coefficient = (AIR_GAS_CONSTANT / GRAVITATIONAL_ACCELERATION) + * base_temperature; + altitude = base_altitude[layer_number] + + coefficient * Math.log(pressure / base_pressure); + } + else { + base = pressure / base_pressure; + exponent = AIR_GAS_CONSTANT * lapse_rate[layer_number] + / GRAVITATIONAL_ACCELERATION; + coefficient = base_temperature / lapse_rate[layer_number]; + altitude = base_altitude[layer_number] + + coefficient * (Math.pow(base, exponent) - 1); + } + + return altitude; + } + + public static double + cc_battery_to_voltage(double battery) + { + return battery / 32767.0 * 5.0; + } + + public static double + cc_ignitor_to_voltage(double ignite) + { + return ignite / 32767 * 15.0; + } + + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { + double f; + + if (freq > 0) + f = freq / 1000.0; + else { + if (setting <= 0) + setting = cal; + f = 434.550 * setting / cal; + /* Round to nearest 50KHz */ + f = Math.floor (20.0 * f + 0.5) / 20.0; + } + return f + channel * 0.100; + } + + public static int radio_frequency_to_setting(double frequency, int cal) { + double set = frequency / 434.550 * cal; + + return (int) Math.floor (set + 0.5); + } + + public static int radio_frequency_to_channel(double frequency) { + int channel = (int) Math.floor ((frequency - 434.550) / 0.100 + 0.5); + + if (channel < 0) + channel = 0; + if (channel > 9) + channel = 9; + return channel; + } + + public static double radio_channel_to_frequency(int channel) { + return 434.550 + channel * 0.100; + } + + public static int[] ParseHex(String line) { + String[] tokens = line.split("\\s+"); + int[] array = new int[tokens.length]; + + for (int i = 0; i < tokens.length; i++) + try { + array[i] = Integer.parseInt(tokens[i], 16); + } catch (NumberFormatException ne) { + return null; + } + return array; + } + + public static double meters_to_feet(double meters) { + return meters * (100 / (2.54 * 12)); + } + + public static double meters_to_mach(double meters) { + return meters / 343; /* something close to mach at usual rocket sites */ + } + + public static double meters_to_g(double meters) { + return meters / 9.80665; + } + + public static int checksum(int[] data, int start, int length) { + int csum = 0x5a; + for (int i = 0; i < length; i++) + csum += data[i + start]; + return csum & 0xff; + } +} -- cgit v1.2.3 From 66a1e07efcac9324d33a1eca0dfb58a2724b667a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 10 Sep 2012 09:14:03 -0700 Subject: altoslib: Add imperial units conversion support "Redneck" mode support Signed-off-by: Keith Packard --- altoslib/AltosAccel.java | 43 +++++++++++++++++++++++++++++++ altoslib/AltosConvert.java | 28 +++++++++++++++++++++ altoslib/AltosDistance.java | 49 ++++++++++++++++++++++++++++++++++++ altoslib/AltosHeight.java | 43 +++++++++++++++++++++++++++++++ altoslib/AltosPreferences.java | 17 +++++++++++++ altoslib/AltosSpeed.java | 43 +++++++++++++++++++++++++++++++ altoslib/AltosUnits.java | 57 ++++++++++++++++++++++++++++++++++++++++++ altoslib/Makefile.am | 7 +++++- 8 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 altoslib/AltosAccel.java create mode 100644 altoslib/AltosDistance.java create mode 100644 altoslib/AltosHeight.java create mode 100644 altoslib/AltosSpeed.java create mode 100644 altoslib/AltosUnits.java (limited to 'altoslib/AltosConvert.java') diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java new file mode 100644 index 00000000..d14764a2 --- /dev/null +++ b/altoslib/AltosAccel.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public class AltosAccel extends AltosUnits { + + public double value(double v) { + if (AltosConvert.imperial_units) + return AltosConvert.meters_to_feet(v); + return v; + } + + public String show_units() { + if (AltosConvert.imperial_units) + return "ft/s²"; + return "m/s²"; + } + + public String say_units() { + if (AltosConvert.imperial_units) + return "feet per second squared"; + return "meters per second squared"; + } + + int show_fraction(int width) { + return width / 9; + } +} \ No newline at end of file diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 3527b575..acd6c5f4 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -242,6 +242,14 @@ public class AltosConvert { return meters * (100 / (2.54 * 12)); } + public static double meters_to_miles(double meters) { + return meters_to_feet(meters) / 5280; + } + + public static double meters_to_mph(double mps) { + return meters_to_miles(mps) * 3600; + } + public static double meters_to_mach(double meters) { return meters / 343; /* something close to mach at usual rocket sites */ } @@ -250,6 +258,26 @@ public class AltosConvert { return meters / 9.80665; } + public static boolean imperial_units = false; + + public static AltosDistance distance = new AltosDistance(); + + public static AltosHeight height = new AltosHeight(); + + public static AltosSpeed speed = new AltosSpeed(); + + public static AltosAccel accel = new AltosAccel(); + + public static String show_gs(String format, double a) { + a = meters_to_g(a); + format = format.concat(" g"); + return String.format(format, a); + } + + public static String say_gs(double a) { + return String.format("%6.0 gees", meters_to_g(a)); + } + public static int checksum(int[] data, int start, int length) { int csum = 0x5a; for (int i = 0; i < length; i++) diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java new file mode 100644 index 00000000..a5e7331c --- /dev/null +++ b/altoslib/AltosDistance.java @@ -0,0 +1,49 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public class AltosDistance extends AltosUnits { + + public double value(double v) { + if (AltosConvert.imperial_units) + return AltosConvert.meters_to_miles(v); + return v; + } + + public String show_units() { + if (AltosConvert.imperial_units) + return "miles"; + return "m"; + } + + public String say_units() { + if (AltosConvert.imperial_units) + return "miles"; + return "meters"; + } + + int show_fraction(int width) { + if (AltosConvert.imperial_units) + return width / 3; + return width / 9; + } + + int say_fraction() { + return 1; + } +} \ No newline at end of file diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java new file mode 100644 index 00000000..da7ffdae --- /dev/null +++ b/altoslib/AltosHeight.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public class AltosHeight extends AltosUnits { + + public double value(double v) { + if (AltosConvert.imperial_units) + return AltosConvert.meters_to_feet(v); + return v; + } + + public String show_units() { + if (AltosConvert.imperial_units) + return "ft"; + return "m"; + } + + public String say_units() { + if (AltosConvert.imperial_units) + return "feet"; + return "meters"; + } + + int show_fraction(int width) { + return width / 9; + } +} \ No newline at end of file diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index 13fee46d..065b6e99 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -93,6 +93,10 @@ public class AltosPreferences { public final static String frequency_format = "FREQUENCY-%d"; public final static String description_format = "DESCRIPTION-%d"; + /* Units preference */ + + public final static String unitsPreference = "IMPERIAL-UNITS"; + public static AltosFrequency[] load_common_frequencies() { AltosFrequency[] frequencies = null; boolean existing = false; @@ -176,6 +180,7 @@ public class AltosPreferences { common_frequencies = load_common_frequencies(); + AltosConvert.imperial_units = preferences.getBoolean(unitsPreference, false); } static { init(); } @@ -356,4 +361,16 @@ public class AltosPreferences { new_frequencies[i+1] = common_frequencies[i]; set_common_frequencies(new_frequencies); } + + public static boolean imperial_units() { + return AltosConvert.imperial_units; + } + + public static void set_imperial_units(boolean imperial_units) { + AltosConvert.imperial_units = imperial_units; + synchronized (preferences) { + preferences.putBoolean(unitsPreference, imperial_units); + flush_preferences(); + } + } } diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java new file mode 100644 index 00000000..4e2daf5a --- /dev/null +++ b/altoslib/AltosSpeed.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public class AltosSpeed extends AltosUnits { + + public double value(double v) { + if (AltosConvert.imperial_units) + return AltosConvert.meters_to_mph(v); + return v; + } + + public String show_units() { + if (AltosConvert.imperial_units) + return "mph"; + return "m/s"; + } + + public String say_units() { + if (AltosConvert.imperial_units) + return "miles per hour"; + return "meters per second"; + } + + int show_fraction(int width) { + return width / 9; + } +} \ No newline at end of file diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java new file mode 100644 index 00000000..47540c61 --- /dev/null +++ b/altoslib/AltosUnits.java @@ -0,0 +1,57 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public abstract class AltosUnits { + + public abstract double value(double v); + + public abstract String show_units(); + + public abstract String say_units(); + + abstract int show_fraction(int width); + + int say_fraction() { + return 0; + } + + private String show_format(int width) { + return String.format("%%%d.%df %s", width, show_fraction(width), show_units()); + } + + private String say_format() { + return String.format("%%1.%df", say_fraction()); + } + + private String say_units_format() { + return String.format("%%1.%df %s", say_fraction(), say_units()); + } + + public String show(int width, double v) { + return String.format(show_format(width), value(v)); + } + + public String say(double v) { + return String.format(say_format(), value(v)); + } + + public String say_units(double v) { + return String.format(say_units_format(), value(v)); + } +} \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 39b43f3d..a9f810f9 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -68,7 +68,12 @@ AltosLib_JAVA = \ $(SRC)/AltosTelemetryRecordMegaData.java \ $(SRC)/AltosMs5607.java \ $(SRC)/AltosIMU.java \ - $(SRC)/AltosMag.java + $(SRC)/AltosMag.java \ + $(SRC)/AltosUnits.java \ + $(SRC)/AltosDistance.java \ + $(SRC)/AltosHeight.java \ + $(SRC)/AltosSpeed.java \ + $(SRC)/AltosAccel.java JAR=AltosLib.jar -- cgit v1.2.3