From 6f2a4c610dfacbf500650db0eeeca6623bb49c5c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 00:26:55 -0700 Subject: micropeak/altosui/telegps: Fix icon file names The icon file names are now structured to have an organization name and application name component. This should avoid collisions with other packages when the icon files are installed in a shared directory, as on Linux. Within the Java .jar file, the new names need to be correctly referenced or we won't find them. Signed-off-by: Keith Packard --- altosuilib/AltosUIFrame.java | 12 ++++++------ micropeak/MicroFrame.java | 12 ++++++------ telegps/TeleGPS.java | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/altosuilib/AltosUIFrame.java b/altosuilib/AltosUIFrame.java index 5b915e85..2e886932 100644 --- a/altosuilib/AltosUIFrame.java +++ b/altosuilib/AltosUIFrame.java @@ -36,12 +36,12 @@ public class AltosUIFrame extends JFrame implements AltosUIListener, AltosPositi } static String[] altos_icon_names = { - "/altus-metrum-16.png", - "/altus-metrum-32.png", - "/altus-metrum-48.png", - "/altus-metrum-64.png", - "/altus-metrum-128.png", - "/altus-metrum-256.png" + "/altusmetrum-altosui-16.png", + "/altusmetrum-altosui-32.png", + "/altusmetrum-altosui-48.png", + "/altusmetrum-altosui-64.png", + "/altusmetrum-altosui-128.png", + "/altusmetrum-altosui-256.png" }; static public String[] icon_names; diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java index f82d1c5e..8b3d49b5 100644 --- a/micropeak/MicroFrame.java +++ b/micropeak/MicroFrame.java @@ -25,12 +25,12 @@ import org.altusmetrum.altosuilib_3.*; public class MicroFrame extends AltosUIFrame { static String[] micro_icon_names = { - "/micropeak-16.png", - "/micropeak-32.png", - "/micropeak-48.png", - "/micropeak-64.png", - "/micropeak-128.png", - "/micropeak-256.png" + "/altusmetrum-micropeak-16.png", + "/altusmetrum-micropeak-32.png", + "/altusmetrum-micropeak-48.png", + "/altusmetrum-micropeak-64.png", + "/altusmetrum-micropeak-128.png", + "/altusmetrum-micropeak-256.png" }; static { set_icon_names(micro_icon_names); } diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java index d4b7bacf..a4b221e8 100644 --- a/telegps/TeleGPS.java +++ b/telegps/TeleGPS.java @@ -32,12 +32,12 @@ public class TeleGPS { static String[] telegps_icon_names = { - "/telegps-16.png", - "/telegps-32.png", - "/telegps-48.png", - "/telegps-64.png", - "/telegps-128.png", - "/telegps-256.png" + "/altusmetrum-telegps-16.png", + "/altusmetrum-telegps-32.png", + "/altusmetrum-telegps-48.png", + "/altusmetrum-telegps-64.png", + "/altusmetrum-telegps-128.png", + "/altusmetrum-telegps-256.png" }; static { set_icon_names(telegps_icon_names); } -- cgit v1.2.3 From b8fa4e9a077e8e04b922d0c434c139ad0a57ee66 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 16:15:52 -0700 Subject: altoslib: Clean up GPS DOP support in AltosState Parse out hdop/pdop/vdop from telem and eeprom. Deal with legacy eeprom files that have dop/100 instead of dop/10 values. Clear state DOP values to MISSING at startup Signed-off-by: Keith Packard --- altoslib/AltosEepromGPS.java | 17 +++++++++++++++-- altoslib/AltosEepromMega.java | 17 +++++++++++++++-- altoslib/AltosEepromMetrum2.java | 2 ++ altoslib/AltosGPS.java | 36 +++++++++++++++++++++++++----------- altoslib/AltosLib.java | 25 +++++++++++++++++++++++++ altoslib/AltosState.java | 6 ++++++ altoslib/AltosTelemetryLegacy.java | 2 ++ altoslib/AltosTelemetryLocation.java | 5 +++-- altoslib/AltosWriter.java | 2 -- 9 files changed, 93 insertions(+), 19 deletions(-) diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 2514b4fc..46a2173d 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -118,8 +118,21 @@ public class AltosEepromGPS extends AltosEeprom { gps.ground_speed = ground_speed() * 1.0e-2; gps.course = course() * 2; gps.climb_rate = climb_rate() * 1.0e-2; - gps.hdop = hdop(); - gps.vdop = vdop(); + if (state.compare_version("1.4.9") >= 0) { + gps.pdop = pdop() / 10.0; + gps.hdop = hdop() / 10.0; + gps.vdop = vdop() / 10.0; + } else { + gps.pdop = pdop() / 100.0; + if (gps.pdop < 0.8) + gps.pdop += 2.56; + gps.hdop = hdop() / 100.0; + if (gps.hdop < 0.8) + gps.hdop += 2.56; + gps.vdop = vdop() / 100.0; + if (gps.vdop < 0.8) + gps.vdop += 2.56; + } break; } } diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 5d5f3fef..1616de77 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -187,8 +187,21 @@ public class AltosEepromMega extends AltosEeprom { gps.ground_speed = ground_speed() * 1.0e-2; gps.course = course() * 2; gps.climb_rate = climb_rate() * 1.0e-2; - gps.hdop = hdop(); - gps.vdop = vdop(); + if (state.compare_version("1.4.9") >= 0) { + gps.pdop = pdop() / 10.0; + gps.hdop = hdop() / 10.0; + gps.vdop = vdop() / 10.0; + } else { + gps.pdop = pdop() / 100.0; + if (gps.pdop < 0.8) + gps.pdop += 2.56; + gps.hdop = hdop() / 100.0; + if (gps.hdop < 0.8) + gps.hdop += 2.56; + gps.vdop = vdop() / 100.0; + if (gps.vdop < 0.8) + gps.vdop += 2.56; + } break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 24277118..2f43879e 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -59,6 +59,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { public int year() { return data8(4); } public int month() { return data8(5); } public int day() { return data8(6); } + public int pdop() { return data8(7); } /* AO_LOG_GPS_SAT elements */ public int nsat() { return data8(0); } @@ -136,6 +137,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { gps.year = 2000 + year(); gps.month = month(); gps.day = day(); + gps.pdop = pdop() / 10.0; break; case AltosLib.AO_LOG_GPS_SAT: gps = state.make_temp_gps(true); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index aabcfc5b..0154e95d 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -40,10 +40,11 @@ public class AltosGPS implements Cloneable { public double ground_speed; /* m/s */ public int course; /* degrees */ public double climb_rate; /* m/s */ + public double pdop; /* unitless */ public double hdop; /* unitless */ public double vdop; /* unitless */ - public int h_error; /* m */ - public int v_error; /* m */ + public double h_error; /* m */ + public double v_error; /* m */ public AltosGPSSat[] cc_gps_sat; /* tracking data */ @@ -95,6 +96,7 @@ public class AltosGPS implements Cloneable { AltosLib.MISSING, 1/100.0); course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, AltosLib.MISSING); + pdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_PDOP, MISSING, 1.0); hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); @@ -268,14 +270,26 @@ public class AltosGPS implements Cloneable { cc_gps_sat[cc_gps_sat.length - 1] = sat; } - public AltosGPS() { + private void init() { lat = AltosLib.MISSING; lon = AltosLib.MISSING; alt = AltosLib.MISSING; + ground_speed = AltosLib.MISSING; + course = AltosLib.MISSING; + climb_rate = AltosLib.MISSING; + pdop = AltosLib.MISSING; + hdop = AltosLib.MISSING; + vdop = AltosLib.MISSING; + h_error = AltosLib.MISSING; + v_error = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } + public AltosGPS() { + init(); + } + public AltosGPS clone() { AltosGPS g = new AltosGPS(); @@ -295,7 +309,9 @@ public class AltosGPS implements Cloneable { g.ground_speed = ground_speed; /* m/s */ g.course = course; /* degrees */ g.climb_rate = climb_rate; /* m/s */ - g.hdop = hdop; /* unitless? */ + g.pdop = pdop; /* unitless */ + g.hdop = hdop; /* unitless */ + g.vdop = vdop; /* unitless */ g.h_error = h_error; /* m */ g.v_error = v_error; /* m */ @@ -327,9 +343,11 @@ public class AltosGPS implements Cloneable { ground_speed = old.ground_speed; /* m/s */ course = old.course; /* degrees */ climb_rate = old.climb_rate; /* m/s */ + pdop = old.pdop; /* unitless? */ hdop = old.hdop; /* unitless? */ - h_error = old.h_error; /* m */ - v_error = old.v_error; /* m */ + vdop = old.vdop; /* unitless? */ + h_error = old.h_error; /* m */ + v_error = old.v_error; /* m */ if (old.cc_gps_sat != null) { cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length]; @@ -340,11 +358,7 @@ public class AltosGPS implements Cloneable { } } } else { - lat = AltosLib.MISSING; - lon = AltosLib.MISSING; - alt = AltosLib.MISSING; - ClearGPSTime(); - cc_gps_sat = null; + init(); } } diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index c2ec0e3b..eb188d6b 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -215,6 +215,31 @@ public class AltosLib { telemetry)); } + private static int[] split_version(String version) { + String[] tokens = version.split("\\."); + int[] ret = new int[tokens.length]; + for (int i = 0; i < tokens.length; i++) + ret[i] = Integer.parseInt(tokens[i]); + return ret; + } + + public static int compare_version(String version_a, String version_b) { + int[] a = split_version(version_a); + int[] b = split_version(version_b); + + for (int i = 0; i < Math.min(a.length, b.length); i++) { + if (a[i] < b[i]) + return -1; + if (a[i] > b[i]) + return 1; + } + if (a.length < b.length) + return -1; + if (a.length > b.length) + return 1; + return 0; + } + private static String[] state_to_string = { "startup", "idle", diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 5e7908af..2fc13b44 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -1024,6 +1024,12 @@ public class AltosState implements Cloneable { firmware_version = version; } + public int compare_version(String other_version) { + if (firmware_version == null) + return AltosLib.MISSING; + return AltosLib.compare_version(firmware_version, other_version); + } + private void re_init() { int bt = boost_tick; int rs = receiver_serial; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index b7aae3c4..72a8bc4a 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -186,6 +186,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { * g_v GPS vertical speed (integer, cm/sec) * g_s GPS horizontal speed (integer, cm/sec) * g_c GPS course (integer, 0-359) + * g_pd GPS pdop (integer * 10) * g_hd GPS hdop (integer * 10) * g_vd GPS vdop (integer * 10) * g_he GPS h error (integer) @@ -209,6 +210,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; final static String AO_TELEM_GPS_COURSE = "g_c"; + final static String AO_TELEM_GPS_PDOP = "g_pd"; final static String AO_TELEM_GPS_HDOP = "g_hd"; final static String AO_TELEM_GPS_VDOP = "g_vd"; final static String AO_TELEM_GPS_HERROR = "g_he"; diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 32ca7608..9d50e2fa 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -80,8 +80,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { gps.ground_speed = ground_speed * 1.0e-2; gps.course = course * 2; gps.climb_rate = climb_rate * 1.0e-2; - gps.hdop = hdop; - gps.vdop = vdop; + gps.pdop = pdop / 10.0; + gps.hdop = hdop / 10.0; + gps.vdop = vdop / 10.0; } state.set_temp_gps(); } diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java index 9df52250..fb208b02 100644 --- a/altoslib/AltosWriter.java +++ b/altoslib/AltosWriter.java @@ -19,8 +19,6 @@ package org.altusmetrum.altoslib_5; public interface AltosWriter { - public void write(AltosState state); - public void write(AltosStateIterable states); public void close(); -- cgit v1.2.3 From 9dafabd77676e08da4067cd405b6f03bf8d8ff85 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 16:17:56 -0700 Subject: altoslib: Ensure CSV output is consistent Scan entire flight to figure out which columns to include before outputing header or data. Limit data output to values which are valid. Signed-off-by: Keith Packard --- altoslib/AltosCSV.java | 139 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 31 deletions(-) diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 7e3d6d07..4a9278d9 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -29,6 +29,14 @@ public class AltosCSV implements AltosWriter { LinkedList pad_states; AltosState state; + static boolean has_basic; + static boolean has_battery; + static boolean has_flight_state; + static boolean has_advanced; + static boolean has_gps; + static boolean has_gps_sat; + static boolean has_companion; + static final int ALTOS_CSV_VERSION = 5; /* Version 4 format: @@ -55,10 +63,12 @@ public class AltosCSV implements AltosWriter { * accelerometer speed (m/s) * barometer speed (m/s) * temp (°C) - * battery (V) * drogue (V) * main (V) * + * Battery + * battery (V) + * * Advanced sensors (if available) * accel_x (m/s²) * accel_y (m/s²) @@ -87,7 +97,9 @@ public class AltosCSV implements AltosWriter { * from_pad_azimuth (deg true) * from_pad_range (m) * from_pad_elevation (deg from horizon) + * pdop * hdop + * vdop * * GPS Sat data * C/N0 data for all 32 valid SDIDs @@ -107,7 +119,7 @@ public class AltosCSV implements AltosWriter { void write_general(AltosState state) { out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, - (double) state.time, (double) state.tick / 100.0, + (double) state.time_since_boost(), (double) state.tick / 100.0, state.rssi, state.status & 0x7f); } @@ -121,11 +133,11 @@ public class AltosCSV implements AltosWriter { } void write_basic_header() { - out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); + out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage"); } void write_basic(AltosState state) { - out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", + out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f", state.acceleration(), state.pressure(), state.altitude(), @@ -133,11 +145,18 @@ public class AltosCSV implements AltosWriter { state.speed(), state.speed(), state.temperature, - state.battery_voltage, state.apogee_voltage, state.main_voltage); } + void write_battery_header() { + out.printf("battery_voltage"); + } + + void write_battery(AltosState state) { + out.printf("%5.2f", state.battery_voltage); + } + void write_advanced_header() { out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); } @@ -150,14 +169,14 @@ public class AltosCSV implements AltosWriter { imu = new AltosIMU(); if (mag == null) mag = new AltosMag(); - out.printf("%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d", + out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", imu.accel_x, imu.accel_y, imu.accel_z, imu.gyro_x, imu.gyro_y, imu.gyro_z, mag.x, mag.y, mag.z); } void write_gps_header() { - out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); + out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop"); } void write_gps(AltosState state) { @@ -169,7 +188,7 @@ public class AltosCSV implements AltosWriter { if (from_pad == null) from_pad = new AltosGreatCircle(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f", gps.connected?1:0, gps.locked?1:0, gps.nsat, @@ -186,7 +205,9 @@ public class AltosCSV implements AltosWriter { state.range, from_pad.bearing, state.elevation, - gps.hdop); + gps.pdop, + gps.hdop, + gps.vdop); } void write_gps_sat_header() { @@ -239,52 +260,83 @@ public class AltosCSV implements AltosWriter { out.printf(",0"); } - void write_header(boolean advanced, boolean gps, boolean companion) { + void write_header() { out.printf("#"); write_general_header(); - out.printf(","); write_flight_header(); - out.printf(","); write_basic_header(); - if (advanced) - out.printf(","); write_advanced_header(); - if (gps) { - out.printf(","); write_gps_header(); - out.printf(","); write_gps_sat_header(); + if (has_flight_state) { + out.printf(","); + write_flight_header(); } - if (companion) { - out.printf(","); write_companion_header(); + if (has_basic) { + out.printf(","); + write_basic_header(); + } + if (has_battery) { + out.printf(","); + write_battery_header(); + } + if (has_advanced) { + out.printf(","); + write_advanced_header(); + } + if (has_gps) { + out.printf(","); + write_gps_header(); + } + if (has_gps_sat) { + out.printf(","); + write_gps_sat_header(); + } + if (has_companion) { + out.printf(","); + write_companion_header(); } out.printf ("\n"); } void write_one(AltosState state) { - write_general(state); out.printf(","); - write_flight(state); out.printf(","); - write_basic(state); out.printf(","); - if (state.imu != null || state.mag != null) + write_general(state); + if (has_flight_state) { + out.printf(","); + write_flight(state); + } + if (has_basic) { + out.printf(","); + write_basic(state); + } + if (has_battery) { + out.printf(","); + write_battery(state); + } + if (has_advanced) { + out.printf(","); write_advanced(state); - if (state.gps != null) { + } + if (has_gps) { + out.printf(","); + write_gps(state); + } + if (has_gps_sat) { out.printf(","); - write_gps(state); out.printf(","); write_gps_sat(state); } - if (state.companion != null) { + if (has_companion) { out.printf(","); write_companion(state); } out.printf ("\n"); } - void flush_pad() { + private void flush_pad() { while (!pad_states.isEmpty()) { write_one (pad_states.remove()); } } - public void write(AltosState state) { + private void write(AltosState state) { if (state.state == AltosLib.ao_flight_startup) return; if (!header_written) { - write_header(state.imu != null || state.mag != null, - state.gps != null, state.companion != null); + write_header(); header_written = true; } if (!seen_boost) { @@ -300,7 +352,7 @@ public class AltosCSV implements AltosWriter { pad_states.add(state); } - public PrintStream out() { + private PrintStream out() { return out; } @@ -314,6 +366,31 @@ public class AltosCSV implements AltosWriter { public void write(AltosStateIterable states) { states.write_comments(out()); + + has_flight_state = false; + has_basic = false; + has_battery = false; + has_advanced = false; + has_gps = false; + has_gps_sat = false; + has_companion = false; + for (AltosState state : states) { + if (state.state != AltosLib.ao_flight_stateless && state.state != AltosLib.ao_flight_invalid && state.state != AltosLib.ao_flight_startup) + has_flight_state = true; + if (state.acceleration() != AltosLib.MISSING || state.pressure() != AltosLib.MISSING) + has_basic = true; + if (state.battery_voltage != AltosLib.MISSING) + has_battery = true; + if (state.imu != null || state.mag != null) + has_advanced = true; + if (state.gps != null) { + has_gps = true; + if (state.gps.cc_gps_sat != null) + has_gps_sat = true; + } + if (state.companion != null) + has_companion = true; + } for (AltosState state : states) write(state); } -- cgit v1.2.3 From 61cbad00b68d9f4f2fed7b76132433e263966952 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 16:19:17 -0700 Subject: altosuilib: Add GPS DOP values to graph Signed-off-by: Keith Packard --- altosuilib/AltosGraph.java | 48 ++++++++++++++++++++++++++++++++++++- altosuilib/AltosGraphDataPoint.java | 23 +++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 292437de..522eea1e 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -172,6 +172,29 @@ class AltosMagUnits extends AltosUnits { } } +class AltosDopUnits extends AltosUnits { + + public double value(double p, boolean imperial_units) { + return p; + } + + public double inverse(double p, boolean imperial_units) { + return p; + } + + public String show_units(boolean imperial_units) { + return null; + } + + public String say_units(boolean imperial_units) { + return null; + } + + public int show_fraction(int width, boolean imperial_units) { + return 1; + } +} + public class AltosGraph extends AltosUIGraph { static final private Color height_color = new Color(194,31,31); @@ -191,6 +214,9 @@ public class AltosGraph extends AltosUIGraph { static final private Color gps_course_color = new Color (100, 31, 112); static final private Color gps_ground_speed_color = new Color (31, 112, 100); static final private Color gps_climb_rate_color = new Color (31, 31, 112); + static final private Color gps_pdop_color = new Color(50, 194, 0); + static final private Color gps_hdop_color = new Color(50, 0, 194); + static final private Color gps_vdop_color = new Color(194, 0, 50); static final private Color temperature_color = new Color (31, 194, 194); static final private Color dbm_color = new Color(31, 100, 100); static final private Color state_color = new Color(0,0,0); @@ -212,11 +238,12 @@ public class AltosGraph extends AltosUIGraph { static AltosGyroUnits gyro_units = new AltosGyroUnits(); static AltosOrient orient_units = new AltosOrient(); static AltosMagUnits mag_units = new AltosMagUnits(); + static AltosDopUnits dop_units = new AltosDopUnits(); AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis; AltosUIAxis distance_axis, pressure_axis; AltosUIAxis gyro_axis, orient_axis, mag_axis; - AltosUIAxis course_axis; + AltosUIAxis course_axis, dop_axis; public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) { super(enable); @@ -236,6 +263,7 @@ public class AltosGraph extends AltosUIGraph { orient_axis = newAxis("Tilt Angle", orient_units, orient_color, 0); mag_axis = newAxis("Magnetic Field", mag_units, mag_x_color, 0); course_axis = newAxis("Course", orient_units, gps_course_color, 0); + dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0); addMarker("State", AltosGraphDataPoint.data_state, state_color); @@ -325,6 +353,24 @@ public class AltosGraph extends AltosUIGraph { gps_climb_rate_color, enable_gps, speed_axis); + addSeries("GPS Position DOP", + AltosGraphDataPoint.data_gps_pdop, + dop_units, + gps_pdop_color, + false, + dop_axis); + addSeries("GPS Horizontal DOP", + AltosGraphDataPoint.data_gps_hdop, + dop_units, + gps_hdop_color, + false, + dop_axis); + addSeries("GPS Vertical DOP", + AltosGraphDataPoint.data_gps_vdop, + dop_units, + gps_vdop_color, + false, + dop_axis); } if (stats.has_rssi) addSeries("Received Signal Strength", diff --git a/altosuilib/AltosGraphDataPoint.java b/altosuilib/AltosGraphDataPoint.java index 14486abf..56dadb8b 100644 --- a/altosuilib/AltosGraphDataPoint.java +++ b/altosuilib/AltosGraphDataPoint.java @@ -53,7 +53,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_gps_course = 27; public static final int data_gps_ground_speed = 28; public static final int data_gps_climb_rate = 29; - public static final int data_ignitor_0 = 30; + public static final int data_gps_pdop = 30; + public static final int data_gps_hdop = 31; + public static final int data_gps_vdop = 32; + public static final int data_ignitor_0 = 33; public static final int data_ignitor_num = 32; public static final int data_ignitor_max = data_ignitor_0 + data_ignitor_num - 1; public static final int data_ignitor_fired_0 = data_ignitor_0 + data_ignitor_num; @@ -194,6 +197,24 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { else y = AltosLib.MISSING; break; + case data_gps_pdop: + if (state.gps != null) + y = state.gps.pdop; + else + y = AltosLib.MISSING; + break; + case data_gps_hdop: + if (state.gps != null) + y = state.gps.hdop; + else + y = AltosLib.MISSING; + break; + case data_gps_vdop: + if (state.gps != null) + y = state.gps.vdop; + else + y = AltosLib.MISSING; + break; default: if (data_ignitor_0 <= index && index <= data_ignitor_max) { int ignitor = index - data_ignitor_0; -- cgit v1.2.3 From a2f44fa867b17a0f1c1ee9aa9b99ecaa102a361b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 16:19:34 -0700 Subject: altosuilib: Add GPS DOP values to info table Signed-off-by: Keith Packard --- altosuilib/AltosInfoTable.java | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/altosuilib/AltosInfoTable.java b/altosuilib/AltosInfoTable.java index ce986ac5..625fe76f 100644 --- a/altosuilib/AltosInfoTable.java +++ b/altosuilib/AltosInfoTable.java @@ -198,24 +198,28 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar if (state.gps_height != AltosLib.MISSING) info_add_row(1, "GPS height", "%8.1f", state.gps_height); - /* The SkyTraq GPS doesn't report these values */ - /* - if (false) { - info_add_row(1, "GPS ground speed", "%8.1f m/s %3d°", - state.gps.ground_speed, - state.gps.course); - info_add_row(1, "GPS climb rate", "%8.1f m/s", - state.gps.climb_rate); - info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", - state.gps.h_error, state.gps.v_error); - } - */ - - info_add_row(1, "GPS hdop", "%8.1f", state.gps.hdop); + if (state.gps.ground_speed != AltosLib.MISSING && state.gps.course != AltosLib.MISSING) + info_add_row(1, "GPS ground speed", "%6.1f m/s %3d°", + state.gps.ground_speed, + state.gps.course); + if (state.gps.climb_rate != AltosLib.MISSING) + info_add_row(1, "GPS climb rate", "%6.1f m/s", + state.gps.climb_rate); + + if (state.gps.h_error != AltosLib.MISSING && state.gps.v_error != AltosLib.MISSING) + info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", + state.gps.h_error, state.gps.v_error); + if (state.gps.pdop != AltosLib.MISSING && + state.gps.hdop != AltosLib.MISSING && + state.gps.vdop != AltosLib.MISSING) + info_add_row(1, "GPS dop", "%3.1fp/%3.1fh/%3.1fv", + state.gps.pdop, + state.gps.hdop, + state.gps.vdop); if (state.npad > 0) { if (state.from_pad != null) { - info_add_row(1, "Distance from pad", "%6d m", + info_add_row(1, "Ground pad dist", "%6d m", (int) (state.from_pad.distance + 0.5)); info_add_row(1, "Direction from pad", "%6d°", (int) (state.from_pad.bearing + 0.5)); @@ -234,12 +238,12 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); } if (state.gps.year != AltosLib.MISSING) - info_add_row(1, "GPS date", "%04d-%02d-%02d", + info_add_row(2, "GPS date", "%04d-%02d-%02d", state.gps.year, state.gps.month, state.gps.day); if (state.gps.hour != AltosLib.MISSING) - info_add_row(1, "GPS time", " %02d:%02d:%02d", + info_add_row(2, "GPS time", " %02d:%02d:%02d", state.gps.hour, state.gps.minute, state.gps.second); -- cgit v1.2.3 From 0d044af0c5025a63026d05adcab68f265f179668 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 16:19:52 -0700 Subject: altosuilib: Allow for unitless axes in graphs DOP values have no units. Signed-off-by: Keith Packard --- altosuilib/AltosUIAxis.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java index 1b5b9205..9e98ddb7 100644 --- a/altosuilib/AltosUIAxis.java +++ b/altosuilib/AltosUIAxis.java @@ -48,7 +48,11 @@ public class AltosUIAxis extends NumberAxis { public final static int axis_default = axis_include_zero; public void set_units() { - setLabel(String.format("%s (%s)", label, units.show_units())); + String u = units.show_units(); + if (u != null) + setLabel(String.format("%s (%s)", label, u)); + else + setLabel(label); } public void set_enable(boolean enable) { -- cgit v1.2.3 From 34d5be68ca23e8beb05db9a480faef63ecc911d0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:07:48 -0700 Subject: altos: Extend GPS altitudes to at least 24 bits everywhere Telemetry gets a special 'mode' flag indicating that 24-bit data is present; log files get new data and log readers are expected to detect that via the firmware version number. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 1 + src/drivers/ao_aprs.c | 2 +- src/drivers/ao_gps_skytraq.c | 3 ++- src/drivers/ao_gps_ublox.c | 2 +- src/kernel/ao_gps_report.c | 8 ++++++-- src/kernel/ao_gps_report_mega.c | 7 ++++--- src/kernel/ao_gps_report_metrum.c | 3 ++- src/kernel/ao_gps_show.c | 8 +++++++- src/kernel/ao_log.h | 23 +++++++++++++++-------- src/kernel/ao_log_gps.c | 3 ++- src/kernel/ao_log_gps.h | 3 --- src/kernel/ao_telemetry.c | 2 +- src/kernel/ao_telemetry.h | 34 ++++++++++++++++++++++++++-------- src/kernel/ao_tracker.c | 13 +++++++------ src/test/ao_aprs_test.c | 7 +++---- src/test/ao_flight_test.c | 7 +++++-- src/test/ao_gps_test.c | 5 ++++- src/test/ao_gps_test_skytraq.c | 4 ++++ src/test/ao_gps_test_ublox.c | 9 ++++++++- 19 files changed, 99 insertions(+), 45 deletions(-) diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 1bc3d716..4db49215 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,7 @@ #define HAS_RADIO 1 #define DISABLE_LOG_SPACE 1 +#define HAS_WIDE_GPS 0 #if defined(TELEMETRUM_V_1_0) /* Discontinued and was never built with CC1111 chips needing this */ diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index a9047149..19beb78f 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -713,7 +713,7 @@ static int tncPositionPacket(void) if (ao_gps_data.flags & AO_GPS_VALID) { latitude = ao_gps_data.latitude; longitude = ao_gps_data.longitude; - altitude = ao_gps_data.altitude; + altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data); if (altitude < 0) altitude = 0; } diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 944a37f9..81178051 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -287,7 +287,8 @@ ao_nmea_gga(void) ao_gps_next.hdop = i; ao_gps_skip_field(); - ao_gps_next.altitude = ao_gps_decimal(0xff); + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_next, ao_gps_decimal(0xff)); + ao_gps_skip_field(); /* skip any fractional portion */ ao_nmea_finish(); diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 077698a9..48765998 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -728,7 +728,7 @@ ao_gps(void) __reentrant if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC)) ao_gps_data.flags |= AO_GPS_DATE_VALID; - ao_gps_data.altitude = nav_posllh.alt_msl / 1000; + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, nav_posllh.alt_msl / 1000); ao_gps_data.latitude = nav_posllh.lat; ao_gps_data.longitude = nav_posllh.lon; diff --git a/src/kernel/ao_gps_report.c b/src/kernel/ao_gps_report.c index 07201ac2..7ef98a97 100644 --- a/src/kernel/ao_gps_report.c +++ b/src/kernel/ao_gps_report.c @@ -52,8 +52,12 @@ ao_gps_report(void) gps_log.u.gps_longitude = gps_data.longitude; ao_log_data(&gps_log); gps_log.type = AO_LOG_GPS_ALT; - gps_log.u.gps_altitude.altitude = gps_data.altitude; - gps_log.u.gps_altitude.unused = 0xffff; + gps_log.u.gps_altitude.altitude_low = gps_data.altitude_low; +#if HAS_WIDE_GPS + gps_log.u.gps_altitude.altitude_high = gps_data.altitude_high; +#else + gps_log.u.gps_altitude.altitude_high = 0xffff; +#endif ao_log_data(&gps_log); if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) { gps_log.type = AO_LOG_GPS_DATE; diff --git a/src/kernel/ao_gps_report_mega.c b/src/kernel/ao_gps_report_mega.c index cb0c0fd9..f3711fb1 100644 --- a/src/kernel/ao_gps_report_mega.c +++ b/src/kernel/ao_gps_report_mega.c @@ -78,7 +78,8 @@ ao_gps_report_mega(void) #if GPS_SPARSE_LOG /* Don't log data if GPS has a fix and hasn't moved for a while */ if ((gps_data.flags & AO_GPS_VALID) && - !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, gps_data.altitude)) + !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, + AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data)) continue; #endif if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { @@ -87,8 +88,8 @@ ao_gps_report_mega(void) gps_log.type = AO_LOG_GPS_TIME; gps_log.u.gps.latitude = gps_data.latitude; gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; - + gps_log.u.gps.altitude_low = gps_data.altitude_low; + gps_log.u.gps.altitude_high = gps_data.altitude_high; gps_log.u.gps.hour = gps_data.hour; gps_log.u.gps.minute = gps_data.minute; gps_log.u.gps.second = gps_data.second; diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c index 696a833b..31939385 100644 --- a/src/kernel/ao_gps_report_metrum.c +++ b/src/kernel/ao_gps_report_metrum.c @@ -44,7 +44,8 @@ ao_gps_report_metrum(void) gps_log.type = AO_LOG_GPS_POS; gps_log.u.gps.latitude = gps_data.latitude; gps_log.u.gps.longitude = gps_data.longitude; - gps_log.u.gps.altitude = gps_data.altitude; + gps_log.u.gps.altitude_low = gps_data.altitude_low; + gps_log.u.gps.altitude_high = gps_data.altitude_high; ao_log_metrum(&gps_log); gps_log.type = AO_LOG_GPS_TIME; diff --git a/src/kernel/ao_gps_show.c b/src/kernel/ao_gps_show.c index 3a05e35a..e45cd795 100644 --- a/src/kernel/ao_gps_show.c +++ b/src/kernel/ao_gps_show.c @@ -19,6 +19,8 @@ #include #endif +#include + void ao_gps_show(void) __reentrant { @@ -27,7 +29,11 @@ ao_gps_show(void) __reentrant printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day); printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second); printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude); - printf ("Alt: %d\n", ao_gps_data.altitude); +#if HAS_WIDE_GPS + printf ("Alt: %ld\n", (long) AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#else + printf ("Alt: %d\n", AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#endif printf ("Flags: 0x%x\n", ao_gps_data.flags); printf ("Sats: %d", ao_gps_tracking_data.channels); for (i = 0; i < ao_gps_tracking_data.channels; i++) diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 33cda3eb..080cfb02 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -176,8 +176,8 @@ struct ao_log_record { int32_t gps_latitude; int32_t gps_longitude; struct { - int16_t altitude; - uint16_t unused; + uint16_t altitude_low; + int16_t altitude_high; } gps_altitude; struct { uint16_t svid; @@ -246,7 +246,7 @@ struct ao_log_mega { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ + uint16_t altitude_low; /* 12 */ uint8_t hour; /* 14 */ uint8_t minute; /* 15 */ uint8_t second; /* 16 */ @@ -261,7 +261,8 @@ struct ao_log_mega { uint8_t hdop; /* 27 */ uint8_t vdop; /* 28 */ uint8_t mode; /* 29 */ - } gps; /* 30 */ + int16_t altitude_high; /* 30 */ + } gps; /* 32 */ /* AO_LOG_GPS_SAT */ struct { uint16_t channels; /* 4 */ @@ -273,6 +274,11 @@ struct ao_log_mega { } u; }; +#define AO_LOG_MEGA_GPS_ALTITUDE(l) ((int32_t) ((l)->u.gps.altitude_high << 16) | ((l)->u.gps.altitude_low)) +#define AO_LOG_MEGA_SET_GPS_ALTITUDE(l,a) (((l)->u.gps.mode |= AO_GPS_MODE_ALTITUDE_24), \ + ((l)->u.gps.altitude_high = (a) >> 16), \ + (l)->u.gps.altitude_low = (a)) + struct ao_log_metrum { char type; /* 0 */ uint8_t csum; /* 1 */ @@ -306,8 +312,9 @@ struct ao_log_metrum { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ - } gps; /* 14 */ + uint16_t altitude_low; /* 12 */ + int16_t altitude_high; /* 14 */ + } gps; /* 16 */ /* AO_LOG_GPS_TIME */ struct { uint8_t hour; /* 4 */ @@ -381,7 +388,7 @@ struct ao_log_gps { struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ - int16_t altitude; /* 12 */ + uint16_t altitude_low; /* 12 */ uint8_t hour; /* 14 */ uint8_t minute; /* 15 */ uint8_t second; /* 16 */ @@ -396,7 +403,7 @@ struct ao_log_gps { uint8_t hdop; /* 27 */ uint8_t vdop; /* 28 */ uint8_t mode; /* 29 */ - uint8_t state; /* 30 */ + int16_t altitude_high; /* 30 */ } gps; /* 31 */ /* AO_LOG_GPS_SAT */ struct { diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c index 3b728c25..a5a6358b 100644 --- a/src/kernel/ao_log_gps.c +++ b/src/kernel/ao_log_gps.c @@ -75,7 +75,8 @@ ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data) log.type = AO_LOG_GPS_TIME; log.u.gps.latitude = gps_data->latitude; log.u.gps.longitude = gps_data->longitude; - log.u.gps.altitude = gps_data->altitude; + log.u.gps.altitude_low = gps_data->altitude_low; + log.u.gps.altitude_high = gps_data->altitude_high; log.u.gps.hour = gps_data->hour; log.u.gps.minute = gps_data->minute; diff --git a/src/kernel/ao_log_gps.h b/src/kernel/ao_log_gps.h index 5851f4d1..a9e8c831 100644 --- a/src/kernel/ao_log_gps.h +++ b/src/kernel/ao_log_gps.h @@ -21,9 +21,6 @@ #ifndef _AO_LOG_GPS_H_ #define _AO_LOG_GPS_H_ -uint8_t -ao_log_gps_should_log(int32_t lat, int32_t lon, int16_t alt); - void ao_log_gps_flight(void); diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index d321c8ff..56bd715e 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -344,7 +344,7 @@ ao_send_location(void) ao_mutex_get(&ao_gps_mutex); ao_xmemcpy(&telemetry.location.flags, &ao_gps_data.flags, - 26); + 27); telemetry.location.tick = ao_gps_tick; ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index be7d0340..83d432cf 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -86,12 +86,9 @@ struct ao_telemetry_configuration { #define AO_TELEMETRY_LOCATION 0x05 -#define AO_GPS_MODE_NOT_VALID 'N' -#define AO_GPS_MODE_AUTONOMOUS 'A' -#define AO_GPS_MODE_DIFFERENTIAL 'D' -#define AO_GPS_MODE_ESTIMATED 'E' -#define AO_GPS_MODE_MANUAL 'M' -#define AO_GPS_MODE_SIMULATED 'S' +/* Mode bits */ + +#define AO_GPS_MODE_ALTITUDE_24 (1 << 0) /* reports 24-bits of altitude */ struct ao_telemetry_location { uint16_t serial; /* 0 */ @@ -99,7 +96,7 @@ struct ao_telemetry_location { uint8_t type; /* 4 */ uint8_t flags; /* 5 Number of sats and other flags */ - int16_t altitude; /* 6 GPS reported altitude (m) */ + uint16_t altitude_low; /* 6 GPS reported altitude (m) */ int32_t latitude; /* 8 latitude (degrees * 10⁷) */ int32_t longitude; /* 12 longitude (degrees * 10⁷) */ uint8_t year; /* 16 (- 2000) */ @@ -115,10 +112,31 @@ struct ao_telemetry_location { uint16_t ground_speed; /* 26 cm/s */ int16_t climb_rate; /* 28 cm/s */ uint8_t course; /* 30 degrees / 2 */ - uint8_t unused; /* 31 unused */ + int8_t altitude_high; /* 31 high byte of altitude */ /* 32 */ }; +#if HAS_GPS + +#ifndef HAS_WIDE_GPS +#define HAS_WIDE_GPS 1 +#endif + +#if HAS_WIDE_GPS +typedef int32_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode |= AO_GPS_MODE_ALTITUDE_24), \ + ((l)->altitude_high = (a) >> 16), \ + ((l)->altitude_low = (a))) +#else +typedef int16_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((gps_alt_t) (l)->altitude_low) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode = 0, \ + (l)->altitude_low = (a))) +#endif /* HAS_WIDE_GPS */ + +#endif /* HAS_GPS */ + #define AO_TELEMETRY_SATELLITE 0x06 struct ao_telemetry_satellite_info { diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index 9febc7f0..d9434048 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -36,9 +36,9 @@ ao_usb_connected(void) #endif struct gps_position { - int32_t latitude; - int32_t longitude; - int16_t altitude; + int32_t latitude; + int32_t longitude; + gps_alt_t altitude; }; #define GPS_RING 16 @@ -122,12 +122,13 @@ ao_tracker(void) { uint8_t ring; uint8_t moving = 0; + gps_alt_t altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data); for (ring = ao_gps_ring_next(gps_head); ring != gps_head; ring = ao_gps_ring_next(ring)) { ground_distance = ao_distance(gps_data.latitude, gps_data.longitude, gps_position[ring].latitude, gps_position[ring].longitude); - height = gps_position[ring].altitude - gps_data.altitude; + height = gps_position[ring].altitude - altitude; if (height < 0) height = -height; @@ -153,7 +154,7 @@ ao_tracker(void) ao_log_gps_data(gps_tick, &gps_data); gps_position[gps_head].latitude = gps_data.latitude; gps_position[gps_head].longitude = gps_data.longitude; - gps_position[gps_head].altitude = gps_data.altitude; + gps_position[gps_head].altitude = altitude; gps_head = ao_gps_ring_next(gps_head); ao_mutex_put(&tracker_mutex); } @@ -203,7 +204,7 @@ ao_tracker_set_telem(void) printf ("log_started: %d\n", log_started); printf ("latitude: %ld\n", (long) gps_data.latitude); printf ("longitude: %ld\n", (long) gps_data.longitude); - printf ("altitude: %d\n", gps_data.altitude); + printf ("altitude: %ld\n", AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data)); printf ("log_running: %d\n", ao_log_running); printf ("log_start_pos: %ld\n", (long) ao_log_start_pos); printf ("log_cur_pos: %ld\n", (long) ao_log_current_pos); diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c index 573b5cb2..ae505dea 100644 --- a/src/test/ao_aprs_test.c +++ b/src/test/ao_aprs_test.c @@ -21,6 +21,8 @@ #include #include +#define HAS_GPS 1 + #include #define AO_GPS_NUM_SAT_MASK (0xf << 0) @@ -100,14 +102,11 @@ audio_gap(int secs) // This is where we go after reset. int main(int argc, char **argv) { - int e, x; - int a; - audio_gap(1); ao_gps_data.latitude = (45.0 + 28.25 / 60.0) * 10000000; ao_gps_data.longitude = (-(122 + 44.2649 / 60.0)) * 10000000; - ao_gps_data.altitude = 84; + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, 84); ao_gps_data.flags = (AO_GPS_VALID|AO_GPS_RUNNING); /* Transmit one packet */ diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 1ab22e5b..314998c1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -175,7 +175,7 @@ ao_gps_angle(void) ao_gps_static.latitude / 1e7, ao_gps_static.longitude / 1e7, &dist, &bearing); - height = ao_gps_static.altitude - ao_gps_prev.altitude; + height = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_static) - AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_prev); angle = atan2(dist, height); return angle * 180/M_PI; @@ -756,7 +756,10 @@ ao_sleep(void *wchan) ao_gps_static.tick = tick; ao_gps_static.latitude = int32(bytes, 0); ao_gps_static.longitude = int32(bytes, 4); - ao_gps_static.altitude = int32(bytes, 8); + { + int32_t altitude = int32(bytes, 8); + AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_static, altitude); + } ao_gps_static.flags = bytes[13]; if (!ao_gps_count) ao_gps_first = ao_gps_static; diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index e799ab0f..543bbcc3 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -53,6 +53,9 @@ struct ao_gps_orig { uint16_t v_error; /* m */ }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) + #define SIRF_SAT_STATE_ACQUIRED (1 << 0) #define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2) @@ -433,7 +436,7 @@ ao_dump_state(void *wchan) if (wchan != &ao_gps_new) return; - + if (ao_gps_new & AO_GPS_NEW_DATA) { ao_gps_print(&ao_gps_data); putchar('\n'); diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 1b590d5e..5eb7118d 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -16,6 +16,7 @@ */ #define AO_GPS_TEST +#define HAS_GPS 1 #include "ao_host.h" #include #include @@ -53,6 +54,9 @@ struct ao_gps_orig { uint16_t v_error; /* m */ }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) + #define SIRF_SAT_STATE_ACQUIRED (1 << 0) #define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2) diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 4eb4b837..5ea205d6 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -16,6 +16,7 @@ */ #define AO_GPS_TEST +#define HAS_GPS 1 #include "ao_host.h" #include #include @@ -44,7 +45,7 @@ struct ao_telemetry_location { uint8_t flags; int32_t latitude; /* degrees * 10⁷ */ int32_t longitude; /* degrees * 10⁷ */ - int16_t altitude; /* m */ + int16_t altitude_low; /* m */ uint16_t ground_speed; /* cm/s */ uint8_t course; /* degrees / 2 */ uint8_t pdop; /* * 5 */ @@ -53,8 +54,14 @@ struct ao_telemetry_location { int16_t climb_rate; /* cm/s */ uint16_t h_error; /* m */ uint16_t v_error; /* m */ + int16_t altitude_high; /* m */ }; +typedef int32_t gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \ + ((l)->altitude_low = (a))) + #define UBLOX_SAT_STATE_ACQUIRED (1 << 0) #define UBLOX_SAT_STATE_CARRIER_PHASE_VALID (1 << 1) #define UBLOX_SAT_BIT_SYNC_COMPLETE (1 << 2) -- cgit v1.2.3 From ed2a08c50d6b8ebcc8c1d2f15e73c1f2a1e25041 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:10:49 -0700 Subject: altoslib: Handle wide GPS altitude values in eeprom and telemetry Detect when the wider data is present and handle it correctly Signed-off-by: Keith Packard --- altoslib/AltosEepromGPS.java | 8 ++++++-- altoslib/AltosEepromMega.java | 9 +++++++-- altoslib/AltosEepromMetrum2.java | 8 ++++++-- altoslib/AltosTelemetryLocation.java | 8 +++++++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 46a2173d..482f0b5f 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -37,7 +37,7 @@ public class AltosEepromGPS extends AltosEeprom { /* AO_LOG_GPS_TIME elements */ public int latitude() { return data32(0); } public int longitude() { return data32(4); } - public int altitude() { return data16(8); } + public int altitude_low() { return data16(8); } public int hour() { return data8(10); } public int minute() { return data8(11); } public int second() { return data8(12); } @@ -52,6 +52,7 @@ public class AltosEepromGPS extends AltosEeprom { public int hdop() { return data8(23); } public int vdop() { return data8(24); } public int mode() { return data8(25); } + public int altitude_high() { return data16(26); } public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; } @@ -99,7 +100,10 @@ public class AltosEepromGPS extends AltosEeprom { gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; - gps.alt = altitude(); + if (state.altitude_32()) + gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); + else + gps.alt = altitude_low(); gps.hour = hour(); gps.minute = minute(); diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 1616de77..adaa7f31 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -67,7 +67,7 @@ public class AltosEepromMega extends AltosEeprom { /* AO_LOG_GPS_TIME elements */ public int latitude() { return data32(0); } public int longitude() { return data32(4); } - public int altitude() { return data16(8); } + public int altitude_low() { return data16(8); } public int hour() { return data8(10); } public int minute() { return data8(11); } public int second() { return data8(12); } @@ -82,6 +82,7 @@ public class AltosEepromMega extends AltosEeprom { public int hdop() { return data8(23); } public int vdop() { return data8(24); } public int mode() { return data8(25); } + public int altitude_high() { return data16(26); } /* AO_LOG_GPS_SAT elements */ public int nsat() { return data16(0); } @@ -168,7 +169,11 @@ public class AltosEepromMega extends AltosEeprom { gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; - gps.alt = altitude(); + + if (state.altitude_32()) + gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); + else + gps.alt = altitude_low(); gps.hour = hour(); gps.minute = minute(); diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 2f43879e..d9a65989 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -49,7 +49,8 @@ public class AltosEepromMetrum2 extends AltosEeprom { /* AO_LOG_GPS_POS elements */ public int latitude() { return data32(0); } public int longitude() { return data32(4); } - public int altitude() { return data16(8); } + public int altitude_low() { return data16(8); } + public int altitude_high() { return data16(10); } /* AO_LOG_GPS_TIME elements */ public int hour() { return data8(0); } @@ -118,7 +119,10 @@ public class AltosEepromMetrum2 extends AltosEeprom { gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; - gps.alt = altitude(); + if (state.altitude_32()) + gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); + else + gps.alt = altitude_low(); break; case AltosLib.AO_LOG_GPS_TIME: gps = state.make_temp_gps(false); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 9d50e2fa..427ae16e 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -37,11 +37,12 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { int climb_rate; int course; + public static final int AO_GPS_MODE_ALTITUDE_24 = (1 << 0); /* Reports 24-bits of altitude */ + public AltosTelemetryLocation(int[] bytes) { super(bytes); flags = uint8(5); - altitude = int16(6); latitude = uint32(8); longitude = uint32(12); year = uint8(16); @@ -57,6 +58,11 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { ground_speed = uint16(26); climb_rate = int16(28); course = uint8(30); + + if ((mode & AO_GPS_MODE_ALTITUDE_24) != 0) { + altitude = (int8(31) << 16) | uint16(6); + } else + altitude = int16(6); } public void update_state(AltosState state) { -- cgit v1.2.3 From 47e62bb26984f6c84660c1d0451f77c2d6ad7e5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:13:09 -0700 Subject: altos: Scale DOP values by 10 in GPS drivers sky traq was scaling by 5, ublox was scaling by 100. Signed-off-by: Keith Packard --- src/drivers/ao_gps_skytraq.c | 6 +++--- src/drivers/ao_gps_ublox.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 81178051..066df6ff 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -278,10 +278,10 @@ ao_nmea_gga(void) ao_gps_lexchar(); i = ao_gps_decimal(0xff); - if (i <= 50) { - i = (uint8_t) 5 * i; + if (i <= 25) { + i = (uint8_t) 10 * i; if (ao_gps_char == '.') - i = (i + ((uint8_t) ao_gps_decimal(1) >> 1)); + i = (i + ((uint8_t) ao_gps_decimal(1))); } else i = 255; ao_gps_next.hdop = i; diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 48765998..74c29e0a 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -740,11 +740,11 @@ ao_gps(void) __reentrant ao_gps_data.minute = nav_timeutc.min; ao_gps_data.second = nav_timeutc.sec; - ao_gps_data.pdop = nav_dop.pdop; - ao_gps_data.hdop = nav_dop.hdop; - ao_gps_data.vdop = nav_dop.vdop; - - /* mode is not set */ + /* we report dop scaled by 10, but ublox provides dop scaled by 100 + */ + ao_gps_data.pdop = nav_dop.pdop / 10; + ao_gps_data.hdop = nav_dop.hdop / 10; + ao_gps_data.vdop = nav_dop.vdop / 10; ao_gps_data.ground_speed = nav_velned.g_speed; ao_gps_data.climb_rate = -nav_velned.vel_d; -- cgit v1.2.3 From 31ae24b5da3e198e7555ea3768d3cbdec3a28a5f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:15:09 -0700 Subject: altos: Record pdop value in TeleMetrumV2 log There's only one byte free, so we'll record the pdop value Signed-off-by: Keith Packard --- src/kernel/ao_gps_report_metrum.c | 1 + src/kernel/ao_log.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c index 31939385..8ce074fe 100644 --- a/src/kernel/ao_gps_report_metrum.c +++ b/src/kernel/ao_gps_report_metrum.c @@ -56,6 +56,7 @@ ao_gps_report_metrum(void) gps_log.u.gps_time.year = gps_data.year; gps_log.u.gps_time.month = gps_data.month; gps_log.u.gps_time.day = gps_data.day; + gps_log.u.gps_time.pdop = gps_data.pdop; ao_log_metrum(&gps_log); } diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 080cfb02..da20e067 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -324,7 +324,7 @@ struct ao_log_metrum { uint8_t year; /* 8 */ uint8_t month; /* 9 */ uint8_t day; /* 10 */ - uint8_t pad; /* 11 */ + uint8_t pdop; /* 11 */ } gps_time; /* 12 */ /* AO_LOG_GPS_SAT (up to three packets) */ struct { -- cgit v1.2.3 From 013e9ccfbe76dc46e8c69ea314950bed83d9a39f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:18:38 -0700 Subject: altos: Use 32-bits for flight state data (alt/speed/accel) Stores 32-bits for all of the flight parameters. Uses 64-bit intermediates for kalman computation. Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/cc1111/ao_pins.h | 1 + src/kalman/kalman.5c | 2 +- src/kalman/kalman_micro.5c | 2 +- src/kernel/ao.h | 14 ++-- src/kernel/ao_cmd.c | 3 + src/kernel/ao_convert.c | 10 +-- src/kernel/ao_convert_pa.c | 16 ++--- src/kernel/ao_convert_pa_test.c | 1 + src/kernel/ao_data.h | 6 -- src/kernel/ao_flight.c | 12 ++-- src/kernel/ao_kalman.c | 147 ++++++++++++++++++++-------------------- src/kernel/ao_microkalman.c | 12 ++-- src/kernel/ao_sample.c | 2 +- src/kernel/ao_sample.h | 56 +++++++++++---- src/product/Makefile.telemetrum | 1 + src/telefire-v0.1/Makefile | 1 - src/telefire-v0.2/Makefile | 1 - src/telemega-v1.0/Makefile | 1 + src/telemini-v2.0/ao_pins.h | 1 + src/teleterra-v0.2/ao_pins.h | 2 + src/test/ao_flight_test.c | 5 +- src/test/ao_micropeak_test.c | 1 + 23 files changed, 170 insertions(+), 129 deletions(-) diff --git a/src/Makefile b/src/Makefile index a7a26b26..3494ba62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -109,7 +109,7 @@ altitude-pa.h: make-altitude-pa altitude-pa-small.h: make-altitude-pa nickle $< --sample 3 > $@ -ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c +ao_kalman.h: make-kalman kalman.5c kalman_micro.5c kalman_filter.5c load_csv.5c matrix.5c bash $< kalman > $@ ao_whiten.h: make-whiten diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 4db49215..e12f813f 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,7 @@ #define HAS_RADIO 1 #define DISABLE_LOG_SPACE 1 +#define AO_VALUE_32 0 #define HAS_WIDE_GPS 0 #if defined(TELEMETRUM_V_1_0) diff --git a/src/kalman/kalman.5c b/src/kalman/kalman.5c index 46fa8e1f..55fde04c 100755 --- a/src/kalman/kalman.5c +++ b/src/kalman/kalman.5c @@ -457,7 +457,7 @@ void main() { name = sprintf("%s_K%d_%d", prefix, i, time_inc); else name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc); - printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]); + printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]); } printf ("\n"); exit(0); diff --git a/src/kalman/kalman_micro.5c b/src/kalman/kalman_micro.5c index 266a1182..1b080384 100644 --- a/src/kalman/kalman_micro.5c +++ b/src/kalman/kalman_micro.5c @@ -307,7 +307,7 @@ void main() { name = sprintf("%s_K%d_%d", prefix, i, time_inc); else name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc); - printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]); + printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]); } printf ("\n"); exit(0); diff --git a/src/kernel/ao.h b/src/kernel/ao.h index a225bc4a..ad5bbf8e 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -278,15 +278,17 @@ ao_report_init(void); * Given raw data, convert to SI units */ +#if HAS_BARO /* pressure from the sensor to altitude in meters */ -int16_t -ao_pres_to_altitude(int16_t pres) __reentrant; +alt_t +ao_pres_to_altitude(pres_t pres) __reentrant; -int16_t -ao_altitude_to_pres(int16_t alt) __reentrant; +pres_t +ao_altitude_to_pres(alt_t alt) __reentrant; int16_t ao_temp_to_dC(int16_t temp) __reentrant; +#endif /* * ao_convert_pa.c @@ -296,11 +298,13 @@ ao_temp_to_dC(int16_t temp) __reentrant; #include +#if HAS_BARO alt_t -ao_pa_to_altitude(int32_t pa); +ao_pa_to_altitude(pres_t pa); int32_t ao_altitude_to_pa(alt_t alt); +#endif #if HAS_DBG #include diff --git a/src/kernel/ao_cmd.c b/src/kernel/ao_cmd.c index 0052bdce..d2f583ef 100644 --- a/src/kernel/ao_cmd.c +++ b/src/kernel/ao_cmd.c @@ -289,6 +289,9 @@ version(void) #endif #if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND) "program-space %u\n" +#endif +#if AO_VALUE_32 + "altitude-32 1\n" #endif , ao_manufacturer , ao_product diff --git a/src/kernel/ao_convert.c b/src/kernel/ao_convert.c index aa9b5f48..db1f2301 100644 --- a/src/kernel/ao_convert.c +++ b/src/kernel/ao_convert.c @@ -19,14 +19,16 @@ #include "ao.h" #endif -static const int16_t altitude_table[] = { +#include + +static const ao_v_t altitude_table[] = { #include "altitude.h" }; #define ALT_FRAC_SCALE (1 << ALT_FRAC_BITS) #define ALT_FRAC_MASK (ALT_FRAC_SCALE - 1) -int16_t +ao_v_t ao_pres_to_altitude(int16_t pres) __reentrant { uint8_t o; @@ -43,9 +45,9 @@ ao_pres_to_altitude(int16_t pres) __reentrant #if AO_NEED_ALTITUDE_TO_PRES int16_t -ao_altitude_to_pres(int16_t alt) __reentrant +ao_altitude_to_pres(ao_v_t alt) __reentrant { - int16_t span, sub_span; + ao_v_t span, sub_span; uint8_t l, h, m; int32_t pres; diff --git a/src/kernel/ao_convert_pa.c b/src/kernel/ao_convert_pa.c index 20162c1f..410815b6 100644 --- a/src/kernel/ao_convert_pa.c +++ b/src/kernel/ao_convert_pa.c @@ -39,11 +39,11 @@ static const alt_t altitude_table[] AO_CONST_ATTRIB = { #define ALT_MASK (ALT_SCALE - 1) alt_t -ao_pa_to_altitude(int32_t pa) +ao_pa_to_altitude(pres_t pa) { int16_t o; int16_t part; - int32_t low, high; + alt_t low, high; if (pa < 0) pa = 0; @@ -52,16 +52,16 @@ ao_pa_to_altitude(int32_t pa) o = pa >> ALT_SHIFT; part = pa & ALT_MASK; - low = (int32_t) FETCH_ALT(o) * (ALT_SCALE - part); - high = (int32_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1); + low = (alt_t) FETCH_ALT(o) * (ALT_SCALE - part); + high = (alt_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1); return (low + high) >> ALT_SHIFT; } #ifdef AO_CONVERT_TEST -int32_t -ao_altitude_to_pa(int32_t alt) +pres_t +ao_altitude_to_pa(alt_t alt) { - int32_t span, sub_span; + alt_t span, sub_span; uint16_t l, h, m; int32_t pa; @@ -76,7 +76,7 @@ ao_altitude_to_pa(int32_t alt) } span = altitude_table[l] - altitude_table[h]; sub_span = altitude_table[l] - alt; - pa = ((((int32_t) l * (span - sub_span) + (int32_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span; + pa = ((((alt_t) l * (span - sub_span) + (alt_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span; if (pa > 120000) pa = 120000; if (pa < 0) diff --git a/src/kernel/ao_convert_pa_test.c b/src/kernel/ao_convert_pa_test.c index 7d5b1922..95422862 100644 --- a/src/kernel/ao_convert_pa_test.c +++ b/src/kernel/ao_convert_pa_test.c @@ -18,6 +18,7 @@ #include #define AO_CONVERT_TEST typedef int32_t alt_t; +typedef int32_t pres_t; #include "ao_host.h" #include "ao_convert_pa.c" diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h index c4b062fd..8f75ad87 100644 --- a/src/kernel/ao_data.h +++ b/src/kernel/ao_data.h @@ -117,9 +117,7 @@ extern volatile __data uint8_t ao_data_count; typedef int32_t pres_t; -#ifndef AO_ALT_TYPE #define AO_ALT_TYPE int32_t -#endif typedef AO_ALT_TYPE alt_t; @@ -146,10 +144,6 @@ typedef int16_t alt_t; #endif -#if !HAS_BARO -typedef int16_t alt_t; -#endif - /* * Need a few macros to pull data from the sensors: * diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index 2b433ee9..251dbc02 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -60,10 +60,10 @@ __xdata uint8_t ao_sensor_errors; * resting */ static __data uint16_t ao_interval_end; -static __data int16_t ao_interval_min_height; -static __data int16_t ao_interval_max_height; +static __data ao_v_t ao_interval_min_height; +static __data ao_v_t ao_interval_max_height; #if HAS_ACCEL -static __data int16_t ao_coast_avg_accel; +static __data ao_v_t ao_coast_avg_accel; #endif __pdata uint8_t ao_flight_force_idle; @@ -398,14 +398,14 @@ ao_flight(void) } #if HAS_FLIGHT_DEBUG -static inline int int_part(int16_t i) { return i >> 4; } -static inline int frac_part(int16_t i) { return ((i & 0xf) * 100 + 8) / 16; } +static inline int int_part(ao_v_t i) { return i >> 4; } +static inline int frac_part(ao_v_t i) { return ((i & 0xf) * 100 + 8) / 16; } static void ao_flight_dump(void) { #if HAS_ACCEL - int16_t accel; + ao_v_t accel; accel = ((ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale) >> 16; #endif diff --git a/src/kernel/ao_kalman.c b/src/kernel/ao_kalman.c index 9aea1f14..7b0f8145 100644 --- a/src/kernel/ao_kalman.c +++ b/src/kernel/ao_kalman.c @@ -23,32 +23,31 @@ #include "ao_sample.h" #include "ao_kalman.h" +static __pdata ao_k_t ao_k_height; +static __pdata ao_k_t ao_k_speed; +static __pdata ao_k_t ao_k_accel; -static __pdata int32_t ao_k_height; -static __pdata int32_t ao_k_speed; -static __pdata int32_t ao_k_accel; +#define AO_K_STEP_100 to_fix_v(0.01) +#define AO_K_STEP_2_2_100 to_fix_v(0.00005) -#define AO_K_STEP_100 to_fix16(0.01) -#define AO_K_STEP_2_2_100 to_fix16(0.00005) +#define AO_K_STEP_10 to_fix_v(0.1) +#define AO_K_STEP_2_2_10 to_fix_v(0.005) -#define AO_K_STEP_10 to_fix16(0.1) -#define AO_K_STEP_2_2_10 to_fix16(0.005) +#define AO_K_STEP_1 to_fix_v(1) +#define AO_K_STEP_2_2_1 to_fix_v(0.5) -#define AO_K_STEP_1 to_fix16(1) -#define AO_K_STEP_2_2_1 to_fix16(0.5) +__pdata ao_v_t ao_height; +__pdata ao_v_t ao_speed; +__pdata ao_v_t ao_accel; +__xdata ao_v_t ao_max_height; +static __pdata ao_k_t ao_avg_height_scaled; +__xdata ao_v_t ao_avg_height; -__pdata int16_t ao_height; -__pdata int16_t ao_speed; -__pdata int16_t ao_accel; -__xdata int16_t ao_max_height; -static __pdata int32_t ao_avg_height_scaled; -__xdata int16_t ao_avg_height; - -__pdata int16_t ao_error_h; -__pdata int16_t ao_error_h_sq_avg; +__pdata ao_v_t ao_error_h; +__pdata ao_v_t ao_error_h_sq_avg; #if HAS_ACCEL -__pdata int16_t ao_error_a; +__pdata ao_v_t ao_error_a; #endif static void @@ -56,40 +55,40 @@ ao_kalman_predict(void) { #ifdef AO_FLIGHT_TEST if (ao_sample_tick - ao_sample_prev_tick > 50) { - ao_k_height += ((int32_t) ao_speed * AO_K_STEP_1 + - (int32_t) ao_accel * AO_K_STEP_2_2_1) >> 4; - ao_k_speed += (int32_t) ao_accel * AO_K_STEP_1; + ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_1 + + (ao_k_t) ao_accel * AO_K_STEP_2_2_1) >> 4; + ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_1; return; } if (ao_sample_tick - ao_sample_prev_tick > 5) { - ao_k_height += ((int32_t) ao_speed * AO_K_STEP_10 + - (int32_t) ao_accel * AO_K_STEP_2_2_10) >> 4; - ao_k_speed += (int32_t) ao_accel * AO_K_STEP_10; + ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_10 + + (ao_k_t) ao_accel * AO_K_STEP_2_2_10) >> 4; + ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_10; return; } if (ao_flight_debug) { printf ("predict speed %g + (%g * %g) = %g\n", ao_k_speed / (65536.0 * 16.0), ao_accel / 16.0, AO_K_STEP_100 / 65536.0, - (ao_k_speed + (int32_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0)); + (ao_k_speed + (ao_k_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0)); } #endif - ao_k_height += ((int32_t) ao_speed * AO_K_STEP_100 + - (int32_t) ao_accel * AO_K_STEP_2_2_100) >> 4; - ao_k_speed += (int32_t) ao_accel * AO_K_STEP_100; + ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_100 + + (ao_k_t) ao_accel * AO_K_STEP_2_2_100) >> 4; + ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_100; } static void ao_kalman_err_height(void) { - int16_t e; - int16_t height_distrust; + ao_v_t e; + ao_v_t height_distrust; #if HAS_ACCEL - int16_t speed_distrust; + ao_v_t speed_distrust; #endif - ao_error_h = ao_sample_height - (int16_t) (ao_k_height >> 16); + ao_error_h = ao_sample_height - (ao_v_t) (ao_k_height >> 16); e = ao_error_h; if (e < 0) @@ -123,7 +122,7 @@ ao_kalman_err_height(void) #endif if (height_distrust > 0x100) height_distrust = 0x100; - ao_error_h = (int16_t) (((int32_t) ao_error_h * (0x100 - height_distrust)) >> 8); + ao_error_h = (ao_v_t) (((ao_k_t) ao_error_h * (0x100 - height_distrust)) >> 8); #ifdef AO_FLIGHT_TEST if (ao_flight_debug) { printf("over height %g over speed %g distrust: %g height: error %d -> %d\n", @@ -142,21 +141,21 @@ ao_kalman_correct_baro(void) ao_kalman_err_height(); #ifdef AO_FLIGHT_TEST if (ao_sample_tick - ao_sample_prev_tick > 50) { - ao_k_height += (int32_t) AO_BARO_K0_1 * ao_error_h; - ao_k_speed += (int32_t) AO_BARO_K1_1 * ao_error_h; - ao_k_accel += (int32_t) AO_BARO_K2_1 * ao_error_h; + ao_k_height += (ao_k_t) AO_BARO_K0_1 * ao_error_h; + ao_k_speed += (ao_k_t) AO_BARO_K1_1 * ao_error_h; + ao_k_accel += (ao_k_t) AO_BARO_K2_1 * ao_error_h; return; } if (ao_sample_tick - ao_sample_prev_tick > 5) { - ao_k_height += (int32_t) AO_BARO_K0_10 * ao_error_h; - ao_k_speed += (int32_t) AO_BARO_K1_10 * ao_error_h; - ao_k_accel += (int32_t) AO_BARO_K2_10 * ao_error_h; + ao_k_height += (ao_k_t) AO_BARO_K0_10 * ao_error_h; + ao_k_speed += (ao_k_t) AO_BARO_K1_10 * ao_error_h; + ao_k_accel += (ao_k_t) AO_BARO_K2_10 * ao_error_h; return; } #endif - ao_k_height += (int32_t) AO_BARO_K0_100 * ao_error_h; - ao_k_speed += (int32_t) AO_BARO_K1_100 * ao_error_h; - ao_k_accel += (int32_t) AO_BARO_K2_100 * ao_error_h; + ao_k_height += (ao_k_t) AO_BARO_K0_100 * ao_error_h; + ao_k_speed += (ao_k_t) AO_BARO_K1_100 * ao_error_h; + ao_k_accel += (ao_k_t) AO_BARO_K2_100 * ao_error_h; } #if HAS_ACCEL @@ -164,7 +163,7 @@ ao_kalman_correct_baro(void) static void ao_kalman_err_accel(void) { - int32_t accel; + ao_k_t accel; accel = (ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale; @@ -187,18 +186,18 @@ ao_kalman_correct_both(void) (double) ao_error_h, AO_BOTH_K10_1 / 65536.0, (double) ao_error_a, AO_BOTH_K11_1 / 65536.0, (ao_k_speed + - (int32_t) AO_BOTH_K10_1 * ao_error_h + - (int32_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0)); + (ao_k_t) AO_BOTH_K10_1 * ao_error_h + + (ao_k_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0)); } ao_k_height += - (int32_t) AO_BOTH_K00_1 * ao_error_h + - (int32_t) AO_BOTH_K01_1 * ao_error_a; + (ao_k_t) AO_BOTH_K00_1 * ao_error_h + + (ao_k_t) AO_BOTH_K01_1 * ao_error_a; ao_k_speed += - (int32_t) AO_BOTH_K10_1 * ao_error_h + - (int32_t) AO_BOTH_K11_1 * ao_error_a; + (ao_k_t) AO_BOTH_K10_1 * ao_error_h + + (ao_k_t) AO_BOTH_K11_1 * ao_error_a; ao_k_accel += - (int32_t) AO_BOTH_K20_1 * ao_error_h + - (int32_t) AO_BOTH_K21_1 * ao_error_a; + (ao_k_t) AO_BOTH_K20_1 * ao_error_h + + (ao_k_t) AO_BOTH_K21_1 * ao_error_a; return; } if (ao_sample_tick - ao_sample_prev_tick > 5) { @@ -208,18 +207,18 @@ ao_kalman_correct_both(void) (double) ao_error_h, AO_BOTH_K10_10 / 65536.0, (double) ao_error_a, AO_BOTH_K11_10 / 65536.0, (ao_k_speed + - (int32_t) AO_BOTH_K10_10 * ao_error_h + - (int32_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0)); + (ao_k_t) AO_BOTH_K10_10 * ao_error_h + + (ao_k_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0)); } ao_k_height += - (int32_t) AO_BOTH_K00_10 * ao_error_h + - (int32_t) AO_BOTH_K01_10 * ao_error_a; + (ao_k_t) AO_BOTH_K00_10 * ao_error_h + + (ao_k_t) AO_BOTH_K01_10 * ao_error_a; ao_k_speed += - (int32_t) AO_BOTH_K10_10 * ao_error_h + - (int32_t) AO_BOTH_K11_10 * ao_error_a; + (ao_k_t) AO_BOTH_K10_10 * ao_error_h + + (ao_k_t) AO_BOTH_K11_10 * ao_error_a; ao_k_accel += - (int32_t) AO_BOTH_K20_10 * ao_error_h + - (int32_t) AO_BOTH_K21_10 * ao_error_a; + (ao_k_t) AO_BOTH_K20_10 * ao_error_h + + (ao_k_t) AO_BOTH_K21_10 * ao_error_a; return; } if (ao_flight_debug) { @@ -228,19 +227,19 @@ ao_kalman_correct_both(void) (double) ao_error_h, AO_BOTH_K10_100 / 65536.0, (double) ao_error_a, AO_BOTH_K11_100 / 65536.0, (ao_k_speed + - (int32_t) AO_BOTH_K10_100 * ao_error_h + - (int32_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0)); + (ao_k_t) AO_BOTH_K10_100 * ao_error_h + + (ao_k_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0)); } #endif ao_k_height += - (int32_t) AO_BOTH_K00_100 * ao_error_h + - (int32_t) AO_BOTH_K01_100 * ao_error_a; + (ao_k_t) AO_BOTH_K00_100 * ao_error_h + + (ao_k_t) AO_BOTH_K01_100 * ao_error_a; ao_k_speed += - (int32_t) AO_BOTH_K10_100 * ao_error_h + - (int32_t) AO_BOTH_K11_100 * ao_error_a; + (ao_k_t) AO_BOTH_K10_100 * ao_error_h + + (ao_k_t) AO_BOTH_K11_100 * ao_error_a; ao_k_accel += - (int32_t) AO_BOTH_K20_100 * ao_error_h + - (int32_t) AO_BOTH_K21_100 * ao_error_a; + (ao_k_t) AO_BOTH_K20_100 * ao_error_h + + (ao_k_t) AO_BOTH_K21_100 * ao_error_a; } #else @@ -251,14 +250,14 @@ ao_kalman_correct_accel(void) ao_kalman_err_accel(); if (ao_sample_tick - ao_sample_prev_tick > 5) { - ao_k_height +=(int32_t) AO_ACCEL_K0_10 * ao_error_a; - ao_k_speed += (int32_t) AO_ACCEL_K1_10 * ao_error_a; - ao_k_accel += (int32_t) AO_ACCEL_K2_10 * ao_error_a; + ao_k_height +=(ao_k_t) AO_ACCEL_K0_10 * ao_error_a; + ao_k_speed += (ao_k_t) AO_ACCEL_K1_10 * ao_error_a; + ao_k_accel += (ao_k_t) AO_ACCEL_K2_10 * ao_error_a; return; } - ao_k_height += (int32_t) AO_ACCEL_K0_100 * ao_error_a; - ao_k_speed += (int32_t) AO_ACCEL_K1_100 * ao_error_a; - ao_k_accel += (int32_t) AO_ACCEL_K2_100 * ao_error_a; + ao_k_height += (ao_k_t) AO_ACCEL_K0_100 * ao_error_a; + ao_k_speed += (ao_k_t) AO_ACCEL_K1_100 * ao_error_a; + ao_k_accel += (ao_k_t) AO_ACCEL_K2_100 * ao_error_a; } #endif /* else FORCE_ACCEL */ diff --git a/src/kernel/ao_microkalman.c b/src/kernel/ao_microkalman.c index 0684ea2b..75a29cc4 100644 --- a/src/kernel/ao_microkalman.c +++ b/src/kernel/ao_microkalman.c @@ -22,19 +22,19 @@ #define FIX_BITS 16 -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_v(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix_k(x) ((int32_t) ((x) * 65536.0 + 0.5)) #define from_fix8(x) ((x) >> 8) #define from_fix(x) ((x) >> 16) -#define fix8_to_fix16(x) ((x) << 8) +#define fix8_to_fix_v(x) ((x) << 8) #define fix16_to_fix8(x) ((x) >> 8) #include /* Basic time step (96ms) */ -#define AO_MK_STEP to_fix16(0.096) +#define AO_MK_STEP to_fix_v(0.096) /* step ** 2 / 2 */ -#define AO_MK_STEP_2_2 to_fix16(0.004608) +#define AO_MK_STEP_2_2 to_fix_v(0.004608) uint32_t ao_k_pa; /* 24.8 fixed point */ int32_t ao_k_pa_speed; /* 16.16 fixed point */ @@ -49,7 +49,7 @@ ao_microkalman_init(void) { ao_pa = pa; ao_k_pa = pa << 8; -} +} void ao_microkalman_predict(void) diff --git a/src/kernel/ao_sample.c b/src/kernel/ao_sample.c index 34658951..29bf2bf6 100644 --- a/src/kernel/ao_sample.c +++ b/src/kernel/ao_sample.c @@ -245,7 +245,7 @@ ao_sample_preflight(void) } else { #if HAS_ACCEL ao_accel_2g = ao_config.accel_minus_g - ao_config.accel_plus_g; - ao_accel_scale = to_fix32(GRAVITY * 2 * 16) / ao_accel_2g; + ao_accel_scale = to_fix_32(GRAVITY * 2 * 16) / ao_accel_2g; #endif ao_sample_preflight_set(); ao_preflight = FALSE; diff --git a/src/kernel/ao_sample.h b/src/kernel/ao_sample.h index 16d4c507..2ec998bd 100644 --- a/src/kernel/ao_sample.h +++ b/src/kernel/ao_sample.h @@ -24,6 +24,24 @@ * ao_sample.c */ +#ifndef AO_VALUE_32 +#define AO_VALUE_32 1 +#endif + +#if AO_VALUE_32 +/* + * For 32-bit computed values, use 64-bit intermediates. + */ +typedef int64_t ao_k_t; +typedef int32_t ao_v_t; +#else +/* + * For 16-bit computed values, use 32-bit intermediates. + */ +typedef int32_t ao_k_t; +typedef int16_t ao_v_t; +#endif + /* * Barometer calibration * @@ -87,9 +105,9 @@ * 2047m/s² (over 200g) */ -#define AO_M_TO_HEIGHT(m) ((int16_t) (m)) -#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) -#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16)) +#define AO_M_TO_HEIGHT(m) ((ao_v_t) (m)) +#define AO_MS_TO_SPEED(ms) ((ao_v_t) ((ms) * 16)) +#define AO_MSS_TO_ACCEL(mss) ((ao_v_t) ((mss) * 16)) extern __pdata uint16_t ao_sample_tick; /* time of last data */ extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */ @@ -134,21 +152,33 @@ uint8_t ao_sample(void); * ao_kalman.c */ -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_16(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix_32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_64(x) ((int64_t) ((x) * 65536.0 + 0.5)) + +#ifdef AO_VALUE_32 +#if AO_VALUE_32 +#define to_fix_v(x) to_fix_32(x) +#define to_fix_k(x) to_fix_64(x) +#else +#define to_fix_v(x) to_fix_16(x) +#define to_fix_k(x) to_fix_32(x) +#endif + #define from_fix(x) ((x) >> 16) -extern __pdata int16_t ao_height; /* meters */ -extern __pdata int16_t ao_speed; /* m/s * 16 */ -extern __pdata int16_t ao_accel; /* m/s² * 16 */ -extern __xdata int16_t ao_max_height; /* max of ao_height */ -extern __xdata int16_t ao_avg_height; /* running average of height */ +extern __pdata ao_v_t ao_height; /* meters */ +extern __pdata ao_v_t ao_speed; /* m/s * 16 */ +extern __pdata ao_v_t ao_accel; /* m/s² * 16 */ +extern __xdata ao_v_t ao_max_height; /* max of ao_height */ +extern __xdata ao_v_t ao_avg_height; /* running average of height */ -extern __pdata int16_t ao_error_h; -extern __pdata int16_t ao_error_h_sq_avg; +extern __pdata ao_v_t ao_error_h; +extern __pdata ao_v_t ao_error_h_sq_avg; #if HAS_ACCEL -extern __pdata int16_t ao_error_a; +extern __pdata ao_v_t ao_error_a; +#endif #endif void ao_kalman(void); diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index dbbf57d8..e9b144c0 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -24,6 +24,7 @@ INC = \ altitude.h \ ao_kalman.h \ ao_product.h \ + ao_telemetry.h \ $(TM_INC) CORE_SRC = \ diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile index 25267268..99d29826 100644 --- a/src/telefire-v0.1/Makefile +++ b/src/telefire-v0.1/Makefile @@ -25,7 +25,6 @@ INC = \ CORE_SRC = \ ao_cmd.c \ ao_config.c \ - ao_convert.c \ ao_mutex.c \ ao_panic.c \ ao_stdio.c \ diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile index ad5065c1..944543c5 100644 --- a/src/telefire-v0.2/Makefile +++ b/src/telefire-v0.2/Makefile @@ -25,7 +25,6 @@ INC = \ CORE_SRC = \ ao_cmd.c \ ao_config.c \ - ao_convert.c \ ao_mutex.c \ ao_panic.c \ ao_stdio.c \ diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile index 46c768e4..4a1b3908 100644 --- a/src/telemega-v1.0/Makefile +++ b/src/telemega-v1.0/Makefile @@ -31,6 +31,7 @@ INC = \ ao_mpu.h \ stm32l.h \ math.h \ + ao_ms5607_convert.c \ Makefile # diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 948310e5..ed911798 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -22,6 +22,7 @@ #define HAS_FLIGHT 1 #define HAS_USB 1 +#define AO_VALUE_32 0 #define HAS_USB_PULLUP 1 #define AO_USB_PULLUP_PORT P1 diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h index 60d627ad..472af534 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -72,6 +72,8 @@ #define BATTERY_PIN 5 #define HAS_TELEMETRY 0 + + #define AO_VALUE_32 0 #endif #if DBG_ON_P1 diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 314998c1..bb5c3a7d 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -34,9 +34,11 @@ #define ao_data_ring_next(n) (((n) + 1) & (AO_DATA_RING - 1)) #define ao_data_ring_prev(n) (((n) - 1) & (AO_DATA_RING - 1)) +#if 0 #define AO_M_TO_HEIGHT(m) ((int16_t) (m)) #define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) #define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16)) +#endif #define AO_GPS_NEW_DATA 1 #define AO_GPS_NEW_TRACKING 2 @@ -93,6 +95,7 @@ struct ao_adc { #include #include #include +#include #if TELEMEGA int ao_gps_count; @@ -234,7 +237,7 @@ double main_time; int tick_offset; -static int32_t ao_k_height; +static ao_k_t ao_k_height; int16_t ao_time(void) diff --git a/src/test/ao_micropeak_test.c b/src/test/ao_micropeak_test.c index 5961bd93..f4af707e 100644 --- a/src/test/ao_micropeak_test.c +++ b/src/test/ao_micropeak_test.c @@ -33,6 +33,7 @@ uint8_t ao_flight_debug; #define AO_FLIGHT_TEST typedef int32_t alt_t; +typedef int32_t pres_t; #define AO_MS_TO_TICKS(ms) ((ms) / 10) -- cgit v1.2.3 From 6dc58c63d202e918f16d5fbe9b188d422edcdd9c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:26:19 -0700 Subject: altosui: Fix the 'Graph' button on the landed tab It hasn't been getting enabled since the state tabs were rewritten. Signed-off-by: Keith Packard --- altosui/AltosLanded.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 50c1ea31..7c50adac 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -151,6 +151,12 @@ public class AltosLanded extends AltosUIFlightTab implements ActionListener { return "Landed"; } + public void show(AltosState state, AltosListenerState listener_state) { + super.show(state, listener_state); + if (reader.backing_file() != null) + graph.setEnabled(true); + } + public AltosLanded(AltosFlightReader in_reader) { reader = in_reader; -- cgit v1.2.3 From 59702e5ff8d0522b0aa9dcca863309eaafbcda09 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:27:43 -0700 Subject: altoslib: Extend telemetry heights from 16 to 32 bits Uses the GPS data and/or previous kalman data to compute the upper 16 bits of the truncated telemetry altitude value. Signed-off-by: Keith Packard --- altoslib/AltosConfigData.java | 3 +++ altoslib/AltosConfigValues.java | 2 ++ altoslib/AltosState.java | 28 ++++++++++++++++++++++++---- altoslib/AltosTelemetry.java | 29 +++++++++++++++++++++++++++++ altoslib/AltosTelemetryMegaData.java | 13 ++++++++++--- altoslib/AltosTelemetryMetrumSensor.java | 7 ++++--- altosui/AltosConfigUI.java | 3 +++ 7 files changed, 75 insertions(+), 10 deletions(-) diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 847436cd..134a0ed2 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -31,6 +31,7 @@ public class AltosConfigData implements Iterable { public int log_format; public int log_space; public String version; + public int altitude_32; /* Strings returned */ public LinkedList lines; @@ -274,6 +275,7 @@ public class AltosConfigData implements Iterable { try { flight = get_int(line, "current-flight"); } catch (Exception e) {} try { log_format = get_int(line, "log-format"); } catch (Exception e) {} try { log_space = get_int(line, "log-space"); } catch (Exception e) {} + try { altitude_32 = get_int(line, "altitude-32"); } catch (Exception e) {} try { version = get_string(line, "software-version"); } catch (Exception e) {} /* Version also contains MS5607 info, which we ignore here */ @@ -484,6 +486,7 @@ public class AltosConfigData implements Iterable { dest.set_serial(serial); dest.set_product(product); dest.set_version(version); + dest.set_altitude_32(altitude_32); dest.set_main_deploy(main_deploy); dest.set_apogee_delay(apogee_delay); dest.set_apogee_lockout(apogee_lockout); diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 987da53b..3f0a7075 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -25,6 +25,8 @@ public interface AltosConfigValues { public abstract void set_serial(int serial); + public abstract void set_altitude_32(int altitude_32); + public abstract void set_main_deploy(int new_main_deploy); public abstract int main_deploy() throws AltosConfigDataException; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 2fc13b44..5fce15c4 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -271,6 +271,7 @@ public class AltosState implements Cloneable { public int state; public int flight; public int serial; + public int altitude_32; public int receiver_serial; public boolean landed; public boolean ascent; /* going up? */ @@ -472,15 +473,23 @@ public class AltosState implements Cloneable { pressure.set(p, time); } + public double baro_height() { + double a = altitude(); + double g = ground_altitude(); + if (a != AltosLib.MISSING && g != AltosLib.MISSING) + return a - g; + return AltosLib.MISSING; + } + public double height() { double k = kalman_height.value(); if (k != AltosLib.MISSING) return k; - double a = altitude(); - double g = ground_altitude(); - if (a != AltosLib.MISSING && g != AltosLib.MISSING) - return a - g; + double b = baro_height(); + if (b != AltosLib.MISSING) + return b; + return gps_height(); } @@ -762,6 +771,7 @@ public class AltosState implements Cloneable { product = null; serial = AltosLib.MISSING; receiver_serial = AltosLib.MISSING; + altitude_32 = AltosLib.MISSING; baro = null; companion = null; @@ -899,6 +909,7 @@ public class AltosState implements Cloneable { product = old.product; serial = old.serial; receiver_serial = old.receiver_serial; + altitude_32 = old.altitude_32; baro = old.baro; companion = old.companion; @@ -1066,6 +1077,15 @@ public class AltosState implements Cloneable { receiver_serial = serial; } + public boolean altitude_32() { + return altitude_32 == 1; + } + + public void set_altitude_32(int altitude_32) { + if (altitude_32 != AltosLib.MISSING) + this.altitude_32 = altitude_32; + } + public int rssi() { if (rssi == AltosLib.MISSING) return 0; diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 4d50a059..2f15cd89 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -114,6 +114,35 @@ public abstract class AltosTelemetry implements AltosStateUpdate { return telem; } + public static int extend_height(AltosState state, int height_16) { + double compare_height; + int height = height_16; + + System.out.printf("state kalman height %g altitude %g ground_altitude %g gps_height %g\n", + state.kalman_height.value(), state.altitude(), state.ground_altitude(), state.gps_height()); + if (state.gps != null && state.gps.alt != AltosLib.MISSING) { + compare_height = state.gps_height(); + } else { + compare_height = state.height(); + } + + if (compare_height != AltosLib.MISSING) { + int high_bits = (int) Math.floor (compare_height / 65536.0); + + height = (high_bits << 16) | (height_16 & 0xffff); + + if (Math.abs(height + 65536 - compare_height) < Math.abs(height - compare_height)) + height += 65536; + else if (Math.abs(height - 65536 - compare_height) < Math.abs(height - compare_height)) + height -= 65536; + if (height != height_16) { + System.out.printf("Height adjusted from %d to %d with %g\n", + height_16, height, compare_height); + } + } + return height; + } + public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException { String[] word = line.split("\\s+"); int i =0; diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index 93610118..8b1869bb 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -31,7 +31,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { int acceleration; int speed; - int height; + int height_16; public AltosTelemetryMegaData(int[] bytes) { super(bytes); @@ -55,7 +55,8 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { acceleration = int16(26); speed = int16(28); - height = int16(30); + + height_16 = int16(30); } public void update_state(AltosState state) { @@ -79,7 +80,13 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { state.set_ground_pressure(ground_pres); state.set_accel_g(accel_plus_g, accel_minus_g); - state.set_kalman(height, speed/16.0, acceleration / 16.0); + /* Fill in the high bits of height from recent GPS + * data if available, otherwise guess using the + * previous kalman height + */ + + state.set_kalman(extend_height(state, height_16), + speed/16.0, acceleration / 16.0); } } diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 3e0abedc..beab6da9 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -27,7 +27,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { int acceleration; int speed; - int height; + int height_16; int v_batt; int sense_a; @@ -43,7 +43,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { acceleration = int16(14); speed = int16(16); - height = int16(18); + height_16 = int16(18); v_batt = int16(20); sense_a = int16(22); @@ -59,7 +59,8 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { state.set_pressure(pres); state.set_temperature(temp/100.0); - state.set_kalman(height, speed/16.0, acceleration/16.0); + state.set_kalman(extend_height(state, height_16), + speed/16.0, acceleration/16.0); state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 043cb876..9fcace61 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -926,6 +926,9 @@ public class AltosConfigUI serial_value.setText(String.format("%d", serial)); } + public void set_altitude_32(int altitude_32) { + } + public void set_main_deploy(int new_main_deploy) { main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy)); main_deploy_value.setEnabled(new_main_deploy >= 0); -- cgit v1.2.3 From aac3fdce54233993c91d326df3732a7c448ac54a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 18:42:37 -0700 Subject: libaltos: Bind to libbluetooth at runtime on demand This lets us reliably start and run without libbluetooth present. Signed-off-by: Keith Packard --- libaltos/Makefile.am | 3 +-- libaltos/libaltos.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/libaltos/Makefile.am b/libaltos/Makefile.am index d2531133..1db2d486 100644 --- a/libaltos/Makefile.am +++ b/libaltos/Makefile.am @@ -41,8 +41,7 @@ cjnitest64_LDADD=libaltos64.la endif - -LIBS=-lbluetooth +LIBS=-ldl HFILES=libaltos.h diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index b7ec98fc..a1f1ee4c 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -643,6 +643,49 @@ altos_list_finish(struct altos_list *usbdevs) free(usbdevs); } +#include + +static void *libbt; +static int bt_initialized; + +static int init_bt(void) { + if (!bt_initialized) { + bt_initialized = 1; + libbt = dlopen("libbluetooth.so.3", RTLD_LAZY); + if (!libbt) + printf("failed to find bluetooth library\n"); + } + return libbt != NULL; +} + +#define join(a,b) a ## b +#define bt_func(name, ret, fail, formals, actuals) \ + static ret join(altos_, name) formals { \ + static ret (*name) formals; \ + if (!init_bt()) return fail; \ + name = dlsym(libbt, #name); \ + if (!name) return fail; \ + return name actuals; \ + } + +bt_func(ba2str, int, -1, (const bdaddr_t *ba, char *str), (ba, str)) +#define ba2str altos_ba2str + +bt_func(str2ba, int, -1, (const char *str, bdaddr_t *ba), (str, ba)) +#define str2ba altos_str2ba + +bt_func(hci_read_remote_name, int, -1, (int sock, const bdaddr_t *ba, int len, char *name, int timeout), (sock, ba, len, name, timeout)) +#define hci_read_remote altos_hci_read_remote + +bt_func(hci_open_dev, int, -1, (int dev_id), (dev_id)) +#define hci_open_dev altos_hci_open_dev + +bt_func(hci_get_route, int, -1, (bdaddr_t *bdaddr), (bdaddr)) +#define hci_get_route altos_hci_get_route + +bt_func(hci_inquiry, int, -1, (int adapter_id, int len, int max_rsp, const uint8_t *lap, inquiry_info **devs, long flags), (adapter_id, len, max_rsp, lap, devs, flags)) +#define hci_inquiry altos_hci_inquiry + struct altos_bt_list { inquiry_info *ii; int sock; @@ -706,7 +749,8 @@ altos_bt_list_next(struct altos_bt_list *bt_list, return 0; ii = &bt_list->ii[bt_list->rsp]; - ba2str(&ii->bdaddr, device->addr); + if (ba2str(&ii->bdaddr, device->addr) < 0) + return 0; memset(&device->name, '\0', sizeof (device->name)); if (hci_read_remote_name(bt_list->sock, &ii->bdaddr, sizeof (device->name), @@ -742,11 +786,17 @@ altos_bt_open(struct altos_bt_device *device) struct altos_file *file; file = calloc(1, sizeof (struct altos_file)); - if (!file) + if (!file) { + errno = ENOMEM; + altos_set_last_posix_error(); goto no_file; + } addr.rc_family = AF_BLUETOOTH; addr.rc_channel = 1; - str2ba(device->addr, &addr.rc_bdaddr); + if (str2ba(device->addr, &addr.rc_bdaddr) < 0) { + altos_set_last_posix_error(); + goto no_sock; + } for (i = 0; i < 5; i++) { file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); -- cgit v1.2.3 From 5f5b03879d9daa68a56498b45ae87a804cb1926b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 18:43:31 -0700 Subject: altosui: Don't show bluetooth UI bits on mac/windows This just confuses people into thinking that bluetooth is supported on those machines. Signed-off-by: Keith Packard --- altosui/AltosConfigureUI.java | 8 +++++++- altosuilib/AltosDeviceDialog.java | 3 ++- altosuilib/AltosUIConfigure.java | 3 ++- altosuilib/AltosUILib.java | 8 ++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java index 80d6d341..85a3f6c0 100644 --- a/altosui/AltosConfigureUI.java +++ b/altosui/AltosConfigureUI.java @@ -89,6 +89,8 @@ public class AltosConfigureUI row++; } + boolean has_bluetooth; + public void add_bluetooth() { JButton manage_bluetooth = new JButton("Manage Bluetooth"); manage_bluetooth.addActionListener(new ActionListener() { @@ -98,6 +100,7 @@ public class AltosConfigureUI }); pane.add(manage_bluetooth, constraints(0, 2)); /* in the same row as add_frequencies, so don't bump row */ + has_bluetooth = true; } public void add_frequencies() { @@ -108,7 +111,10 @@ public class AltosConfigureUI } }); manage_frequencies.setToolTipText("Configure which values are shown in frequency menus"); - pane.add(manage_frequencies, constraints(2, 1)); + if (has_bluetooth) + pane.add(manage_frequencies, constraints(2, 1)); + else + pane.add(manage_frequencies, constraints(0, 3)); row++; } diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java index 0875bea7..d2ccd5e7 100644 --- a/altosuilib/AltosDeviceDialog.java +++ b/altosuilib/AltosDeviceDialog.java @@ -131,7 +131,8 @@ public abstract class AltosDeviceDialog extends AltosUIDialog implements ActionL buttonPane.add(cancel_button); buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); - add_bluetooth(); + if (AltosUILib.has_bluetooth) + add_bluetooth(); buttonPane.add(select_button); diff --git a/altosuilib/AltosUIConfigure.java b/altosuilib/AltosUIConfigure.java index 5648d1df..9c0f3bc7 100644 --- a/altosuilib/AltosUIConfigure.java +++ b/altosuilib/AltosUIConfigure.java @@ -283,7 +283,8 @@ public class AltosUIConfigure add_look_and_feel(); add_position(); add_map_cache(); - add_bluetooth(); + if (AltosUILib.has_bluetooth) + add_bluetooth(); add_frequencies(); /* And a close button at the bottom */ diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 0050f12c..8fa7dfe6 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -80,6 +80,7 @@ public class AltosUILib extends AltosLib { static public boolean initialized = false; static public boolean loaded_library = false; + static public boolean has_bluetooth = false; static final String[] library_names = { "altos", "altos32", "altos64" }; @@ -96,6 +97,13 @@ public class AltosUILib extends AltosLib { loaded_library = false; } } + + String OS = System.getProperty("os.name"); + + if (OS.startsWith("Linux")) { + has_bluetooth = true; + } + initialized = true; } return loaded_library; -- cgit v1.2.3 From 405626971b47d4d4031312232bf13ad3d4bace7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 21:13:49 -0700 Subject: libaltos: typo in libaltos broke the build When converting this to use dlopen, I mis-typed the name hci_read_remote_name Signed-off-by: Keith Packard --- libaltos/libaltos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index a1f1ee4c..4e3bc2c5 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -675,7 +675,7 @@ bt_func(str2ba, int, -1, (const char *str, bdaddr_t *ba), (str, ba)) #define str2ba altos_str2ba bt_func(hci_read_remote_name, int, -1, (int sock, const bdaddr_t *ba, int len, char *name, int timeout), (sock, ba, len, name, timeout)) -#define hci_read_remote altos_hci_read_remote +#define hci_read_remote_name altos_hci_read_remote_name bt_func(hci_open_dev, int, -1, (int dev_id), (dev_id)) #define hci_open_dev altos_hci_open_dev -- cgit v1.2.3 From fa155693282746861b227afd6cbccc83dfd1bbed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 21:27:30 -0700 Subject: telegps: Missing function in TeleGPSConfigUI set_altitude_32 was added to the abstract class but not here. Signed-off-by: Keith Packard --- telegps/TeleGPSConfigUI.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/telegps/TeleGPSConfigUI.java b/telegps/TeleGPSConfigUI.java index 2bd1d2df..7a59bf48 100644 --- a/telegps/TeleGPSConfigUI.java +++ b/telegps/TeleGPSConfigUI.java @@ -670,6 +670,9 @@ public class TeleGPSConfigUI serial_value.setText(String.format("%d", serial)); } + public void set_altitude_32(int altitude_32) { + } + public void set_main_deploy(int new_main_deploy) { } -- cgit v1.2.3 From a60ba449ec237ad3b8dade9dcea603b349dbccb1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Jul 2014 23:52:05 -0700 Subject: altos/telefire,telelco: Add HAS_RADIO_RATE to launch system software This lets us set the rate to a lower value to improve range. 9600 baud works great; 2400 baud makes the initial search take a long time. Signed-off-by: Keith Packard --- src/drivers/ao_lco_func.c | 16 +++++++++++++++- src/telefire-v0.2/ao_pins.h | 1 + src/telelco-v0.2/ao_lco.c | 2 +- src/telelco-v0.2/ao_pins.h | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c index 9e642836..32c00068 100644 --- a/src/drivers/ao_lco_func.c +++ b/src/drivers/ao_lco_func.c @@ -28,7 +28,21 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset) { int8_t r; uint16_t sent_time; + uint16_t timeout = AO_MS_TO_TICKS(10); +#if HAS_RADIO_RATE + switch (ao_config.radio_rate) { + case AO_RADIO_RATE_38400: + default: + break; + case AO_RADIO_RATE_9600: + timeout = AO_MS_TO_TICKS(20); + break; + case AO_RADIO_RATE_2400: + timeout = AO_MS_TO_TICKS(80); + break; + } +#endif ao_mutex_get(&ao_lco_mutex); command.tick = ao_time() - *tick_offset; command.box = box; @@ -36,7 +50,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset) command.channels = 0; ao_radio_cmac_send(&command, sizeof (command)); sent_time = ao_time(); - r = ao_radio_cmac_recv(query, sizeof (*query), AO_MS_TO_TICKS(10)); + r = ao_radio_cmac_recv(query, sizeof (*query), timeout); if (r == AO_RADIO_CMAC_OK) *tick_offset = sent_time - query->tick; ao_mutex_put(&ao_lco_mutex); diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index 9e6631ce..ef2d4822 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -19,6 +19,7 @@ #define _AO_PINS_H_ #define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 0 #define HAS_FLIGHT 0 diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index b3f5bb16..4b5f7a9b 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -258,7 +258,7 @@ ao_lco_search(void) for (box = 0; box < AO_PAD_MAX_BOXES; box++) { if ((box % 10) == 0) ao_lco_set_box(box); - for (try = 0; try < 5; try++) { + for (try = 0; try < 3; try++) { tick_offset = 0; r = ao_lco_query(box, &ao_pad_query, &tick_offset); PRINTD("box %d result %d\n", box, r); diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index a6fd4ff8..da790b14 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -48,6 +48,7 @@ #define HAS_USB 1 #define HAS_BEEP 1 #define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 0 #define HAS_AES 1 -- cgit v1.2.3 From e447e1e5c90d3fc1be9c5a1c966c7c688a87ba18 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 11:06:29 -0700 Subject: ao-tools: Add TMv2 and Tgps log formats to cc.h Signed-off-by: Keith Packard --- ao-tools/lib/cc.h | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index c07f8cd0..c434b102 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -346,6 +346,143 @@ struct ao_log_mega { } u; }; +struct ao_log_metrum { + char type; /* 0 */ + uint8_t csum; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t ground_accel; /* 6 */ + uint32_t ground_pres; /* 8 */ + uint32_t ground_temp; /* 12 */ + } flight; /* 16 */ + /* AO_LOG_STATE */ + struct { + uint16_t state; /* 4 */ + uint16_t reason; /* 6 */ + } state; /* 8 */ + /* AO_LOG_SENSOR */ + struct { + uint32_t pres; /* 4 */ + uint32_t temp; /* 8 */ + int16_t accel; /* 12 */ + } sensor; /* 14 */ + /* AO_LOG_TEMP_VOLT */ + struct { + int16_t v_batt; /* 4 */ + int16_t sense_a; /* 6 */ + int16_t sense_m; /* 8 */ + } volt; /* 10 */ + /* AO_LOG_GPS_POS */ + struct { + int32_t latitude; /* 4 */ + int32_t longitude; /* 8 */ + uint16_t altitude_low; /* 12 */ + int16_t altitude_high; /* 14 */ + } gps; /* 16 */ + /* AO_LOG_GPS_TIME */ + struct { + uint8_t hour; /* 4 */ + uint8_t minute; /* 5 */ + uint8_t second; /* 6 */ + uint8_t flags; /* 7 */ + uint8_t year; /* 8 */ + uint8_t month; /* 9 */ + uint8_t day; /* 10 */ + uint8_t pdop; /* 11 */ + } gps_time; /* 12 */ + /* AO_LOG_GPS_SAT (up to three packets) */ + struct { + uint8_t channels; /* 4 */ + uint8_t more; /* 5 */ + struct { + uint8_t svid; + uint8_t c_n; + } sats[4]; /* 6 */ + } gps_sat; /* 14 */ + uint8_t raw[12]; /* 4 */ + } u; /* 16 */ +}; + +struct ao_log_mini { + char type; /* 0 */ + uint8_t csum; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + uint16_t r6; + uint32_t ground_pres; /* 8 */ + } flight; + /* AO_LOG_STATE */ + struct { + uint16_t state; /* 4 */ + uint16_t reason; /* 6 */ + } state; + /* AO_LOG_SENSOR */ + struct { + uint8_t pres[3]; /* 4 */ + uint8_t temp[3]; /* 7 */ + int16_t sense_a; /* 10 */ + int16_t sense_m; /* 12 */ + int16_t v_batt; /* 14 */ + } sensor; /* 16 */ + } u; /* 16 */ +}; /* 16 */ + +#define ao_log_pack24(dst,value) do { \ + (dst)[0] = (value); \ + (dst)[1] = (value) >> 8; \ + (dst)[2] = (value) >> 16; \ + } while (0) + +struct ao_log_gps { + char type; /* 0 */ + uint8_t csum; /* 1 */ + uint16_t tick; /* 2 */ + union { /* 4 */ + /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t start_altitude; /* 6 */ + int32_t start_latitude; /* 8 */ + int32_t start_longitude; /* 12 */ + } flight; /* 16 */ + /* AO_LOG_GPS_TIME */ + struct { + int32_t latitude; /* 4 */ + int32_t longitude; /* 8 */ + uint16_t altitude_low; /* 12 */ + uint8_t hour; /* 14 */ + uint8_t minute; /* 15 */ + uint8_t second; /* 16 */ + uint8_t flags; /* 17 */ + uint8_t year; /* 18 */ + uint8_t month; /* 19 */ + uint8_t day; /* 20 */ + uint8_t course; /* 21 */ + uint16_t ground_speed; /* 22 */ + int16_t climb_rate; /* 24 */ + uint8_t pdop; /* 26 */ + uint8_t hdop; /* 27 */ + uint8_t vdop; /* 28 */ + uint8_t mode; /* 29 */ + int16_t altitude_high; /* 30 */ + } gps; /* 31 */ + /* AO_LOG_GPS_SAT */ + struct { + uint16_t channels; /* 4 */ + struct { + uint8_t svid; + uint8_t c_n; + } sats[12]; /* 6 */ + } gps_sat; /* 30 */ + } u; +}; + #define AO_CONFIG_CONFIG 1 #define AO_CONFIG_MAIN 2 #define AO_CONFIG_APOGEE 3 @@ -383,6 +520,18 @@ struct ao_log_mega { #define AO_LOG_CONFIG 'c' +#define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ +#define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */ +#define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */ +#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */ +#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */ +#define AO_LOG_FORMAT_TELEMEGA 5 /* 32 byte typed telemega records */ +#define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */ +#define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */ +#define AO_LOG_FORMAT_TELEMINI 8 /* 16-byte MS5607 baro only, 3.3V supply */ +#define AO_LOG_FORMAT_TELEGPS 9 /* 32 byte telegps records */ +#define AO_LOG_FORMAT_NONE 127 /* No log at all */ + int cc_mega_parse(const char *input_line, struct ao_log_mega *l); @@ -398,6 +547,9 @@ cc_pressure_to_altitude(double pressure); double cc_altitude_to_pressure(double altitude); +double +cc_altitude_to_temperature(double altitude); + double cc_barometer_to_pressure(double baro); -- cgit v1.2.3 From 6c9daa4f471ac90ffce3bfe8876c9008f79a5b7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:40:40 -0700 Subject: ao-tools: Provide altitude to temperature conversion function This takes altitude and computes the 'normal' temperature for that. Signed-off-by: Keith Packard --- ao-tools/lib/cc-convert.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ao-tools/lib/cc-convert.c b/ao-tools/lib/cc-convert.c index 8d6876a0..b82dd778 100644 --- a/ao-tools/lib/cc-convert.c +++ b/ao-tools/lib/cc-convert.c @@ -108,6 +108,29 @@ cc_altitude_to_pressure(double altitude) return pressure; } +double +cc_altitude_to_temperature(double altitude) +{ + + double base_temperature = LAYER0_BASE_TEMPERATURE; + double temperature; + + int layer_number; /* identifies layer in the atmosphere */ + double delta_z; /* difference between two altitudes */ + + /* calculate the base temperature 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]; + base_temperature += delta_z * lapse_rate[layer_number]; + } + + /* calculate the pressure at the inputted altitude */ + delta_z = altitude - base_altitude[layer_number]; + temperature = base_temperature + lapse_rate[layer_number] * delta_z; + + return temperature - 273.15; +} /* outputs the altitude associated with the given pressure. the altitude returned is measured with respect to the mean sea level */ -- cgit v1.2.3 From 5d1adc6775a66633661af747bc4176e06f97630f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:41:36 -0700 Subject: ao-tools: Add a few GPS telem/eeprom constants These make it possible to encode/decode GPS data from telemetry and eeprom files Signed-off-by: Keith Packard --- ao-tools/lib/cc.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index c434b102..bff4b2c9 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -517,9 +517,18 @@ struct ao_log_gps { #define AO_LOG_GPS_ALT 'H' #define AO_LOG_GPS_SAT 'V' #define AO_LOG_GPS_DATE 'Y' +#define AO_LOG_GPS_POS 'P' #define AO_LOG_CONFIG 'c' +#define AO_GPS_NUM_SAT_MASK (0xf << 0) +#define AO_GPS_NUM_SAT_SHIFT (0) + +#define AO_GPS_VALID (1 << 4) +#define AO_GPS_RUNNING (1 << 5) +#define AO_GPS_DATE_VALID (1 << 6) +#define AO_GPS_COURSE_VALID (1 << 7) + #define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ #define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */ #define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */ -- cgit v1.2.3 From 6c3d09bf40f2af6e8722f33a70b41e5d94ceaf9f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:42:41 -0700 Subject: altos: Interrupt radio receive when changing data rate This aborts any pending radio receive when changing the data rate so that the radio can be reprogrammed to receive at the correct rate. Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 32a0967c..d73a3733 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -518,6 +518,9 @@ ao_config_radio_rate_set(void) __reentrant ao_telemetry_reset_interval(); #endif _ao_config_edit_finish(); +#if HAS_RADIO_RECV + ao_radio_recv_abort(); +#endif } #endif -- cgit v1.2.3 From 50aec54bdc35962145eff9b465f9cd7b3d9fea0b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:43:27 -0700 Subject: altos: Make ao_gps_print deal with telem containing 32-bit altitude values ao_gps_print is used with new telem packets from a few places; use AO_TELEMETRY_LOCATION_ALTITUDE when necessary. Signed-off-by: Keith Packard --- src/kernel/ao_gps_print.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/kernel/ao_gps_print.c b/src/kernel/ao_gps_print.c index 47c945d7..d26021da 100644 --- a/src/kernel/ao_gps_print.c +++ b/src/kernel/ao_gps_print.c @@ -20,6 +20,10 @@ #endif #include "ao_telem.h" +#ifndef AO_TELEMETRY_LOCATION_ALTITUDE +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#endif + void ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant { @@ -42,7 +46,7 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant AO_TELEM_GPS_ALTITUDE " %d ", (long) gps_data->latitude, (long) gps_data->longitude, - gps_data->altitude); + AO_TELEMETRY_LOCATION_ALTITUDE(gps_data)); if (gps_data->flags & AO_GPS_DATE_VALID) printf(AO_TELEM_GPS_YEAR " %d " -- cgit v1.2.3 From 0fd867f504dd7df62e95da98ded511bb7b9e4c66 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:44:39 -0700 Subject: altos/test: Build TeleMetrumV2 flight test variant Parses TeleMetrumV2 eeprom files and runs the TeleMetrumV2 flight code. Signed-off-by: Keith Packard --- src/test/Makefile | 4 ++ src/test/ao_flight_test.c | 108 ++++++++++++++++++++++++++++++++++++---------- src/test/plottest | 6 +-- 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/src/test/Makefile b/src/test/Makefile index 017f7f71..02e1d22b 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,6 +1,7 @@ vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ + ao_flight_test_metrum \ ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \ ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \ ao_ms5607_convert_test ao_quaternion_test @@ -33,6 +34,9 @@ ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kal ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) cc -DTELEMEGA=1 $(CFLAGS) -o $@ $< -lm +ao_flight_test_metrum: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) + cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $< -lm + ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h cc $(CFLAGS) -o $@ $< diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index bb5c3a7d..8b737ca1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -45,6 +45,10 @@ int ao_gps_new; +#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) +#define TELEMETRUM_V1 1 +#endif + #if TELEMEGA #define AO_ADC_NUM_SENSE 6 #define HAS_MS5607 1 @@ -60,7 +64,25 @@ struct ao_adc { int16_t v_pbatt; int16_t temp; }; -#else +#endif + +#if TELEMETRUM_V2 +#define AO_ADC_NUM_SENSE 2 +#define HAS_MS5607 1 +#define HAS_MMA655X 1 +#define HAS_BEEP 1 +#define AO_CONFIG_MAX_SIZE 1024 + +struct ao_adc { + int16_t sense_a; + int16_t sense_m; + int16_t v_batt; + int16_t temp; +}; +#endif + + +#if TELEMETRUM_V1 /* * One set of samples read from the A/D converter */ @@ -189,17 +211,6 @@ ao_gps_angle(void) #define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) #define from_fix(x) ((x) >> 16) -/* - * Above this height, the baro sensor doesn't work - */ -#define AO_BARO_SATURATE 13000 -#define AO_MIN_BARO_VALUE ao_altitude_to_pres(AO_BARO_SATURATE) - -/* - * Above this speed, baro measurements are unreliable - */ -#define AO_MAX_BARO_SPEED 200 - #define ACCEL_NOSE_UP (ao_accel_2g >> 2) extern enum ao_flight_state ao_flight_state; @@ -309,7 +320,7 @@ struct ao_cmds { #define ao_xmemcmp(d,s,c) memcmp(d,s,c) #define AO_NEED_ALTITUDE_TO_PRES 1 -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2 #include "ao_convert_pa.c" #include struct ao_ms5607_prom ao_ms5607_prom; @@ -459,7 +470,7 @@ ao_insert(void) #else double accel = 0.0; #endif -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2 double height; ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); @@ -554,6 +565,7 @@ ao_insert(void) mag_azel.el, mag_azel.az); #endif +#if 0 printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d dist %12.2f gps_tilt %4d gps_sats %2d\n", time, ao_state_names[ao_flight_state], @@ -563,6 +575,7 @@ ao_insert(void) (int) floor (ao_gps_angle() + 0.5), (ao_gps_static.flags & 0xf) * 10); +#endif #if 0 printf ("\t\tstate %-8.8s ground az: %4d el %4d mag az %4d el %4d rot az %4d el %4d el_diff %4d az_diff %4d angle %4d tilt %4d ground %8.5f %8.5f %8.5f cur %8.5f %8.5f %8.5f rot %8.5f %8.5f %8.5f\n", ao_state_names[ao_flight_state], @@ -585,9 +598,9 @@ ao_insert(void) #endif #endif -#if 0 +#if 1 printf("%7.2f height %8.2f accel %8.3f " -#if TELEMEGA +#if TELEMEGA && 0 "angle %5d " "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d " #endif @@ -595,7 +608,7 @@ ao_insert(void) time, height, accel, -#if TELEMEGA +#if TELEMEGA && 0 ao_sample_orient, ao_mpu6000_accel(ao_data_static.mpu6000.accel_x), @@ -678,7 +691,8 @@ ao_sleep(void *wchan) { #if TELEMEGA ao_data_static.mpu6000 = ao_ground_mpu6000; -#else +#endif +#if TELEMETRUM_V1 ao_data_static.adc.accel = ao_flight_ground_accel; #endif ao_insert(); @@ -807,7 +821,59 @@ ao_sleep(void *wchan) } } } -#else +#endif +#if TELEMETRUM_V2 + if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) { + int i; + struct ao_ms5607_value value; + + type = words[0][0]; + tick = strtoul(words[1], NULL, 16); +// printf ("%c %04x", type, tick); + for (i = 2; i < nword; i++) { + bytes[i - 2] = strtoul(words[i], NULL, 16); +// printf(" %02x", bytes[i-2]); + } +// printf ("\n"); + switch (type) { + case 'F': + ao_flight_ground_accel = int16(bytes, 2); + ao_flight_started = 1; + ao_ground_pres = int32(bytes, 4); + ao_ground_height = ao_pa_to_altitude(ao_ground_pres); + break; + case 'A': + ao_data_static.tick = tick; + ao_data_static.ms5607_raw.pres = int32(bytes, 0); + ao_data_static.ms5607_raw.temp = int32(bytes, 4); + ao_ms5607_convert(&ao_data_static.ms5607_raw, &value); + ao_data_static.mma655x = int16(bytes, 8); + ao_records_read++; + ao_insert(); + return; + } + continue; + } else if (nword == 3 && strcmp(words[0], "ms5607") == 0) { + if (strcmp(words[1], "reserved:") == 0) + ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "sens:") == 0) + ao_ms5607_prom.sens = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "off:") == 0) + ao_ms5607_prom.off = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "tcs:") == 0) + ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "tco:") == 0) + ao_ms5607_prom.tco = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "tref:") == 0) + ao_ms5607_prom.tref = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "tempsens:") == 0) + ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10); + else if (strcmp(words[1], "crc:") == 0) + ao_ms5607_prom.crc = strtoul(words[2], NULL, 10); + continue; + } +#endif +#if TELEMETRUM_V1 if (nword == 4 && log_format != AO_LOG_FORMAT_TELEMEGA) { type = words[0][0]; tick = strtoul(words[1], NULL, 16); @@ -932,7 +998,7 @@ ao_sleep(void *wchan) if (type != 'F' && !ao_flight_started) continue; -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2 (void) a; (void) b; #else @@ -953,8 +1019,6 @@ ao_sleep(void *wchan) ao_data_static.tick = tick; ao_data_static.adc.accel = a; ao_data_static.adc.pres_real = b; - if (b < AO_MIN_BARO_VALUE) - b = AO_MIN_BARO_VALUE; ao_data_static.adc.pres = b; ao_records_read++; ao_insert(); diff --git a/src/test/plottest b/src/test/plottest index 76af5ee7..7d253ff1 100755 --- a/src/test/plottest +++ b/src/test/plottest @@ -10,7 +10,7 @@ plot "$1" using 1:3 with lines axes x1y1 title "raw height",\ "$1" using 1:9 with lines axes x1y1 title "height",\ "$1" using 1:11 with lines axes x1y2 title "speed",\ "$1" using 1:13 with lines axes x1y2 title "accel",\ -"$1" using 1:15 with lines axes x1y1 title "drogue",\ -"$1" using 1:17 with lines axes x1y1 title "main",\ -"$1" using 1:19 with lines axes x1y1 title "error" +"$1" using 1:17 with lines axes x1y1 title "drogue",\ +"$1" using 1:19 with lines axes x1y1 title "main",\ +"$1" using 1:21 with lines axes x1y1 title "error" EOF -- cgit v1.2.3 From 9e9151c3b4bb9ce329e1b44440a7aceb9f39b9a0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Jul 2014 00:45:13 -0700 Subject: altoslib: Parse eeprom 'altitude-32' fields This lets us tell if the altimeter supports 32-bit GPS altitudes in the eeprom log. Signed-off-by: Keith Packard --- altoslib/AltosEepromHeader.java | 35 +++++++++++++++++++++++++++++++++++ altoslib/AltosLib.java | 14 ++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index 47e9eceb..71030655 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -96,6 +96,22 @@ public class AltosEepromHeader extends AltosEeprom { case AltosLib.AO_LOG_SOFTWARE_VERSION: state.set_firmware_version(data); break; + case AltosLib.AO_LOG_FREQUENCY: + case AltosLib.AO_LOG_APOGEE_LOCKOUT: + case AltosLib.AO_LOG_RADIO_RATE: + case AltosLib.AO_LOG_IGNITE_MODE: + case AltosLib.AO_LOG_PAD_ORIENTATION: + case AltosLib.AO_LOG_RADIO_ENABLE: + case AltosLib.AO_LOG_AES_KEY: + case AltosLib.AO_LOG_APRS: + case AltosLib.AO_LOG_BEEP_SETTING: + case AltosLib.AO_LOG_TRACKER_SETTING: + case AltosLib.AO_LOG_PYRO_TIME: + case AltosLib.AO_LOG_APRS_ID: + break; + case AltosLib.AO_LOG_ALTITUDE_32: + state.set_altitude_32(config_a); + break; } } @@ -161,6 +177,22 @@ public class AltosEepromHeader extends AltosEeprom { case AltosLib.AO_LOG_BARO_CRC: out.printf ("# Baro crc: %d\n", config_a); break; + case AltosLib.AO_LOG_FREQUENCY: + case AltosLib.AO_LOG_APOGEE_LOCKOUT: + case AltosLib.AO_LOG_RADIO_RATE: + case AltosLib.AO_LOG_IGNITE_MODE: + case AltosLib.AO_LOG_PAD_ORIENTATION: + case AltosLib.AO_LOG_RADIO_ENABLE: + case AltosLib.AO_LOG_AES_KEY: + case AltosLib.AO_LOG_APRS: + case AltosLib.AO_LOG_BEEP_SETTING: + case AltosLib.AO_LOG_TRACKER_SETTING: + case AltosLib.AO_LOG_PYRO_TIME: + case AltosLib.AO_LOG_APRS_ID: + break; + case AltosLib.AO_LOG_ALTITUDE_32: + out.printf("# Altitude-32: %d\n", config_a); + break; } } @@ -205,6 +237,9 @@ public class AltosEepromHeader extends AltosEeprom { } else if (tokens[0].equals("log-format")) { cmd = AltosLib.AO_LOG_LOG_FORMAT; config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("altitude-32")) { + cmd = AltosLib.AO_LOG_ALTITUDE_32; + config_a = Integer.parseInt(tokens[1]); } else if (tokens[0].equals("software-version")) { cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; data = tokens[1]; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index eb188d6b..68bdd17f 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -51,6 +51,20 @@ public class AltosLib { public static final int AO_LOG_SERIAL_NUMBER = 2002; public static final int AO_LOG_LOG_FORMAT = 2003; + public static final int AO_LOG_FREQUENCY = 2004; + public static final int AO_LOG_APOGEE_LOCKOUT = 2005; + public static final int AO_LOG_RADIO_RATE = 2006; + public static final int AO_LOG_IGNITE_MODE = 2007; + public static final int AO_LOG_PAD_ORIENTATION = 2008; + public static final int AO_LOG_RADIO_ENABLE = 2009; + public static final int AO_LOG_AES_KEY = 2010; + public static final int AO_LOG_APRS = 2011; + public static final int AO_LOG_BEEP_SETTING = 2012; + public static final int AO_LOG_TRACKER_SETTING = 2013; + public static final int AO_LOG_PYRO_TIME = 2014; + public static final int AO_LOG_APRS_ID = 2015; + public static final int AO_LOG_ALTITUDE_32 = 2016; + /* Added for header fields in telemega files */ public static final int AO_LOG_BARO_RESERVED = 3000; public static final int AO_LOG_BARO_SENS = 3001; -- cgit v1.2.3 From 54b58e925e27e87bf2903678f87b7544ee2e8167 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Jul 2014 00:46:41 -0700 Subject: Set version to 1.4.9.2 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8cc5adc1..c2b8b55c 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.4.9.1) +AC_INIT([altos], 1.4.9.2) AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From fb914d37018a585a879161483609d3c0be556d1e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Jul 2014 02:32:03 -0700 Subject: altosuilib: Fix minor scan UI nits Wasn't computing geometry correctly and overlapped the 2400 baud entry with the list of scan results. Was not saving the telemetry rate/telemetry style when switching to monitor mode, which caused the new monitor to come up with the wrong values. Signed-off-by: Keith Packard --- altosuilib/AltosScanUI.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/altosuilib/AltosScanUI.java b/altosuilib/AltosScanUI.java index 7b5f2c7e..7e51a55a 100644 --- a/altosuilib/AltosScanUI.java +++ b/altosuilib/AltosScanUI.java @@ -356,10 +356,13 @@ public class AltosScanUI if (r != null) { if (device != null) { if (reader != null) { + System.out.printf("frequency %g rate %d\n", r.frequency.frequency, r.rate); reader.set_telemetry(r.telemetry); reader.set_telemetry_rate(r.rate); reader.set_frequency(r.frequency.frequency); reader.save_frequency(); + reader.save_telemetry(); + reader.save_telemetry_rate(); owner.scan_device_selected(device); } } @@ -519,7 +522,7 @@ public class AltosScanUI rate_boxes[k].addActionListener(this); rate_boxes[k].setSelected((scanning_rate & (1 << k)) != 0); } - y_offset_rate += AltosLib.ao_telemetry_rate_max; + y_offset_rate += AltosLib.ao_telemetry_rate_max + 1; } if (select_telemetry) { -- cgit v1.2.3 From ec7ceb607f5ba7e1ed5cfd32b7a452a5f364b095 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 15 Jul 2014 00:44:14 -0700 Subject: linux-fat: Fix up fat linux install icons, mime types and .desktop files use the standard xdg utilities to install mime type and .desktop files. The standard xdg icon installer doesn't handle svg icons, so we have to do those manually. With this patch, xfce, gnome3 and kde4 all place the applications in user-visible menus, display correct file icons and launch correct applications for our file types. Signed-off-by: Keith Packard --- altosui/Makefile.am | 10 +++++- altosui/linux-install.sh | 79 +++++++++++++++++++++++++----------------------- micropeak/Makefile.am | 9 +++++- telegps/Makefile.am | 10 +++++- 4 files changed, 68 insertions(+), 40 deletions(-) diff --git a/altosui/Makefile.am b/altosui/Makefile.am index c79e27c0..44258fd2 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -104,6 +104,14 @@ MACOSX_ICONS =\ $(ICONDIR)/application-vnd.altusmetrum.eeprom.icns \ $(ICONDIR)/application-vnd.altusmetrum.telemetry.icns +LINUX_ICONS =\ + $(ICONDIR)/altusmetrum-altosui.svg \ + $(ICONDIR)/application-vnd.altusmetrum.eeprom.svg \ + $(ICONDIR)/application-vnd.altusmetrum.telemetry.svg + +LINUX_MIMETYPE =\ + $(ICONDIR)/org-altusmetrum-mimetypes.xml + # Firmware FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx FIRMWARE_TD=$(FIRMWARE_TD_0_2) @@ -152,7 +160,7 @@ FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFR LINUX_LIBS=libaltos32.so libaltos64.so -LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(ICONDIR)/altusmetrum-altosui.svg +LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE) LINUX_EXTRA=altosui-fat MACOSX_INFO_PLIST=Info.plist diff --git a/altosui/linux-install.sh b/altosui/linux-install.sh index 957b1aad..2e44c2aa 100644 --- a/altosui/linux-install.sh +++ b/altosui/linux-install.sh @@ -130,6 +130,7 @@ esac # # Create the .desktop file by editing the paths # + case "$target" in /*) target_abs="$target" @@ -149,43 +150,46 @@ for infile in "$target"/AltOS/*.desktop.in; do done # -# Figure out where to install the .desktop files. If we can, write it -# to the public /usr/share/applications, otherwise, write it to the -# per-user ~/.local/share/applications +# Install the .desktop file # -public=/usr/share/applications -private=$HOME/.local/share/applications -apps="" +for desktop in "$target"/AltOS/*.desktop; do + case `id -u` in + 0) + xdg-desktop-menu install --mode system "$desktop" + ;; + *) + xdg-desktop-menu install --mode user "$desktop" + ;; + esac +done -if [ -d "$public" -a -w "$public" ]; then - apps="$public" -else - mkdir -p "$private" >/dev/null 2>&1 - if [ -d "$private" -a -w "$private" ]; then - apps="$private" - fi -fi - -case "$apps" in -"") - echo "Cannot install application icon" - finish 1 - ;; -esac +# +# Install mime type file +# + +for mimetype in "$target"/AltOS/*-mimetypes.xml; do + case `id -u` in + 0) + xdg-mime install --mode system "$mimetype" + ;; + *) + xdg-mime install --mode user "$mimetype" + ;; + esac +done -echo -n "Installing .desktop files to $apps..." +# +# Install icons +# -cp "$target"/AltOS/*.desktop "$apps" +for icon_dir in /usr/share/icons/hicolor/scalable/mimetypes "$HOME/.icons" "$HOME/.kde/share/icons"; do + if [ -w "$icon_dir" ]; then + cp "$target"/AltOS/*.svg "$icon_dir" + update-icon-caches "$icon_dir" + fi +done -case "$?" in -0) - echo " done." - ;; -*) - echo " failed." - ;; -esac # # Install icon to desktop if desired @@ -222,13 +226,14 @@ if [ -d $HOME/Desktop ]; then esac done - echo -n "Installing desktop icons..." case "$do_desktop" in - [yY]*) - for d in "$target"/AltOS/*.desktop; do - ln -f -s "$d" "$HOME/Desktop/" - done - ;; + [yY]*) + echo -n "Installing desktop icons..." + for d in "$target"/AltOS/*.desktop; do + base=`basename $d` + cp --remove-destination "$d" "$HOME/Desktop/" + done + ;; esac echo " done." diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index e3b77c8a..15865606 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -82,6 +82,13 @@ MACOSX_ICONS =\ ../icon/altusmetrum-micropeak.icns \ ../icon/application-vnd.altusmetrum.micropeak.icns +LINUX_ICONS =\ + $(ICONDIR)/altusmetrum-micropeak.svg \ + $(ICONDIR)/application-vnd.altusmetrum.micropeak.svg + +LINUX_MIMETYPE =\ + $(ICONDIR)/org-altusmetrum-mimetypes.xml + desktopdir = $(datadir)/applications desktop_file = altusmetrum-micropeak.desktop desktop_SCRIPTS = $(desktop_file) @@ -114,7 +121,7 @@ DOC=$(MICROPEAK_DOC) FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) -LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in ../icon/altusmetrum-micropeak.svg +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE) LINUX_EXTRA=micropeak-fat $(desktop_file).in MACOSX_DRIVER_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg diff --git a/telegps/Makefile.am b/telegps/Makefile.am index 6138b004..3b33428e 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -87,6 +87,14 @@ MACOSX_ICONS =\ ../icon/application-vnd.altusmetrum.eeprom.icns \ ../icon/application-vnd.altusmetrum.telemetry.icns +LINUX_ICONS =\ + $(ICONDIR)/altusmetrum-altosui.svg \ + $(ICONDIR)/application-vnd.altusmetrum.eeprom.svg \ + $(ICONDIR)/application-vnd.altusmetrum.telemetry.svg + +LINUX_MIMETYPE =\ + $(ICONDIR)/org-altusmetrum-mimetypes.xml + # Firmware FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx FIRMWARE_TD=$(FIRMWARE_TD_0_2) @@ -131,7 +139,7 @@ DOC=$(TELEGPS_DOC) FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) -LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in ../icon/altusmetrum-telegps.svg +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE) LINUX_EXTRA=telegps-fat $(desktop_file).in MACOSX_INFO_PLIST=Info.plist -- cgit v1.2.3 From 165b7dcf6fba90b15ff32b891cba4b9111c1965b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 16 Jul 2014 17:13:25 -0700 Subject: altoslib: Handle TeleGPS files for KML export TeleGPS files had state values that couldn't be converted to colors, which resulted in a truncated file that wasn't much use for anything. Signed-off-by: Keith Packard --- altoslib/AltosKML.java | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index e31ddfba..e701fda3 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -28,18 +28,25 @@ public class AltosKML implements AltosWriter { double gps_start_altitude; static final String[] kml_state_colors = { - "FF000000", - "FF000000", - "FF000000", - "FF0000FF", - "FF4080FF", - "FF00FFFF", - "FFFF0000", - "FF00FF00", - "FF000000", - "FFFFFFFF" + "FF000000", // startup + "FF000000", // idle + "FF000000", // pad + "FF0000FF", // boost + "FF4080FF", // fast + "FF00FFFF", // coast + "FFFF0000", // drogue + "FF00FF00", // main + "FF000000", // landed + "FFFFFFFF", // invalid + "FFFF0000", // stateless }; + static String state_color(int state) { + if (state < 0 || kml_state_colors.length <= state) + return kml_state_colors[AltosLib.ao_flight_invalid]; + return kml_state_colors[state]; + } + static final String kml_header_start = "\n" + "\n" + @@ -95,7 +102,8 @@ public class AltosKML implements AltosWriter { void state_start(AltosState state) { String state_name = AltosLib.state_name(state.state); - out.printf(kml_style_start, state_name, kml_state_colors[state.state]); + String state_color = state_color(state.state); + out.printf(kml_style_start, state_name, state_color); out.printf("\tState: %s\n", state_name); out.printf("%s", kml_style_end); out.printf(kml_placemark_start, state_name, state_name); -- cgit v1.2.3