import android.os.Handler;
//import android.os.Message;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosBluetooth extends AltosDroidLink {
import java.io.*;
import java.lang.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.graphics.*;
import android.graphics.*;
import android.graphics.drawable.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
+
+class SavedState {
+ long received_time;
+ int state;
+ boolean locked;
+ String callsign;
+ int serial;
+ int flight;
+ int rssi;
+
+ SavedState(AltosState state) {
+ received_time = state.received_time;
+ this.state = state.state();
+ if (state.gps != null)
+ locked = state.gps.locked;
+ else
+ locked = false;
+ callsign = state.cal_data().callsign;
+ serial = state.cal_data().serial;
+ flight = state.cal_data().flight;
+ rssi = state.rssi;
+ }
+}
public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
public Location location = null;
+ private AltosState state;
+ private SavedState saved_state;
+
// Tabs
TabHost mTabHost;
AltosViewPager mViewPager;
// Timer and Saved flight state for Age calculation
private Timer timer;
- AltosState saved_state;
+
TelemetryState telemetry_state;
Integer[] serials;
if (telemetry_state.states.containsKey(current_serial)) {
state = telemetry_state.states.get(current_serial);
- int age = state_age(state);
+ int age = state_age(state.received_time);
if (age < 20)
aged = false;
if (current_serial == selected_serial)
for (int serial : telemetry_state.states.keySet()) {
AltosState existing = telemetry_state.states.get(serial);
- int existing_age = state_age(existing);
+ int existing_age = state_age(existing.received_time);
if (newest_state == null || existing_age < newest_age) {
newest_state = existing;
state = newest_state;
}
- update_ui(telemetry_state, state);
+ update_ui(telemetry_state, state, telemetry_state.quiet);
start_timer();
}
blend_component(a, b, r, 24, 0xff));
}
- int state_age(AltosState state) {
- return (int) ((System.currentTimeMillis() - state.received_time + 500) / 1000);
+ int state_age(long received_time) {
+ return (int) ((System.currentTimeMillis() - received_time + 500) / 1000);
}
void set_screen_on(int age) {
void update_age() {
if (saved_state != null) {
- int age = state_age(saved_state);
+ int age = state_age(saved_state.received_time);
double age_scale = age / 100.0;
}
}
- void update_ui(TelemetryState telem_state, AltosState state) {
+ void update_ui(TelemetryState telem_state, AltosState state, boolean quiet) {
+
+ this.state = state;
int prev_state = AltosLib.ao_flight_invalid;
AltosGreatCircle from_receiver = null;
if (saved_state != null)
- prev_state = saved_state.state();
+ prev_state = saved_state.state;
if (state != null) {
- set_screen_on(state_age(state));
+ set_screen_on(state_age(state.received_time));
if (state.state() == AltosLib.ao_flight_stateless) {
boolean prev_locked = false;
if(state.gps != null)
locked = state.gps.locked;
- if (saved_state != null && saved_state.gps != null)
- prev_locked = saved_state.gps.locked;
+ if (saved_state != null)
+ prev_locked = saved_state.locked;
if (prev_locked != locked) {
String currentTab = mTabHost.getCurrentTabTag();
if (locked) {
state.gps.alt);
}
- if (saved_state == null || !same_string(saved_state.callsign, state.callsign)) {
- mCallsignView.setText(state.callsign);
+ if (saved_state == null || !same_string(saved_state.callsign, state.cal_data().callsign)) {
+ mCallsignView.setText(state.cal_data().callsign);
}
- if (saved_state == null || state.serial != saved_state.serial) {
- if (state.serial == AltosLib.MISSING)
+ if (saved_state == null || state.cal_data().serial != saved_state.serial) {
+ if (state.cal_data().serial == AltosLib.MISSING)
mSerialView.setText("");
else
- mSerialView.setText(String.format("%d", state.serial));
+ mSerialView.setText(String.format("%d", state.cal_data().serial));
}
- if (saved_state == null || state.flight != saved_state.flight) {
- if (state.flight == AltosLib.MISSING)
+ if (saved_state == null || state.cal_data().flight != saved_state.flight) {
+ if (state.cal_data().flight == AltosLib.MISSING)
mFlightView.setText("");
else
- mFlightView.setText(String.format("%d", state.flight));
+ mFlightView.setText(String.format("%d", state.cal_data().flight));
}
- if (saved_state == null || state.state() != saved_state.state()) {
+ if (saved_state == null || state.state() != saved_state.state) {
if (state.state() == AltosLib.ao_flight_stateless) {
mStateLayout.setVisibility(View.GONE);
} else {
else
mRSSIView.setText(String.format("%d", state.rssi));
}
+ saved_state = new SavedState(state);
}
for (AltosDroidTab mTab : mTabs)
mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
+ AltosDebug.debug("quiet %b\n", quiet);
if (mAltosVoice != null)
- mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem());
+ mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet);
- saved_state = state;
}
private void onTimerTick() {
// Display the Version
mVersion = (TextView) findViewById(R.id.version);
mVersion.setText("Version: " + BuildInfo.version +
- " Built: " + BuildInfo.builddate + " " + BuildInfo.buildtime + " " + BuildInfo.buildtz +
- " (" + BuildInfo.branch + "-" + BuildInfo.commitnum + "-" + BuildInfo.commithash + ")");
+ (AltosVersion.has_google_maps_api_key() ? " maps" : "") +
+ " Built: " + BuildInfo.builddate + " " + BuildInfo.buildtime + " " + BuildInfo.buildtz +
+ " (" + BuildInfo.branch + "-" + BuildInfo.commitnum + "-" + BuildInfo.commithash + ")");
mCallsignView = (TextView) findViewById(R.id.callsign_value);
mRSSIView = (TextView) findViewById(R.id.rssi_value);
location.getLatitude(),
location.getLongitude());
- update_ui(telemetry_state, saved_state);
+ update_ui(telemetry_state, state, true);
}
@Override
AltosDebug.debug("Location changed to %f,%f",
location.getLatitude(),
location.getLongitude());
- update_ui(telemetry_state, saved_state);
+ update_ui(telemetry_state, state, false);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
import android.os.Handler;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public abstract class AltosDroidLink extends AltosLink {
import java.util.*;
import java.io.*;
import android.location.Location;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public interface AltosDroidMapInterface {
public void onCreateView(AltosDroid altos_droid);
import java.text.*;
import android.content.Context;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosDroidPreferences extends AltosPreferences {
import android.os.Environment;
import android.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
public final static String NAME = "org.altusmetrum.AltosDroid";
}
public String getString(String key, String def) {
- return prefs.getString(key, def);
+ String ret;
+ ret = prefs.getString(key, def);
+// AltosDebug.debug("AltosDroidPreferencesBackend get string %s:\n", key);
+// if (ret == null)
+// AltosDebug.debug(" (null)\n");
+// else {
+// String[] lines = ret.split("\n");
+// for (String l : lines)
+// AltosDebug.debug(" %s\n", l);
+// }
+ return ret;
}
public byte[] getBytes(String key, byte[] def) {
}
public void putString(String key, String value) {
+// AltosDebug.debug("AltosDroidPreferencesBackend put string %s:\n", key);
+// String[] lines = value.split("\n");
+// for (String l : lines)
+// AltosDebug.debug(" %s\n", l);
editor.putString(key, value);
}
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.location.Location;
import android.app.Activity;
import android.graphics.Color;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.graphics.*;
break;
case AltosMapTile.forbidden:
message = "Too many requests, try later";
+ AltosDebug.debug("Forbidden map response %d\n", AltosMapStore.forbidden_response);
break;
}
if (message != null) {
if (t_state.gps != null) {
AltosLatLon latlon = new AltosLatLon(t_state.gps.lat, t_state.gps.lon);
rocket.set_position(latlon, t_state.received_time);
- if (state.serial == serial)
+ if (state.cal_data().serial == serial)
there = latlon;
}
if (state != null)
- rocket.set_active(state.serial == serial);
+ rocket.set_active(state.cal_data().serial == serial);
}
}
if (receiver != null) {
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import android.app.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUsb extends AltosDroidLink {
import android.speech.tts.TextToSpeech.OnInitListener;
import android.location.Location;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosVoice {
private Location last_receiver;
private long last_speak_time;
private int last_flight_tell = TELL_FLIGHT_NONE;
+ private boolean quiet = false;
private long now() {
return System.currentTimeMillis();
public synchronized void speak(String s) {
if (!tts_enabled) return;
last_speak_time = now();
- tts.speak(s, TextToSpeech.QUEUE_ADD, null);
+ if (!quiet)
+ tts.speak(s, TextToSpeech.QUEUE_ADD, null);
}
public synchronized long time_since_speak() {
if (state == null)
return false;
+ AltosDebug.debug("tell_pad lag %b ltm %d\n", last_apogee_good, last_tell_mode);
+
if (state.apogee_voltage != AltosLib.MISSING)
last_apogee_good = tell_gonogo("apogee",
state.apogee_voltage >= AltosLib.ao_igniter_good,
if (last_flight_tell == TELL_FLIGHT_HEIGHT) {
last_flight_tell = TELL_FLIGHT_TRACK;
if (from_receiver != null) {
- speak("bearing %s %d, elevation %d, range %s.",
+ speak("bearing %s %d, elevation %d, distance %s.",
from_receiver.bearing_words(
AltosGreatCircle.BEARING_VOICE),
(int) (from_receiver.bearing + 0.5),
(int) (from_receiver.elevation + 0.5),
- AltosConvert.distance.say(from_receiver.range));
+ AltosConvert.distance.say(from_receiver.distance));
return true;
}
}
if (direction == null)
direction = String.format("Bearing %d", (int) (from_receiver.bearing + 0.5));
- speak("%s, range %s.", direction,
+ speak("%s, distance %s.", direction,
AltosConvert.distance.say_units(from_receiver.distance));
return true;
public void tell(TelemetryState telem_state, AltosState state,
AltosGreatCircle from_receiver, Location receiver,
- AltosDroidTab tab) {
+ AltosDroidTab tab, boolean quiet) {
+
+ this.quiet = quiet;
boolean spoken = false;
int tell_serial = last_tell_serial;
if (state != null)
- tell_serial = state.serial;
+ tell_serial = state.cal_data().serial;
if (tell_serial != last_tell_serial)
reset_last();
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class IdleModeActivity extends Activity {
private EditText callsign;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class IgniterItem {
public String name;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class FrequencyItem {
public AltosFrequency frequency;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class MapTypeActivity extends Activity {
private Button hybrid;
import android.location.LocationListener;
import android.location.Criteria;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
/**
* This Activity appears as a dialog. It lists any paired devices and
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class SetupActivity extends Activity {
private Spinner select_rate;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.os.Bundle;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.graphics.*;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.os.Bundle;
}
main_lights.set(state.main_voltage >= AltosLib.ao_igniter_good, state.main_voltage == AltosLib.MISSING);
- int num_igniter = state.ignitor_voltage == null ? 0 : state.ignitor_voltage.length;
+ int num_igniter = state.igniter_voltage == null ? 0 : state.igniter_voltage.length;
for (int i = 0; i < 4; i++) {
- double voltage = i >= num_igniter ? AltosLib.MISSING : state.ignitor_voltage[i];
+ double voltage = i >= num_igniter ? AltosLib.MISSING : state.igniter_voltage[i];
if (voltage == AltosLib.MISSING) {
ignite_row[i].setVisibility(View.GONE);
} else {
ignite_lights[i].set(voltage >= AltosLib.ao_igniter_good, voltage == AltosLib.MISSING);
}
- if (state.flight != 0) {
+ if (state.cal_data().flight != 0) {
if (state.state() <= AltosLib.ao_flight_pad)
data_logging_view.setText("Ready to record");
else if (state.state() < AltosLib.ao_flight_landed)
} else {
data_logging_view.setText("Storage full");
}
- data_logging_lights.set(state.flight != 0, state.flight == AltosLib.MISSING);
+ data_logging_lights.set(state.cal_data().flight != 0, state.cal_data().flight == AltosLib.MISSING);
if (state.gps != null) {
int soln = state.gps.nsat;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.app.Activity;
import android.os.Bundle;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import java.util.concurrent.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class TelemetryReader extends Thread {
import android.widget.Toast;
import android.location.Criteria;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class TelemetryService extends Service implements AltosIdleMonitorListener {
private void telemetry(AltosTelemetry telem) {
AltosState state;
- if (telemetry_state.states.containsKey(telem.serial))
- state = telemetry_state.states.get(telem.serial).clone();
+ if (telemetry_state.states.containsKey(telem.serial()))
+ state = telemetry_state.states.get(telem.serial());
else
- state = new AltosState();
- telem.update_state(state);
- telemetry_state.states.put(telem.serial, state);
+ state = new AltosState(new AltosCalData());
+ telem.provide_data(state);
+ telemetry_state.states.put(telem.serial(), state);
+ telemetry_state.quiet = false;
if (state != null) {
- AltosPreferences.set_state(state);
+ AltosPreferences.set_state(state,telem.serial());
}
send_to_clients();
}
telemetry_state.latest_serial = AltosPreferences.latest_state();
+ telemetry_state.quiet = true;
+
AltosDebug.debug("latest serial %d\n", telemetry_state.latest_serial);
for (int serial : serials) {
AltosDebug.debug("recovered old state serial %d flight %d",
serial,
- saved_state.flight);
+ saved_state.cal_data().flight);
if (saved_state.gps != null)
AltosDebug.debug("\tposition %f,%f",
saved_state.gps.lat,
/* AltosIdleMonitorListener */
public void update(AltosState state, AltosListenerState listener_state) {
- telemetry_state.states.put(state.serial, state);
+ telemetry_state.states.put(state.cal_data().serial, state);
telemetry_state.receiver_battery = listener_state.battery;
send_to_clients();
}
package org.altusmetrum.AltosDroid;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import android.location.Location;
public class TelemetryState {
double frequency;
int telemetry_rate;
+ boolean quiet;
+
HashMap<Integer,AltosState> states;
int latest_serial;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosCRCException extends Exception {
public int rssi;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
boolean header_written;
boolean seen_boost;
int boost_tick;
- LinkedList<AltosState> 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;
+ boolean has_basic;
+ boolean has_battery;
+ boolean has_flight_state;
+ boolean has_advanced;
+ boolean has_gps;
+ boolean has_gps_sat;
+ boolean has_companion;
+
+ AltosFlightSeries series;
+ int[] indices;
static final int ALTOS_CSV_VERSION = 5;
out.printf("version,serial,flight,call,time,clock,rssi,lqi");
}
- void write_general(AltosState state) {
+ double time() {
+ return series.time(indices);
+ }
+
+ int rssi() {
+ return (int) series.value(AltosFlightSeries.rssi_name, indices);
+ }
+
+ int status() {
+ return (int) series.value(AltosFlightSeries.status_name, indices);
+ }
+
+ void write_general() {
+ double time = time();
out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d",
- ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign,
- (double) state.time_since_boost(), (double) state.tick / 100.0,
- state.rssi,
- state.status & 0x7f);
+ ALTOS_CSV_VERSION, series.cal_data().serial,
+ series.cal_data().flight, series.cal_data().callsign,
+ time, time,
+ rssi(), status() & 0x7f);
}
void write_flight_header() {
out.printf("state,state_name");
}
- void write_flight(AltosState state) {
- out.printf("%d,%8s", state.state(), state.state_name());
+ int state() {
+ return (int) series.value(AltosFlightSeries.state_name, indices);
+ }
+
+ void write_flight() {
+ int state = state();
+ out.printf("%d,%8s", state, AltosLib.state_name(state));
}
void write_basic_header() {
out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");
}
- void write_basic(AltosState state) {
+ double acceleration() { return series.value(AltosFlightSeries.accel_name, indices); }
+ double pressure() { return series.value(AltosFlightSeries.pressure_name, indices); }
+ double altitude() { return series.value(AltosFlightSeries.altitude_name, indices); }
+ double height() { return series.value(AltosFlightSeries.height_name, indices); }
+ double speed() { return series.value(AltosFlightSeries.speed_name, indices); }
+ double temperature() { return series.value(AltosFlightSeries.temperature_name, indices); }
+ double apogee_voltage() { return series.value(AltosFlightSeries.apogee_voltage_name, indices); }
+ double main_voltage() { return series.value(AltosFlightSeries.main_voltage_name, indices); }
+
+ void write_basic() {
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(),
- state.height(),
- state.speed(),
- state.speed(),
- state.temperature,
- state.apogee_voltage,
- state.main_voltage);
+ acceleration(),
+ pressure(),
+ altitude(),
+ height(),
+ speed(),
+ speed(),
+ temperature(),
+ apogee_voltage(),
+ main_voltage());
}
void write_battery_header() {
out.printf("battery_voltage");
}
- void write_battery(AltosState state) {
- out.printf("%5.2f", state.battery_voltage);
+ double battery_voltage() { return series.value(AltosFlightSeries.battery_voltage_name, indices); }
+
+ void write_battery() {
+ out.printf("%5.2f", battery_voltage());
}
void write_advanced_header() {
out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z");
}
- void write_advanced(AltosState state) {
+ double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); }
+ double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); }
+ double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); }
+
+ double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); }
+ double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); }
+ double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); }
+
+ double mag_along() { return series.value(AltosFlightSeries.mag_along_name, indices); }
+ double mag_across() { return series.value(AltosFlightSeries.mag_across_name, indices); }
+ double mag_through() { return series.value(AltosFlightSeries.mag_through_name, indices); }
+
+ void write_advanced() {
out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",
- state.accel_along(), state.accel_across(), state.accel_through(),
- state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(),
- state.mag_along(), state.mag_across(), state.mag_through());
+ accel_along(), accel_across(), accel_through(),
+ gyro_roll(), gyro_pitch(), gyro_yaw(),
+ mag_along(), mag_across(), mag_through());
}
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,pdop,hdop,vdop");
}
- void write_gps(AltosState state) {
- AltosGPS gps = state.gps;
- if (gps == null)
- gps = new AltosGPS();
+ void write_gps() {
+ AltosGPS gps = series.gps_before(series.time(indices));
+
+ AltosGreatCircle from_pad;
- AltosGreatCircle from_pad = state.from_pad;
- if (from_pad == null)
+ if (series.cal_data().gps_pad != null && gps != null)
+ from_pad = new AltosGreatCircle(series.cal_data().gps_pad, gps);
+ else
from_pad = new AltosGreatCircle();
+ if (gps == null)
+ gps = new AltosGPS();
+
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.minute,
gps.second,
from_pad.distance,
- state.range,
+ from_pad.range,
from_pad.bearing,
- state.elevation,
+ from_pad.elevation,
gps.pdop,
gps.hdop,
gps.vdop);
}
}
- void write_gps_sat(AltosState state) {
- AltosGPS gps = state.gps;
+ void write_gps_sat() {
+ AltosGPS gps = series.gps_before(series.time(indices));
for(int i = 1; i <= 32; i++) {
int c_n0 = 0;
if (gps != null && gps.cc_gps_sat != null) {
}
void write_companion_header() {
+/*
out.printf("companion_id,companion_time,companion_update,companion_channels");
for (int i = 0; i < 12; i++)
out.printf(",companion_%02d", i);
+*/
}
- void write_companion(AltosState state) {
+ void write_companion() {
+/*
AltosCompanion companion = state.companion;
int channels_written = 0;
}
for (; channels_written < 12; channels_written++)
out.printf(",0");
+*/
}
void write_header() {
out.printf ("\n");
}
- void write_one(AltosState state) {
- write_general(state);
+ void write_one() {
+ write_general();
if (has_flight_state) {
out.printf(",");
- write_flight(state);
+ write_flight();
}
if (has_basic) {
out.printf(",");
- write_basic(state);
+ write_basic();
}
if (has_battery) {
out.printf(",");
- write_battery(state);
+ write_battery();
}
if (has_advanced) {
out.printf(",");
- write_advanced(state);
+ write_advanced();
}
if (has_gps) {
out.printf(",");
- write_gps(state);
+ write_gps();
}
if (has_gps_sat) {
out.printf(",");
- write_gps_sat(state);
+ write_gps_sat();
}
if (has_companion) {
out.printf(",");
- write_companion(state);
+ write_companion();
}
out.printf ("\n");
}
- private void flush_pad() {
- while (!pad_states.isEmpty()) {
- write_one (pad_states.remove());
- }
- }
-
- private void write(AltosState state) {
- if (state.state() == AltosLib.ao_flight_startup)
+ private void write() {
+ if (state() == AltosLib.ao_flight_startup)
return;
if (!header_written) {
write_header();
header_written = true;
}
- if (!seen_boost) {
- if (state.state() >= AltosLib.ao_flight_boost) {
- seen_boost = true;
- boost_tick = state.tick;
- flush_pad();
- }
- }
- if (seen_boost)
- write_one(state);
- else
- pad_states.add(state);
+ write_one();
}
private PrintStream out() {
}
public void close() {
- if (!pad_states.isEmpty()) {
- boost_tick = pad_states.element().tick;
- flush_pad();
- }
out.close();
}
- public void write(AltosStateIterable states) {
- states.write_comments(out());
+ public void write(AltosFlightSeries series) {
+// series.write_comments(out());
+
+ this.series = series;
+
+ series.finish();
has_flight_state = false;
has_basic = 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.accel_across() != AltosLib.MISSING)
- 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;
+
+ if (series.has_series(AltosFlightSeries.state_name))
+ has_flight_state = true;
+ if (series.has_series(AltosFlightSeries.accel_name) || series.has_series(AltosFlightSeries.pressure_name))
+ has_basic = true;
+ if (series.has_series(AltosFlightSeries.battery_voltage_name))
+ has_battery = true;
+ if (series.has_series(AltosFlightSeries.accel_across_name))
+ has_advanced = true;
+
+ if (series.gps_series != null)
+ has_gps = true;
+ if (series.sats_in_view != null)
+ has_gps_sat = true;
+ /*
+ if (state.companion != null)
+ has_companion = true;
+ */
+
+ indices = series.indices();
+
+ for (;;) {
+ write();
+ if (!series.step_indices(indices))
+ break;
}
- for (AltosState state : states)
- write(state);
}
public AltosCSV(PrintStream in_out, File in_name) {
name = in_name;
out = in_out;
- pad_states = new LinkedList<AltosState>();
}
public AltosCSV(File in_name) throws FileNotFoundException {
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+/*
+ * Calibration and other data needed to construct 'real' values from various data
+ * sources.
+ */
+
+public class AltosCalData {
+ public int flight = AltosLib.MISSING;
+
+ public void set_flight(int flight) {
+ if (flight != AltosLib.MISSING)
+ this.flight = flight;
+ }
+
+ public String callsign = null;
+
+ public void set_callsign(String callsign) {
+ if (callsign != null)
+ this.callsign = callsign;
+ }
+
+ public String firmware_version = null;
+
+ public void set_firmware_version(String firmware_version) {
+ if (firmware_version != null)
+ this.firmware_version = firmware_version;
+ }
+
+ public String product = null;
+
+ public void set_product(String product) {
+ if (product != null)
+ this.product = product;
+ }
+
+ public int serial = AltosLib.MISSING;
+
+ public void set_serial(int serial) {
+ if (serial != AltosLib.MISSING)
+ this.serial = serial;
+ }
+
+ public int receiver_serial = AltosLib.MISSING;
+
+ public void set_receiver_serial(int receiver_serial) {
+ if (receiver_serial != AltosLib.MISSING)
+ this.receiver_serial = receiver_serial;
+ }
+
+ public int device_type = AltosLib.MISSING;
+
+ public void set_device_type(int device_type) {
+ if (device_type != AltosLib.MISSING) {
+ this.device_type = device_type;
+ if (product == null)
+ set_product(AltosLib.product_name(device_type));
+ }
+ }
+
+ public int config_major = AltosLib.MISSING;
+ public int config_minor = AltosLib.MISSING;
+ public int flight_log_max = AltosLib.MISSING;
+
+ public void set_config(int major, int minor, int log_max) {
+ if (major != AltosLib.MISSING)
+ config_major = major;
+ if (minor != AltosLib.MISSING)
+ config_minor = minor;
+ if (log_max != AltosLib.MISSING)
+ flight_log_max = log_max;
+ }
+
+ public double apogee_delay = AltosLib.MISSING;
+ public double main_deploy = AltosLib.MISSING;
+
+ public void set_flight_params(double apogee_delay, double main_deploy) {
+ if (apogee_delay != AltosLib.MISSING)
+ this.apogee_delay = apogee_delay;
+ if (main_deploy != AltosLib.MISSING)
+ this.main_deploy = main_deploy;
+ }
+
+ public double accel_plus_g = AltosLib.MISSING;
+ public double accel_minus_g = AltosLib.MISSING;
+ public double ground_accel = AltosLib.MISSING;
+
+ public void set_accel_plus_minus(double plus, double minus) {
+ if (plus != AltosLib.MISSING && minus != AltosLib.MISSING) {
+ if (plus == minus)
+ return;
+ accel_plus_g = plus;
+ accel_minus_g = minus;
+ }
+ }
+
+ public void set_ground_accel(double ground_accel) {
+ if (ground_accel != AltosLib.MISSING)
+ this.ground_accel = ground_accel;
+ }
+
+ /* Raw acceleration value */
+ public double accel = AltosLib.MISSING;
+
+ public void set_accel(double accel) {
+ this.accel = accel;
+ }
+
+ public boolean mma655x_inverted = false;
+
+ public void set_mma655x_inverted(boolean inverted) {
+ mma655x_inverted = inverted;
+ }
+
+ public int pad_orientation = AltosLib.MISSING;
+
+ public void set_pad_orientation(int orientation) {
+ if (orientation != AltosLib.MISSING)
+ pad_orientation = orientation;
+ }
+
+ /* Compute acceleration */
+ public double acceleration(double sensor) {
+ return AltosConvert.acceleration_from_sensor(sensor, accel_plus_g, accel_minus_g, ground_accel);
+ }
+
+ public AltosMs5607 ms5607 = null;
+
+ public void set_ms5607(AltosMs5607 ms5607) {
+ this.ms5607 = ms5607;
+ }
+
+ public double ground_pressure = AltosLib.MISSING;
+ public double ground_altitude = AltosLib.MISSING;
+
+ public void set_ground_pressure(double ground_pressure) {
+ if (ground_pressure != AltosLib.MISSING) {
+ this.ground_pressure = ground_pressure;
+ this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+ }
+ }
+
+ public void set_ground_altitude(double ground_altitude) {
+ if (ground_altitude != AltosLib.MISSING)
+ this.ground_altitude = ground_altitude;
+ }
+
+ /* Compute pressure */
+
+ public AltosPresTemp pressure_ms5607(int raw_pres, int raw_temp) {
+ if (ms5607 == null)
+ return new AltosPresTemp(AltosLib.MISSING, AltosLib.MISSING);
+ return ms5607.pres_temp(raw_pres, raw_temp);
+ }
+
+ public int tick = AltosLib.MISSING;
+ private int first_tick = AltosLib.MISSING;
+ private int prev_tick = AltosLib.MISSING;
+
+ public void set_tick(int tick) {
+ if (tick != AltosLib.MISSING) {
+ if (prev_tick != AltosLib.MISSING) {
+ while (tick < prev_tick - 1000) {
+ tick += 65536;
+ }
+ }
+ if (first_tick == AltosLib.MISSING)
+ first_tick = tick;
+ prev_tick = tick;
+ this.tick = tick;
+ }
+ }
+
+ /* Reset all values which change during flight
+ */
+ public void reset() {
+ state = AltosLib.MISSING;
+ tick = AltosLib.MISSING;
+ prev_tick = AltosLib.MISSING;
+ temp_gps = null;
+ prev_gps = null;
+ temp_gps_sat_tick = AltosLib.MISSING;
+ accel = AltosLib.MISSING;
+ }
+
+ public int boost_tick = AltosLib.MISSING;
+
+ public void set_boost_tick() {
+ boost_tick = tick;
+ }
+
+ public double ticks_per_sec = 100.0;
+
+ public void set_ticks_per_sec(double ticks_per_sec) {
+ this.ticks_per_sec = ticks_per_sec;
+ }
+
+ public double time() {
+ if (tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ if (boost_tick != AltosLib.MISSING)
+ return (tick - boost_tick) / ticks_per_sec;
+ if (first_tick != AltosLib.MISSING)
+ return (tick - first_tick) / ticks_per_sec;
+ return tick / ticks_per_sec;
+ }
+
+ public double boost_time() {
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return boost_tick / ticks_per_sec;
+ }
+
+ public int state = AltosLib.MISSING;
+
+ public void set_state(int state) {
+ if (state >= AltosLib.ao_flight_boost && boost_tick == AltosLib.MISSING)
+ set_boost_tick();
+ this.state = state;
+ }
+
+ public AltosGPS gps_pad = null;
+
+ public double gps_pad_altitude = AltosLib.MISSING;
+
+ public void set_gps(AltosGPS gps) {
+ if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null)
+ gps_pad = gps;
+ if (gps_pad_altitude == AltosLib.MISSING && gps.alt != AltosLib.MISSING)
+ gps_pad_altitude = gps.alt;
+ }
+
+ /*
+ * While receiving GPS data, we construct a temporary GPS state
+ * object and then deliver the result atomically to the listener
+ */
+ AltosGPS temp_gps = null;
+ AltosGPS prev_gps = null;
+ int temp_gps_sat_tick = AltosLib.MISSING;
+
+ public AltosGPS temp_gps() {
+ return temp_gps;
+ }
+
+ public void reset_temp_gps() {
+ if (temp_gps != null) {
+ if (temp_gps.locked && temp_gps.nsat >= 4)
+ set_gps(temp_gps);
+ prev_gps = temp_gps;
+ temp_gps = null;
+ }
+ }
+
+ public boolean gps_pending() {
+ return temp_gps != null;
+ }
+
+ public AltosGPS make_temp_gps(int tick, boolean sats) {
+ if (temp_gps == null) {
+ if (prev_gps != null)
+ temp_gps = prev_gps.clone();
+ else
+ temp_gps = new AltosGPS();
+ }
+ if (sats) {
+ if (tick != temp_gps_sat_tick)
+ temp_gps.cc_gps_sat = null;
+ temp_gps_sat_tick = tick;
+ }
+ return temp_gps;
+ }
+
+ public double accel_zero_along, accel_zero_across, accel_zero_through;
+
+ public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
+ if (zero_along != AltosLib.MISSING) {
+ accel_zero_along = zero_along;
+ accel_zero_across = zero_across;
+ accel_zero_through = zero_through;
+ }
+ }
+
+ public double accel_along(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_along);
+ }
+
+ public double accel_across(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_across);
+ }
+
+ public double accel_through(double counts) {
+ return AltosIMU.convert_accel(counts - accel_zero_through);
+ }
+
+ public double gyro_zero_roll, gyro_zero_pitch, gyro_zero_yaw;
+
+ public void set_gyro_zero(double roll, double pitch, double yaw) {
+ if (roll != AltosLib.MISSING) {
+ gyro_zero_roll = roll;
+ gyro_zero_pitch = pitch;
+ gyro_zero_yaw = yaw;
+ imu_wrap_checked = false;
+ }
+ }
+
+ public double gyro_roll(double counts) {
+ if (gyro_zero_roll == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_roll);
+ }
+
+ public double gyro_pitch(double counts) {
+ if (gyro_zero_pitch == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_pitch);
+ }
+
+ public double gyro_yaw(double counts) {
+ if (gyro_zero_yaw == AltosLib.MISSING || counts == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_yaw);
+ }
+
+ private double gyro_zero_overflow(double first) {
+ double v = first / 128.0;
+ if (v < 0)
+ v = Math.ceil(v);
+ else
+ v = Math.floor(v);
+ if (v != 0)
+ System.out.printf("Adjusting gyro axis by %g steps\n", v);
+ return v * 128.0;
+ }
+
+ /* Initial TeleMega log format had only 16 bits for gyro cal, so the top 9 bits got lost as the
+ * cal data are scaled by 512. Use the first sample to adjust the cal value, assuming that it is
+ * from a time of fairly low rotation speed. Fixed in later TeleMega firmware by storing 32 bits
+ * of cal values.
+ */
+ private boolean imu_wrap_checked = false;
+
+ public void check_imu_wrap(double roll, double pitch, double yaw) {
+ if (!imu_wrap_checked) {
+ gyro_zero_roll += gyro_zero_overflow(roll);
+ gyro_zero_pitch += gyro_zero_overflow(pitch);
+ gyro_zero_yaw += gyro_zero_overflow(yaw);
+ imu_wrap_checked = true;
+ }
+ }
+
+ public double mag_along(double along) {
+ if (along == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(along);
+ }
+
+ public double mag_across(double across) {
+ if (across == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(across);
+ }
+
+ public double mag_through(double through) {
+ if (through == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return AltosMag.convert_gauss(through);
+ }
+
+ public AltosCalData() {
+ }
+
+ public AltosCalData(AltosConfigData config_data) {
+ set_serial(config_data.serial);
+ set_ticks_per_sec(100.0);
+ set_flight(config_data.flight);
+ set_callsign(config_data.callsign);
+ set_config(config_data.config_major, config_data.config_minor, config_data.flight_log_max);
+ set_firmware_version(config_data.version);
+ set_flight_params(config_data.apogee_delay / ticks_per_sec, config_data.apogee_lockout / ticks_per_sec);
+ set_pad_orientation(config_data.pad_orientation);
+ set_product(config_data.product);
+ set_accel_plus_minus(config_data.accel_cal_plus, config_data.accel_cal_minus);
+ set_accel_zero(config_data.accel_zero_along, config_data.accel_zero_across, config_data.accel_zero_through);
+ set_ms5607(config_data.ms5607);
+ try {
+ set_mma655x_inverted(config_data.mma655x_inverted());
+ } catch (AltosUnknownProduct up) {
+ }
+ set_pad_orientation(config_data.pad_orientation);
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-public class AltosConfigData implements Iterable<String> {
+public class AltosConfigData {
/* Version information */
public String manufacturer;
public int log_space;
public String version;
public int altitude_32;
-
- /* Strings returned */
- public LinkedList<String> __lines;
+ public int config_major, config_minor;
/* Config information */
/* HAS_FLIGHT*/
public int accel_zero_along, accel_zero_across, accel_zero_through;
/* ms5607 data */
- public int ms5607_reserved;
- public int ms5607_sens;
- public int ms5607_off;
- public int ms5607_tcs;
- public int ms5607_tco;
- public int ms5607_tref;
- public int ms5607_tempsens;
- public int ms5607_crc;
+ AltosMs5607 ms5607;
+
+ public AltosMs5607 ms5607() {
+ if (ms5607 == null)
+ ms5607 = new AltosMs5607();
+ return ms5607;
+ }
public static String get_string(String line, String label) throws ParseException {
if (line.startsWith(label)) {
throw new ParseException("mismatch", 0);
}
- public Iterator<String> iterator() {
- return __lines.iterator();
- }
-
public int log_space() {
- if (log_space > 0)
+ if (log_space != AltosLib.MISSING)
return log_space;
- if (storage_size > 0) {
+ if (storage_size != AltosLib.MISSING) {
int space = storage_size;
- if (storage_erase_unit > 0 && use_flash_for_config())
+ if (storage_erase_unit != AltosLib.MISSING && use_flash_for_config())
space -= storage_erase_unit;
- if (space > 0)
+ if (space != AltosLib.MISSING)
return space;
}
return 0;
return r;
}
+ public boolean altitude_32() {
+ return altitude_32 == 1;
+ }
+
public int compare_version(String other) {
int[] me = parse_version(version);
int[] them = parse_version(other);
}
public void reset() {
- __lines = new LinkedList<String>();
-
manufacturer = null;
product = null;
serial = AltosLib.MISSING;
log_format = AltosLib.AO_LOG_FORMAT_UNKNOWN;
log_space = AltosLib.MISSING;
version = "unknown";
+ config_major = AltosLib.MISSING;
+ config_minor = AltosLib.MISSING;
main_deploy = AltosLib.MISSING;
apogee_delay = AltosLib.MISSING;
aes_key = null;
- pyro = 0;
- npyro = 0;
+ pyro = AltosLib.MISSING;
+ npyro = AltosLib.MISSING;
pyros = null;
pyro_firing_time = AltosLib.MISSING;
}
public void parse_line(String line) {
- __lines.add(line);
+
/* Version replies */
try { manufacturer = get_string(line, "manufacturer"); } catch (Exception e) {}
try { product = get_string(line, "product"); } catch (Exception e) {}
/* Version also contains MS5607 info, which we ignore here */
- try { ms5607_reserved = get_int(line, "ms5607 reserved:"); } catch (Exception e) {}
- try { ms5607_sens = get_int(line, "ms5607 sens:"); } catch (Exception e) {}
- try { ms5607_off = get_int(line, "ms5607 off:"); } catch (Exception e) {}
- try { ms5607_tcs = get_int(line, "ms5607 tcs:"); } catch (Exception e) {}
- try { ms5607_tco = get_int(line, "ms5607 tco:"); } catch (Exception e) {}
- try { ms5607_tref = get_int(line, "ms5607 tref:"); } catch (Exception e) {}
- try { ms5607_tempsens = get_int(line, "ms5607 tempsens:"); } catch (Exception e) {}
- try { ms5607_crc = get_int(line, "ms5607 crc:"); } catch (Exception e) {}
+ try { ms5607().reserved = get_int(line, "ms5607 reserved:"); } catch (Exception e) {}
+ try { ms5607().sens = get_int(line, "ms5607 sens:"); } catch (Exception e) {}
+ try { ms5607().off = get_int(line, "ms5607 off:"); } catch (Exception e) {}
+ try { ms5607().tcs = get_int(line, "ms5607 tcs:"); } catch (Exception e) {}
+ try { ms5607().tco = get_int(line, "ms5607 tco:"); } catch (Exception e) {}
+ try { ms5607().tref = get_int(line, "ms5607 tref:"); } catch (Exception e) {}
+ try { ms5607().tempsens = get_int(line, "ms5607 tempsens:"); } catch (Exception e) {}
+ try { ms5607().crc = get_int(line, "ms5607 crc:"); } catch (Exception e) {}
/* Config show replies */
+ try {
+ if (line.startsWith("Config version")) {
+ String[] bits = line.split("\\s+");
+ if (bits.length >= 3) {
+ String[] cfg = bits[2].split("\\.");
+
+ if (cfg.length >= 2) {
+ config_major = Integer.parseInt(cfg[0]);
+ config_minor = Integer.parseInt(cfg[1]);
+ }
+ }
+ }
+ } catch (Exception e) {}
+
/* HAS_FLIGHT */
try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {}
try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {}
pyros = new AltosPyro[npyro];
pyro = 0;
} catch (Exception e) {}
- if (npyro > 0) {
+ if (npyro != AltosLib.MISSING) {
try {
AltosPyro p = new AltosPyro(pyro, line);
if (pyro < npyro)
}
public boolean has_frequency() {
- return radio_frequency >= 0 || radio_setting >= 0 || radio_channel >= 0;
+ return radio_frequency != AltosLib.MISSING || radio_setting != AltosLib.MISSING || radio_channel != AltosLib.MISSING;
}
public boolean has_telemetry_rate() {
- return telemetry_rate >= 0;
+ return telemetry_rate != AltosLib.MISSING;
}
public void set_frequency(double freq) {
int frequency = radio_frequency;
int setting = radio_setting;
- if (frequency > 0) {
+ if (frequency != AltosLib.MISSING) {
radio_frequency = (int) Math.floor (freq * 1000 + 0.5);
- radio_channel = -1;
- } else if (setting > 0) {
- radio_setting =AltosConvert.radio_frequency_to_setting(freq,
- radio_calibration);
- radio_channel = -1;
+ radio_channel = AltosLib.MISSING;
+ } else if (setting != AltosLib.MISSING) {
+ radio_setting =AltosConvert.radio_frequency_to_setting(freq, radio_calibration);
+ radio_channel = AltosLib.MISSING;
} else {
radio_channel = AltosConvert.radio_frequency_to_channel(freq);
}
int channel = radio_channel;
int setting = radio_setting;
- if (radio_frequency < 0 && channel < 0 && setting < 0)
- return -1;
+ if (radio_frequency == AltosLib.MISSING && channel == AltosLib.MISSING && setting == AltosLib.MISSING)
+ return AltosLib.MISSING;
- if (channel < 0)
+ if (channel == AltosLib.MISSING)
channel = 0;
- if (setting < 0)
+ if (setting == AltosLib.MISSING)
setting = 0;
return AltosConvert.radio_to_frequency(radio_frequency,
public void get_values(AltosConfigValues source) throws AltosConfigDataException {
/* HAS_FLIGHT */
- if (main_deploy >= 0)
+ if (main_deploy != AltosLib.MISSING)
main_deploy = source.main_deploy();
- if (apogee_delay >= 0)
+ if (apogee_delay != AltosLib.MISSING)
apogee_delay = source.apogee_delay();
- if (apogee_lockout >= 0)
+ if (apogee_lockout != AltosLib.MISSING)
apogee_lockout = source.apogee_lockout();
/* HAS_RADIO */
if (has_frequency())
set_frequency(source.radio_frequency());
- if (radio_enable >= 0)
+ if (radio_enable != AltosLib.MISSING)
radio_enable = source.radio_enable();
if (callsign != null)
callsign = source.callsign();
- if (telemetry_rate >= 0)
+ if (telemetry_rate != AltosLib.MISSING)
telemetry_rate = source.telemetry_rate();
/* HAS_ACCEL */
- if (pad_orientation >= 0)
+ if (pad_orientation != AltosLib.MISSING)
pad_orientation = source.pad_orientation();
/* HAS_LOG */
- if (flight_log_max >= 0)
+ if (flight_log_max != AltosLib.MISSING)
flight_log_max = source.flight_log_max();
/* HAS_IGNITE */
- if (ignite_mode >= 0)
+ if (ignite_mode != AltosLib.MISSING)
ignite_mode = source.ignite_mode();
/* AO_PYRO_NUM */
- if (npyro > 0)
+ if (npyro != AltosLib.MISSING)
pyros = source.pyros();
- if (pyro_firing_time >= 0)
+ if (pyro_firing_time != AltosLib.MISSING)
pyro_firing_time = source.pyro_firing_time();
/* HAS_APRS */
- if (aprs_interval >= 0)
+ if (aprs_interval != AltosLib.MISSING)
aprs_interval = source.aprs_interval();
- if (aprs_ssid >= 0)
+ if (aprs_ssid != AltosLib.MISSING)
aprs_ssid = source.aprs_ssid();
- if (aprs_format >= 0)
+ if (aprs_format != AltosLib.MISSING)
aprs_format = source.aprs_format();
/* HAS_BEEP */
- if (beep >= 0)
+ if (beep != AltosLib.MISSING)
beep = source.beep();
/* HAS_TRACKER */
- if (tracker_motion >= 0)
+ if (tracker_motion != AltosLib.MISSING)
tracker_motion = source.tracker_motion();
- if (tracker_interval >= 0)
+ if (tracker_interval != AltosLib.MISSING)
tracker_interval = source.tracker_interval();
}
if (log_space() == 0)
max_enabled = false;
- if (log_fixed > 0)
+ if (log_fixed != AltosLib.MISSING)
max_enabled = false;
switch (log_format) {
max_enabled = false;
break;
default:
- if (stored_flight > 0)
+ if (stored_flight != AltosLib.MISSING)
max_enabled = false;
break;
}
dest.set_ignite_mode(ignite_mode);
dest.set_pad_orientation(pad_orientation);
dest.set_callsign(callsign);
- if (npyro > 0)
+ if (npyro != AltosLib.MISSING)
dest.set_pyros(pyros);
else
dest.set_pyros(null);
public void save(AltosLink link, boolean remote) throws InterruptedException, TimeoutException {
/* HAS_FLIGHT */
- if (main_deploy >= 0)
+ if (main_deploy != AltosLib.MISSING)
link.printf("c m %d\n", main_deploy);
- if (apogee_delay >= 0)
+ if (apogee_delay != AltosLib.MISSING)
link.printf("c d %d\n", apogee_delay);
- if (apogee_lockout >= 0)
+ if (apogee_lockout != AltosLib.MISSING)
link.printf("c L %d\n", apogee_lockout);
/* HAS_RADIO */
if (has_frequency()) {
- boolean has_frequency = radio_frequency >= 0;
- boolean has_setting = radio_setting > 0;
+ boolean has_frequency = radio_frequency != AltosLib.MISSING;
+ boolean has_setting = radio_setting != AltosLib.MISSING;
double frequency = frequency();
link.set_radio_frequency(frequency,
has_frequency,
}
}
- if (telemetry_rate >= 0) {
+ if (telemetry_rate != AltosLib.MISSING) {
link.printf("c T %d\n", telemetry_rate);
if (remote) {
link.flush_output();
}
}
- if (radio_enable >= 0)
+ if (radio_enable != AltosLib.MISSING)
link.printf("c e %d\n", radio_enable);
/* HAS_ACCEL */
/* UI doesn't support accel cal */
- if (pad_orientation >= 0)
+ if (pad_orientation != AltosLib.MISSING)
link.printf("c o %d\n", pad_orientation);
/* HAS_LOG */
link.printf("c l %d\n", flight_log_max);
/* HAS_IGNITE */
- if (ignite_mode >= 0)
+ if (ignite_mode != AltosLib.MISSING)
link.printf("c i %d\n", ignite_mode);
/* HAS_AES */
/* UI doesn't support AES key config */
/* AO_PYRO_NUM */
- if (npyro > 0) {
+ if (npyro != AltosLib.MISSING) {
for (int p = 0; p < pyros.length; p++) {
link.printf("c P %s\n",
pyros[p].toString());
}
}
- if (pyro_firing_time >= 0)
+ if (pyro_firing_time != AltosLib.MISSING)
link.printf("c I %d\n", (int) (pyro_firing_time * 100.0 + 0.5));
/* HAS_APRS */
- if (aprs_interval >= 0)
+ if (aprs_interval != AltosLib.MISSING)
link.printf("c A %d\n", aprs_interval);
- if (aprs_ssid >= 0)
+ if (aprs_ssid != AltosLib.MISSING)
link.printf("c S %d\n", aprs_ssid);
- if (aprs_format >= 0)
+ if (aprs_format != AltosLib.MISSING)
link.printf("c C %d\n", aprs_format);
/* HAS_BEEP */
- if (beep >= 0)
+ if (beep != AltosLib.MISSING)
link.printf("c b %d\n", beep);
/* HAS_TRACKER */
- if (tracker_motion >= 0 && tracker_interval >= 0)
+ if (tracker_motion != AltosLib.MISSING && tracker_interval != AltosLib.MISSING)
link.printf("c t %d %d\n", tracker_motion, tracker_interval);
/* HAS_GYRO */
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosConfigDataException extends Exception {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosConfigValues {
/* set and get all of the dialog values */
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
public class AltosConvert {
+
+ public static final double gravity = 9.80665;
+
/*
* Pressure Sensor Model, version 1.1
*
* in Joules/(kilogram-Kelvin).
*/
- public static final double GRAVITATIONAL_ACCELERATION = -9.80665;
- public static final double AIR_GAS_CONSTANT = 287.053;
- public static final double NUMBER_OF_LAYERS = 7;
- public static final double MAXIMUM_ALTITUDE = 84852.0;
- public static final double MINIMUM_PRESSURE = 0.3734;
- public static final double LAYER0_BASE_TEMPERATURE = 288.15;
- public static final double LAYER0_BASE_PRESSURE = 101325;
+ private static final double GRAVITATIONAL_ACCELERATION = -gravity;
+ private static final double AIR_GAS_CONSTANT = 287.053;
+ private static final double NUMBER_OF_LAYERS = 7;
+ private static final double MAXIMUM_ALTITUDE = 84852.0;
+ private static final double MINIMUM_PRESSURE = 0.3734;
+ private static final double LAYER0_BASE_TEMPERATURE = 288.15;
+ private static final double LAYER0_BASE_PRESSURE = 101325;
/* lapse rate and base altitude for each layer in the atmosphere */
- public static final double[] lapse_rate = {
+ private static final double[] lapse_rate = {
-0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
};
- public static final int[] base_altitude = {
+ private static final int[] base_altitude = {
0, 11000, 20000, 32000, 47000, 51000, 71000
};
return altitude;
}
+ public static double degrees_to_radians(double degrees) {
+ if (degrees == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return degrees * (Math.PI / 180.0);
+ }
+
+ public static double radians_to_degrees(double radians) {
+ if (radians == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return radians * (180.0 / Math.PI);
+ }
+
public static double
cc_battery_to_voltage(double battery)
{
}
public static double
- cc_ignitor_to_voltage(double ignite)
+ cc_igniter_to_voltage(double ignite)
{
return ignite / 32767 * 15.0;
}
return 3.3 * mega_adc(raw) * (5.1 + 10.0) / 10.0;
}
- static double easy_mini_voltage(int sensor, int serial) {
+ static double easy_mini_2_adc(int raw) {
+ return raw / 4095.0;
+ }
+
+ static double easy_mini_1_adc(int raw) {
+ return raw / 32767.0;
+ }
+
+ static double easy_mini_1_voltage(int sensor, int serial) {
double supply = 3.3;
double diode_offset = 0.0;
if (serial < 1665)
diode_offset = 0.150;
- return sensor / 32767.0 * supply * 127/27 + diode_offset;
+ return easy_mini_1_adc(sensor) * supply * 127/27 + diode_offset;
+ }
+
+ static double easy_mini_2_voltage(int sensor) {
+ double supply = 3.3;
+
+ return easy_mini_2_adc(sensor) * supply * 127/27;
}
public static double radio_to_frequency(int freq, int setting, int cal, int channel) {
return 434.550 + channel * 0.100;
}
+ public static int telem_to_rssi(int telem) {
+ return telem / 2 - 74;
+ }
+
public static int[] ParseHex(String line) {
String[] tokens = line.split("\\s+");
int[] array = new int[tokens.length];
return lb / 0.22480894;
}
+ public static double acceleration_from_sensor(double sensor, double plus_g, double minus_g, double ground) {
+
+ if (sensor == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ if (plus_g == AltosLib.MISSING || minus_g == AltosLib.MISSING)
+ return AltosLib.MISSING;
+
+ if (ground == AltosLib.MISSING)
+ ground = plus_g;
+
+ double counts_per_g = (plus_g - minus_g) / 2.0;
+ double counts_per_mss = counts_per_g / gravity;
+
+ if (counts_per_mss == 0)
+ return AltosLib.MISSING;
+
+ return (sensor - ground) / counts_per_mss;
+ }
+
public static boolean imperial_units = false;
public static AltosDistance distance = new AltosDistance();
public static AltosLongitude longitude = new AltosLongitude();
+ public static AltosRotationRate rotation_rate = new AltosRotationRate();
+
+ public static AltosStateName state_name = new AltosStateName();
+
+ public static AltosPyroName pyro_name = new AltosPyroName();
+
+ public static AltosUnits magnetic_field = null;
+
public static String show_gs(String format, double a) {
a = meters_to_g(a);
format = format.concat(" g");
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public abstract class AltosDataListener {
+
+ private AltosCalData cal_data = null;
+
+ public double time = AltosLib.MISSING;
+ public int state = AltosLib.MISSING;
+
+ public void set_tick(int tick) {
+ cal_data.set_tick(tick);
+ set_time(cal_data.time());
+ }
+
+ public AltosCalData cal_data() {
+ if (cal_data == null)
+ cal_data = new AltosCalData();
+ return cal_data;
+ }
+
+ public void set_time(double time) {
+ if (time != AltosLib.MISSING)
+ this.time = time;
+ }
+
+ public void set_serial(int serial) {
+ cal_data().set_serial(serial);
+ }
+
+ public double time() {
+ return time;
+ }
+
+ public void set_state(int state) {
+ cal_data().set_state(state);
+ if (state != AltosLib.MISSING)
+ this.state = state;
+ }
+
+ public void set_flight(int flight) {
+ cal_data().set_flight(flight);
+ }
+
+ /* Called after all records are captured */
+ public void finish() {
+ }
+
+ public abstract void set_rssi(int rssi, int status);
+ public abstract void set_received_time(long received_time);
+
+ public abstract void set_acceleration(double accel);
+ public abstract void set_pressure(double pa);
+ public abstract void set_thrust(double N);
+
+ public abstract void set_kalman(double height, double speed, double accel);
+
+ public abstract void set_temperature(double deg_c);
+ public abstract void set_battery_voltage(double volts);
+
+ public abstract void set_apogee_voltage(double volts);
+ public abstract void set_main_voltage(double volts);
+
+ public abstract void set_gps(AltosGPS gps);
+
+ public abstract void set_orient(double orient);
+ public abstract void set_gyro(double roll, double pitch, double yaw);
+ public abstract void set_accel_ground(double along, double across, double through);
+ public abstract void set_accel(double along, double across, double through);
+ public abstract void set_mag(double along, double across, double through);
+ public abstract void set_pyro_voltage(double volts);
+ public abstract void set_igniter_voltage(double[] voltage);
+ public abstract void set_pyro_fired(int pyro_mask);
+ public abstract void set_companion(AltosCompanion companion);
+
+ public AltosDataListener() {
+ }
+
+ public AltosDataListener(AltosCalData cal_data) {
+ this.cal_data = cal_data;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public interface AltosDataProvider {
+ public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct;
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosDistance extends AltosUnits {
}
};
- range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000),
+ range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(5280),
"mi", "miles") {
double value(double v) {
return AltosConvert.meters_to_miles(v);
/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
import java.util.*;
-import java.text.*;
+import java.io.*;
+
+public class AltosEeprom {
-public abstract class AltosEeprom implements AltosStateUpdate {
- public int cmd;
- public int tick;
- public int data8[];
- public boolean valid;
+ private AltosJson config;
+ ArrayList<Byte> data;
+ private AltosConfigData config_data;
- public int data8(int i) {
- return data8[i];
+ /*
+ * Public accessor APIs
+ */
+ public int data8(int offset) {
+ return ((int) data.get(offset)) & 0xff;
}
- public int data16(int i) {
- return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16;
+ public int data16(int offset) {
+ return data8(offset) | (data8(offset+1) << 8);
}
- public int data24(int i) {
- return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16);
+ public int data24(int offset) {
+ return (data8(offset) |
+ (data8(offset+1) << 8) |
+ (data8(offset+2) << 16));
}
- public int data32(int i) {
- return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24);
+ public int data32(int offset) {
+ return (data8(offset) |
+ (data8(offset+1) << 8) |
+ (data8(offset+2) << 16) |
+ (data8(offset+3) << 24));
}
- public boolean has_seconds() { return false; }
+ public int size() {
+ return data.size();
+ }
- public int seconds() { return 0; }
+ public AltosConfigData config_data() {
+ if (config_data == null) {
+ config_data = (AltosConfigData) config.make(AltosConfigData.class);
+ if (config_data == null)
+ config_data = new AltosConfigData();
- public final static int header_length = 4;
+ if (config_data.log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) {
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
+ if (config_data.product != null) {
+ if (config_data.product.startsWith("TeleMetrum"))
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
+ else if (config_data.product.startsWith("TeleMini"))
+ config_data.log_format = AltosLib.AO_LOG_FORMAT_TINY;
+ }
+ }
+ }
+ return config_data;
+ }
+
+ private void write_config(Writer w) throws IOException {
+ config.write(w, 0, true);
+ w.append('\n');
+ }
+
+ /*
+ * Private I/O APIs
+ */
+ private void write_data(Writer w) throws IOException {
+ PrintWriter pw = new PrintWriter(w);
- public abstract int record_length();
+ for (int i = 0; i < data.size(); i++) {
+ if (i > 0) {
+ if ((i & 0x1f) == 0)
+ pw.printf("\n");
+ else
+ pw.printf(" ");
+ }
+ pw.printf("%02x", data.get(i));
+ }
+ w.append('\n');
+ }
- public void update_state(AltosState state) {
- if (cmd == AltosLib.AO_LOG_FLIGHT)
- state.set_boost_tick(tick);
- else
- state.set_tick(tick);
+ private boolean read_config(InputStream stream) throws IOException {
+ config = AltosJson.fromInputStream(stream);
+ if (config == null)
+ return false;
+ return true;
}
- public void write(PrintStream out) {
- out.printf("%c %04x", cmd, tick);
- if (data8 != null) {
- for (int i = 0; i < data8.length; i++)
- out.printf (" %02x", data8[i]);
+ private String read_line(InputStream stream) throws IOException {
+ StringBuffer buffer = null;
+ int c;
+
+ for (;;) {
+ c = stream.read();
+ if (c == -1 && buffer == null)
+ return null;
+ if (buffer == null)
+ buffer = new StringBuffer();
+ if (c == -1 || c == '\n')
+ return buffer.toString();
+ buffer.append((char) c);
}
- out.printf ("\n");
}
- public String string() {
- String s;
+ private boolean read_data(InputStream stream) throws IOException {
+ String s;
+
+ data = new ArrayList<Byte>();
+ while ((s = read_line(stream)) != null) {
- s = String.format("%c %04x", cmd, tick);
- if (data8 != null) {
- for (int i = 0; i < data8.length; i++) {
- String d = String.format(" %02x", data8[i]);
- s = s.concat(d);
+ String[] tokens = s.split("\\s+");
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (tokens[i].length() > 0) {
+ try {
+ data.add((byte) AltosLib.fromhex(tokens[i]));
+ } catch (NumberFormatException e) {
+ throw new IOException(e.toString());
+ }
+ }
}
}
- s = s.concat("\n");
- return s;
+ return true;
}
- void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException {
- cmd = chunk.data(start);
+ private boolean read_old_config(InputStream stream) throws IOException {
+ AltosConfigData cfg = new AltosConfigData();
+ for (;;) {
+ boolean done = false;
- int data_length = record_length() - header_length;
+ /* The data starts with an upper case F character followed by a space */
+ stream.mark(2);
+ int first = stream.read();
+ if (first == 'F') {
+ int second = stream.read();
+ if (second == ' ')
+ done = true;
+ }
+ stream.reset();
+ if (done)
+ break;
- valid = !chunk.erased(start, record_length());
- if (valid) {
- if (AltosConvert.checksum(chunk.data, start, record_length()) != 0)
- throw new ParseException(String.format("invalid checksum at 0x%x",
- chunk.address + start), 0);
- } else {
- cmd = AltosLib.AO_LOG_INVALID;
+ String line = read_line(stream);
+ if (line == null)
+ return false;
+ cfg.parse_line(line);
}
+ config = new AltosJson(cfg);
+ return true;
+ }
- tick = chunk.data16(start+2);
+ private boolean read_old_data(InputStream stream) throws IOException {
+ String line;
- data8 = new int[data_length];
- for (int i = 0; i < data_length; i++)
- data8[i] = chunk.data(start + header_length + i);
- }
+ data = new ArrayList<Byte>();
+ while ((line = read_line(stream)) != null) {
+ String[] tokens = line.split("\\s+");
- void parse_string(String line) {
- valid = false;
- tick = 0;
- cmd = AltosLib.AO_LOG_INVALID;
+ /* Make sure there's at least a type and time */
+ if (tokens.length < 2)
+ break;
- int data_length = record_length() - header_length;
+ /* packet type */
+ if (tokens[0].length() != 1)
+ break;
+ int start = data.size();
- if (line == null)
- return;
- try {
- String[] tokens = line.split("\\s+");
+ if (config_data().log_format != AltosLib.AO_LOG_FORMAT_TINY) {
+ byte cmd = (byte) tokens[0].codePointAt(0);
+ data.add(cmd);
- if (tokens[0].length() == 1) {
- if (tokens.length == 2 + data_length) {
- cmd = tokens[0].codePointAt(0);
- tick = Integer.parseInt(tokens[1],16);
- valid = true;
- data8 = new int[data_length];
+ int time = AltosLib.fromhex(tokens[1]);
- for (int i = 0; i < data_length; i++)
- data8[i] = Integer.parseInt(tokens[2 + i],16);
+ data.add((byte) 0);
+ data.add((byte) (time & 0xff));
+ data.add((byte) (time >> 8));
+ }
+ if (tokens.length == 4) {
+ /* Handle ancient log files */
+ if (config_data().log_format == AltosLib.AO_LOG_FORMAT_TINY) {
+ /*
+ * Ancient TeleMini log files stored "extra" data to pretend
+ * that it was a TeleMetrum device. Throw that away and
+ * just save the actual log data.
+ */
+ int a = AltosLib.fromhex(tokens[2]);
+ int b = AltosLib.fromhex(tokens[3]);
+ if (a != 0)
+ b = 0x8000 | a;
+ data.add((byte) (b & 0xff));
+ data.add((byte) ((b >> 8)));
+ } else {
+ for (int i = 2; i < tokens.length; i++) {
+ int v = AltosLib.fromhex(tokens[i]);
+ data.add((byte) (v & 0xff));
+ data.add((byte) ((v >> 8)));
+ }
+ /* Re-compute the checksum byte */
+ data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
}
+ } else {
+ for (int i = 2; i < tokens.length; i++)
+ data.add((byte) AltosLib.fromhex(tokens[i]));
+ /* Re-compute the checksum byte */
+ data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
}
- } catch (NumberFormatException ne) {
}
+ return true;
+ }
+
+ private void read(InputStream stream) throws IOException {
+ BufferedInputStream bis = new BufferedInputStream(stream);
+
+ bis.mark(1);
+ int c = bis.read();
+ bis.reset();
+
+ if (c == '{') {
+ if (!read_config(bis))
+ throw new IOException("failed to read config");
+ if (!read_data(bis))
+ throw new IOException("failed to read data");
+ } else {
+ if (!read_old_config(bis))
+ throw new IOException("failed to read old config");
+ if (!read_old_data(bis))
+ throw new IOException("failed to read old data");
+ }
+ }
+
+ /*
+ * Public APIs for I/O
+ */
+ public void write(Writer w) throws IOException {
+ write_config(w);
+ write_data(w);
+ }
+
+ public String toString() {
+ try {
+ Writer w = new StringWriter();
+
+ write(w);
+ return w.toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void print() throws IOException {
+ System.out.printf("%s", toString());
+ }
+
+ /*
+ * Constructors
+ */
+ public AltosEeprom(InputStream stream) throws IOException {
+ read(stream);
+ }
+
+ public AltosEeprom(String s) throws IOException {
+ read(new AltosStringInputStream(s));
+ }
+
+ public AltosEeprom(AltosJson config, ArrayList<Byte> data) {
+ this.config = config;
+ this.data = data;
+ }
+
+ public AltosEeprom(AltosConfigData config_data, ArrayList<Byte> data) {
+ this.config = new AltosJson(config_data);
+ this.data = data;
+ }
+
+ public AltosEeprom() {
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
+class AltosEepromNameData extends AltosDataListener {
+ AltosGPS gps = null;
+
+ public void set_rssi(int rssi, int status) { }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { }
+ public void set_pressure(double pa) { }
+ public void set_thrust(double N) { }
+
+ public void set_temperature(double deg_c) { }
+ public void set_battery_voltage(double volts) { }
+
+ public void set_apogee_voltage(double volts) { }
+ public void set_main_voltage(double volts) { }
+
+ public void set_gps(AltosGPS gps) {
+ if (gps != null &&
+ gps.year != AltosLib.MISSING &&
+ gps.month != AltosLib.MISSING &&
+ gps.day != AltosLib.MISSING) {
+ this.gps = gps;
+ }
+ }
+
+ public boolean done() {
+ if (gps == null)
+ return false;
+ return true;
+ }
+
+ public void set_gyro(double roll, double pitch, double yaw) { }
+ public void set_accel_ground(double along, double across, double through) { }
+ public void set_accel(double along, double across, double through) { }
+ public void set_mag(double along, double across, double through) { }
+ public void set_pyro_voltage(double volts) { }
+ public void set_igniter_voltage(double[] voltage) { }
+ public void set_pyro_fired(int pyro_mask) { }
+ public void set_companion(AltosCompanion companion) { }
+ public void set_kalman(double height, double speed, double acceleration) { }
+ public void set_orient(double new_orient) { }
+
+ public AltosEepromNameData(AltosCalData cal_data) {
+ super(cal_data);
+ }
+}
+
public class AltosEepromDownload implements Runnable {
AltosLink link;
gps.day != AltosLib.MISSING;
}
- private AltosFile MakeFile(int serial, int flight, AltosState state) throws IOException {
+ private AltosFile MakeFile(int serial, int flight, AltosEepromNameData name_data) throws IOException {
AltosFile eeprom_name;
- if (has_gps_date(state)) {
- AltosGPS gps = state.gps;
+ if (name_data.gps != null) {
+ AltosGPS gps = name_data.gps;
eeprom_name = new AltosFile(gps.year, gps.month, gps.day,
serial, flight, "eeprom");
} else
}
/* Construct our internal representation of the eeprom data */
- AltosEepromNew eeprom = new AltosEepromNew(flights.config_data, data);
+ AltosEeprom eeprom = new AltosEeprom(flights.config_data, data);
/* Now see if we can't actually parse the resulting
* file to generate a better filename. Note that this
* doesn't need to work; we'll still save the data using
* a less accurate name.
*/
- AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom);
-
- AltosState state = new AltosState();
+ AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom);
+ AltosEepromNameData name_data = new AltosEepromNameData(set.cal_data());
- for (AltosState s : set) {
- state = s;
- if (state.gps != null)
+ for (AltosEepromRecord record : set.ordered) {
+ record.provide_data(name_data, set.cal_data());
+ if (name_data.done())
break;
}
- AltosFile f = MakeFile(flights.config_data.serial, log.flight, state);
+ AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data);
monitor.set_filename(f.toString());
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-public class AltosEepromFile extends AltosStateIterable {
+public class AltosEepromFile implements AltosRecordSet {
AltosEepromRecordSet set;
- public AltosConfigData config_data() {
- return set.eeprom.config_data();
- }
-
public void write_comments(PrintStream out) {
}
out.printf("%s\n", set.eeprom.toString());
}
- public AltosEepromFile(Reader input) throws IOException {
+ public AltosEepromFile(InputStream input) throws IOException {
set = new AltosEepromRecordSet(input);
}
- public Iterator<AltosState> iterator() {
- return set.iterator();
+ public AltosConfigData config_data() {
+ return set.config_data();
+ }
+
+ public AltosCalData cal_data() {
+ return set.cal_data();
+ }
+
+ public void capture_series(AltosDataListener series) {
+ set.capture_series(series);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosEepromMonitor {
+++ /dev/null
-/*
- * Copyright © 2017 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-package org.altusmetrum.altoslib_11;
-
-import java.util.*;
-import java.io.*;
-
-public class AltosEepromNew {
-
- private AltosJson config;
- ArrayList<Byte> data;
- private AltosConfigData config_data;
-
- /*
- * Public accessor APIs
- */
- public int data8(int offset) {
- return ((int) data.get(offset)) & 0xff;
- }
-
- public int data16(int offset) {
- return data8(offset) | (data8(offset+1) << 8);
- }
-
- public int data24(int offset) {
- return (data8(offset) |
- (data8(offset+1) << 8) |
- (data8(offset+2) << 16));
- }
-
- public int data32(int offset) {
- return (data8(offset) |
- (data8(offset+1) << 8) |
- (data8(offset+2) << 16) |
- (data8(offset+3) << 24));
- }
-
- public int size() {
- return data.size();
- }
-
- public AltosConfigData config_data() {
- if (config_data == null) {
- config_data = (AltosConfigData) config.make(AltosConfigData.class);
- if (config_data == null)
- config_data = new AltosConfigData();
-
- if (config_data.log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) {
- config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
- if (config_data.product != null) {
- if (config_data.product.startsWith("TeleMetrum"))
- config_data.log_format = AltosLib.AO_LOG_FORMAT_FULL;
- else if (config_data.product.startsWith("TeleMini"))
- config_data.log_format = AltosLib.AO_LOG_FORMAT_TINY;
- }
- }
- }
- return config_data;
- }
-
- public void reset_config_data() {
- config_data = null;
- }
-
- private void write_config(Writer w) throws IOException {
- config.write(w, 0, true);
- w.append('\n');
- }
-
- /*
- * Private I/O APIs
- */
- private void write_data(Writer w) throws IOException {
- PrintWriter pw = new PrintWriter(w);
-
- for (int i = 0; i < data.size(); i++) {
- if (i > 0) {
- if ((i & 0x1f) == 0)
- pw.printf("\n");
- else
- pw.printf(" ");
- }
- pw.printf("%02x", data.get(i));
- }
- w.append('\n');
- }
-
- private boolean read_config(Reader r) throws IOException {
- config = AltosJson.fromReader(r);
- if (config == null)
- return false;
- return true;
- }
-
- private boolean read_data(Reader r) throws IOException {
- BufferedReader br = new BufferedReader(r);
- String s;
-
- data = new ArrayList<Byte>();
- while ((s = br.readLine()) != null) {
-
- String[] tokens = s.split("\\s+");
-
- for (int i = 0; i < tokens.length; i++) {
- if (tokens[i].length() > 0) {
- try {
- data.add((byte) AltosLib.fromhex(tokens[i]));
- } catch (NumberFormatException e) {
- throw new IOException(e.toString());
- }
- }
- }
- }
- return true;
- }
-
- private boolean read_old_config(BufferedReader r) throws IOException {
- AltosConfigData cfg = new AltosConfigData();
- for (;;) {
- boolean done = false;
-
- /* The data starts with an upper case F character followed by a space */
- r.mark(2);
- int first = r.read();
- if (first == 'F') {
- int second = r.read();
- if (second == ' ')
- done = true;
- }
- r.reset();
- if (done)
- break;
-
- String line = r.readLine();
- if (line == null)
- return false;
- cfg.parse_line(line);
- }
- config = new AltosJson(cfg);
- return true;
- }
-
- private boolean read_old_data(BufferedReader r) throws IOException {
- String line;
-
- data = new ArrayList<Byte>();
- while ((line = r.readLine()) != null) {
- String[] tokens = line.split("\\s+");
-
- /* Make sure there's at least a type and time */
- if (tokens.length < 2)
- break;
-
- /* packet type */
- if (tokens[0].length() != 1)
- break;
- int start = data.size();
-
- if (config_data().log_format != AltosLib.AO_LOG_FORMAT_TINY) {
- data.add((byte) tokens[0].codePointAt(0));
-
- int time = AltosLib.fromhex(tokens[1]);
-
- data.add((byte) 0);
- data.add((byte) (time & 0xff));
- data.add((byte) (time >> 8));
- }
- if (tokens.length == 4) {
- /* Handle ancient log files */
- if (config_data().log_format == AltosLib.AO_LOG_FORMAT_TINY) {
- /*
- * Ancient TeleMini log files stored "extra" data to pretend
- * that it was a TeleMetrum device. Throw that away and
- * just save the actual log data.
- */
- int a = AltosLib.fromhex(tokens[2]);
- int b = AltosLib.fromhex(tokens[3]);
- if (a != 0)
- b = 0x8000 | a;
- data.add((byte) (b & 0xff));
- data.add((byte) ((b >> 8)));
- } else {
- for (int i = 2; i < tokens.length; i++) {
- int v = AltosLib.fromhex(tokens[i]);
- data.add((byte) (v & 0xff));
- data.add((byte) ((v >> 8)));
- }
- /* Re-compute the checksum byte */
- data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
- }
- } else {
- for (int i = 2; i < tokens.length; i++)
- data.add((byte) AltosLib.fromhex(tokens[i]));
- /* Re-compute the checksum byte */
- data.set(start + 1, (byte) (256 - AltosConvert.checksum(data, start, data.size() - start)));
- }
- }
- return true;
- }
-
- private void read(Reader r) throws IOException {
- BufferedReader br = new BufferedReader(r);
-
- br.mark(1);
- int c = br.read();
- br.reset();
-
- if (c == '{') {
- if (!read_config(br))
- throw new IOException("failed to read config");
- if (!read_data(br))
- throw new IOException("failed to read data");
- } else {
- if (!read_old_config(br))
- throw new IOException("failed to read old config");
- if (!read_old_data(br))
- throw new IOException("failed to read old data");
- }
- }
-
- /*
- * Public APIs for I/O
- */
- public void write(Writer w) throws IOException {
- write_config(w);
- write_data(w);
- }
-
- public String toString() {
- try {
- Writer w = new StringWriter();
-
- write(w);
- return w.toString();
- } catch (Exception e) {
- return null;
- }
- }
-
- public void print() throws IOException {
- System.out.printf("%s", toString());
- }
-
- /*
- * Constructors
- */
- public AltosEepromNew(Reader r) throws IOException {
- read(r);
- }
-
- public AltosEepromNew(String s) throws IOException {
- read(new StringReader(s));
- }
-
- public AltosEepromNew(AltosJson config, ArrayList<Byte> data) {
- this.config = config;
- this.data = data;
- }
-
- public AltosEepromNew(AltosConfigData config_data, ArrayList<Byte> data) {
- this.config = new AltosJson(config_data);
- this.data = data;
- }
-
- public AltosEepromNew() {
- }
-}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_11;
-
+package org.altusmetrum.altoslib_12;
public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord> {
- AltosEepromNew eeprom;
+ AltosEeprom eeprom;
int wide_tick;
return 1;
}
+ public AltosConfigData config_data() {
+ return eeprom.config_data();
+ }
+
public int compareTo(AltosEepromRecord o) {
int cmd_diff = cmdi() - o.cmdi();
if (cmd_diff != 0)
return cmd_diff;
- int tick_diff = tick() - o.tick();
+ int tick_diff = wide_tick - o.wide_tick;
if (tick_diff != 0)
return tick_diff;
return start - o.start;
}
- public void update_state(AltosState state) {
+ /* AltosDataProvider */
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_tick(tick());
if (cmd() == AltosLib.AO_LOG_FLIGHT)
- state.set_boost_tick(tick());
- else
- state.set_tick(tick());
+ cal_data.set_boost_tick();
+ listener.set_time(cal_data.time());
+
+ /* Flush any pending GPS changes */
+ if (!AltosLib.is_gps_cmd(cmd())) {
+ AltosGPS gps = cal_data.temp_gps();
+ if (gps != null) {
+ listener.set_gps(gps);
+ cal_data.reset_temp_gps();
+ }
+ }
}
public int next_start() {
int s = start + length;
- while (s + length < eeprom.data.size()) {
+ while (s + length <= eeprom.data.size()) {
if (valid(s))
return s;
s += length;
public abstract AltosEepromRecord next();
- public AltosEepromRecord(AltosEepromNew eeprom, int start, int length) {
+ public AltosEepromRecord(AltosEeprom eeprom, int start, int length) {
this.eeprom = eeprom;
this.start = start;
this.length = length;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
return AltosConvert.lb_to_n(v * 298 * 9.807);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(0.0);
- state.set_accel_g(0, -1);
+ cal_data.set_flight(flight());
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_pressure(adc_to_pa(pres()));
- state.set_accel(adc_to_n(thrust()));
+ listener.set_pressure(adc_to_pa(pres()));
+ listener.set_thrust(adc_to_n(thrust()));
break;
}
}
return new AltosEepromRecordFireTwo(eeprom, s);
}
- public AltosEepromRecordFireTwo(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordFireTwo(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordFireTwo(AltosEepromNew eeprom) {
+ public AltosEepromRecordFireTwo(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosEepromRecordFull extends AltosEepromRecord {
public static final int record_length = 8;
public static final int two_g_default = 16294 - 15758;
- public void update_state(AltosState state) {
- super.update_state(state);
- AltosGPS gps;
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd()) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
+ super.provide_data(listener, cal_data);
+ AltosGPS gps;
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_pad);
- state.set_ground_accel(data16(0));
- state.set_flight(data16(2));
- if (state.accel_plus_g == AltosLib.MISSING)
- state.set_accel_g(data16(0), data16(0) + two_g_default);
+ listener.set_state(AltosLib.ao_flight_pad);
+ cal_data.set_ground_accel(data16(0));
+ cal_data.set_flight(data16(2));
+ if (cal_data.accel_plus_g == AltosLib.MISSING)
+ cal_data.set_accel_plus_minus(data16(0), data16(0) + two_g_default);
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_accel(data16(0));
- state.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ listener.set_acceleration(cal_data.acceleration(data16(0)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
break;
case AltosLib.AO_LOG_PRESSURE:
- state.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(data16(2)));
break;
case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_temperature(AltosConvert.thermometer_to_temperature(data16(0)));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2)));
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(data16(0)));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2)));
break;
case AltosLib.AO_LOG_DEPLOY:
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(data16(0)));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(data16(2)));
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(data16(0)));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(data16(2)));
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(data16(0));
+ listener.set_state(data16(0));
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.hour = data8(0);
gps.minute = data8(1);
AltosLib.AO_GPS_NUM_SAT_SHIFT;
break;
case AltosLib.AO_LOG_GPS_LAT:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
int lat32 = data32(0);
gps.lat = (double) lat32 / 1e7;
break;
case AltosLib.AO_LOG_GPS_LON:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
int lon32 = data32(0);
gps.lon = (double) lon32 / 1e7;
break;
case AltosLib.AO_LOG_GPS_ALT:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.alt = data16(0);
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ gps = cal_data.make_temp_gps(tick(),true);
int svid = data16(0);
int c_n0 = data16(3);
gps.add_sat(svid, c_n0);
break;
case AltosLib.AO_LOG_GPS_DATE:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(),false);
gps.year = data8(0) + 2000;
gps.month = data8(1);
gps.day = data8(2);
return new AltosEepromRecordFull(eeprom, s);
}
- public AltosEepromRecordFull(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordFull(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordFull(AltosEepromNew eeprom) {
+ public AltosEepromRecordFull(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
return start - o.start;
}
- public void update_state(AltosState state) {
- super.update_state(state);
-
- AltosGPS gps;
-
- /* Flush any pending RecordGps changes */
- if (state.gps_pending) {
- switch (cmd()) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- if (state.flight == AltosLib.MISSING) {
- state.set_boost_tick(tick());
- state.set_flight(flight());
+ if (cal_data.flight == AltosLib.MISSING) {
+ cal_data.set_boost_tick();
+ cal_data.set_flight(flight());
}
/* no place to log start lat/lon yet */
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ AltosGPS gps = new AltosGPS();
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
if (eeprom.config_data().altitude_32 == 1)
if (gps.vdop < 0.8)
gps.vdop += 2.56;
}
+ listener.set_gps(gps);
break;
}
}
return new AltosEepromRecordGps(eeprom, s);
}
- public AltosEepromRecordGps(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordGps(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordGps(AltosEepromNew eeprom) {
+ public AltosEepromRecordGps(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosEepromRecordMega extends AltosEepromRecord {
public static final int record_length = 32;
private int gyro_y() { return data16(16); }
private int gyro_z() { return data16(18); }
private int mag_x() { return data16(20); }
- private int mag_y() { return data16(22); }
- private int mag_z() { return data16(24); }
+ private int mag_z() { return data16(22); }
+ private int mag_y() { return data16(24); }
private int accel() { return data16(26); }
/* AO_LOG_TEMP_VOLT elements */
private int svid(int n) { return data8(2 + n * 2); }
private int c_n(int n) { return data8(2 + n * 2 + 1); }
- public void update_state(AltosState state) {
- super.update_state(state);
- AltosGPS gps;
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd()) {
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
+ AltosGPS gps;
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_accel(ground_accel());
- state.set_ground_pressure(ground_pres());
- state.set_accel_ground(ground_accel_along(),
- ground_accel_across(),
- ground_accel_through());
- state.set_gyro_zero(ground_roll() / 512.0,
- ground_pitch() / 512.0,
- ground_yaw() / 512.0);
+ cal_data.set_flight(flight());
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
+ listener.set_accel_ground(ground_accel_along(),
+ ground_accel_across(),
+ ground_accel_through());
+ cal_data.set_gyro_zero(ground_roll() / 512.0,
+ ground_pitch() / 512.0,
+ ground_yaw() / 512.0);
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_ms5607(pres(), temp());
-
- AltosIMU imu = new AltosIMU(accel_y(), /* along */
- accel_x(), /* across */
- accel_z(), /* through */
- gyro_y(), /* roll */
- gyro_x(), /* pitch */
- gyro_z()); /* yaw */
+ AltosConfigData config_data = eeprom.config_data();
+ AltosPresTemp pt = config_data.ms5607().pres_temp(pres(), temp());;
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+
+ int accel_along = accel_y();
+ int accel_across = accel_x();
+ int accel_through = accel_z();
+ int gyro_roll = gyro_y();
+ int gyro_pitch = gyro_x();
+ int gyro_yaw = gyro_z();
+
+ int mag_along = mag_y();
+ int mag_across = mag_x();
+ int mag_through = mag_z();
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD)
- state.check_imu_wrap(imu);
+ cal_data.check_imu_wrap(gyro_roll, gyro_pitch, gyro_yaw);
+
+ listener.set_accel(cal_data.accel_along(accel_along),
+ cal_data.accel_across(accel_across),
+ cal_data.accel_through(accel_through));
+ listener.set_gyro(cal_data.gyro_roll(gyro_roll),
+ cal_data.gyro_pitch(gyro_pitch),
+ cal_data.gyro_yaw(gyro_yaw));
+
+ listener.set_mag(cal_data.mag_along(mag_along),
+ cal_data.mag_across(mag_across),
+ cal_data.mag_through(mag_through));
- state.set_imu(imu);
- state.set_mag(new AltosMag(mag_x(),
- mag_y(),
- mag_z()));
+ final double lsb_per_g = 1920.0/105.5;
- state.set_accel(accel());
+ double acceleration = AltosConvert.acceleration_from_sensor(
+ accel(),
+ cal_data.ground_accel,
+ cal_data.ground_accel + 2 * lsb_per_g,
+ cal_data.ground_accel);
+ listener.set_acceleration(acceleration);
break;
case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
- state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
int nsense = nsense();
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
double voltages[] = new double[nsense-2];
for (int i = 0; i < nsense-2; i++)
voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
- state.set_ignitor_voltage(voltages);
- state.set_pyro_fired(pyro());
+ listener.set_igniter_voltage(voltages);
+ listener.set_pyro_fired(pyro());
break;
case AltosLib.AO_LOG_GPS_TIME:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- if (state.altitude_32())
+ if (config_data().altitude_32())
gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16);
else
gps.alt = altitude_low();
gps.ground_speed = ground_speed() * 1.0e-2;
gps.course = course() * 2;
gps.climb_rate = climb_rate() * 1.0e-2;
- if (state.compare_version("1.4.9") >= 0) {
+ if (config_data().compare_version("1.4.9") >= 0) {
gps.pdop = pdop() / 10.0;
gps.hdop = hdop() / 10.0;
gps.vdop = vdop() / 10.0;
}
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ gps = cal_data.make_temp_gps(tick(), true);
int n = nsat();
if (n > max_sat)
return new AltosEepromRecordMega(eeprom, s);
}
- public AltosEepromRecordMega(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordMega(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
log_format = eeprom.config_data().log_format;
}
- public AltosEepromRecordMega(AltosEepromNew eeprom) {
+ public AltosEepromRecordMega(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosEepromRecordMetrum extends AltosEepromRecord {
public static final int record_length = 16;
public int svid(int n) { return data8(2 + n * 2); }
public int c_n(int n) { return data8(2 + n * 2 + 1); }
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
AltosGPS gps;
- /* Flush any pending GPS changes */
- if (state.gps_pending) {
- switch (cmd()) {
- case AltosLib.AO_LOG_GPS_POS:
- case AltosLib.AO_LOG_GPS_LAT:
- case AltosLib.AO_LOG_GPS_LON:
- case AltosLib.AO_LOG_GPS_ALT:
- case AltosLib.AO_LOG_GPS_SAT:
- case AltosLib.AO_LOG_GPS_DATE:
- break;
- default:
- state.set_temp_gps();
- break;
- }
- }
-
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_accel(ground_accel());
- state.set_ground_pressure(ground_pres());
+ cal_data.set_flight(flight());
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_ms5607(pres(), temp());
- state.set_accel(accel());
-
+ AltosPresTemp pt = eeprom.config_data().ms5607().pres_temp(pres(), temp());
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+ listener.set_acceleration(cal_data.acceleration(accel()));
break;
case AltosLib.AO_LOG_TEMP_VOLT:
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
-
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
-
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
break;
case AltosLib.AO_LOG_GPS_POS:
- gps = state.make_temp_gps(false);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.lat = latitude() / 1e7;
gps.lon = longitude() / 1e7;
- if (state.altitude_32())
+ if (config_data().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);
+ gps = cal_data.make_temp_gps(tick(), false);
gps.hour = hour();
gps.minute = minute();
gps.pdop = pdop() / 10.0;
break;
case AltosLib.AO_LOG_GPS_SAT:
- gps = state.make_temp_gps(true);
+ gps = cal_data.make_temp_gps(tick(), true);
int n = nsat();
for (int i = 0; i < n; i++)
return new AltosEepromRecordMetrum(eeprom, s);
}
- public AltosEepromRecordMetrum(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordMetrum(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordMetrum(AltosEepromNew eeprom) {
+ public AltosEepromRecordMetrum(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosEepromRecordMini extends AltosEepromRecord {
public static final int record_length = 16;
private double battery_voltage(int sensor) {
int log_format = log_format();
- if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI)
- return AltosConvert.easy_mini_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI1)
+ return AltosConvert.easy_mini_1_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI2)
+ return AltosConvert.easy_mini_2_voltage(sensor);
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
return AltosConvert.tele_mini_2_voltage(sensor);
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
private double pyro_voltage(int sensor) {
int log_format = log_format();
- if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI)
- return AltosConvert.easy_mini_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI1)
+ return AltosConvert.easy_mini_1_voltage(sensor, eeprom.config_data().serial);
+ if (log_format == AltosLib.AO_LOG_FORMAT_EASYMINI2)
+ return AltosConvert.easy_mini_2_voltage(sensor);
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI2)
return AltosConvert.tele_mini_2_voltage(sensor);
if (log_format == AltosLib.AO_LOG_FORMAT_TELEMINI3)
return -1;
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ super.provide_data(listener, cal_data);
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_flight(flight());
- state.set_ground_pressure(ground_pres());
+ cal_data.set_flight(flight());
+ cal_data.set_ground_pressure(ground_pres());
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(state());
+ listener.set_state(state());
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_ms5607(pres(), temp());
- state.set_apogee_voltage(pyro_voltage(sense_a()));
- state.set_main_voltage(pyro_voltage(sense_m()));
- state.set_battery_voltage(battery_voltage(v_batt()));
+ AltosPresTemp pt = eeprom.config_data().ms5607().pres_temp(pres(), temp());
+ listener.set_pressure(pt.pres);
+ listener.set_temperature(pt.temp);
+ listener.set_apogee_voltage(pyro_voltage(sense_a()));
+ listener.set_main_voltage(pyro_voltage(sense_m()));
+ listener.set_battery_voltage(battery_voltage(v_batt()));
break;
}
}
return new AltosEepromRecordMini(eeprom, s);
}
- public AltosEepromRecordMini(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordMini(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordMini(AltosEepromNew eeprom) {
+ public AltosEepromRecordMini(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
-public class AltosEepromRecordSet implements Iterable<AltosState> {
- AltosEepromNew eeprom;
+public class AltosEepromRecordSet implements AltosRecordSet {
+ AltosEeprom eeprom;
TreeSet<AltosEepromRecord> ordered;
- AltosState start_state;
+ AltosCalData cal_data;
- class RecordIterator implements Iterator<AltosState> {
- Iterator<AltosEepromRecord> riterator;
- AltosState state;
- boolean started;
-
- public boolean hasNext() {
- return state == null || riterator.hasNext();
- }
+ public AltosConfigData config_data() {
+ return eeprom.config_data();
+ }
- public AltosState next() {
- if (state == null)
- state = start_state.clone();
- else {
- state = state.clone();
- AltosEepromRecord r = riterator.next();
- r.update_state(state);
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ cal_data = new AltosCalData(config_data());
+ for (AltosEepromRecord record : ordered) {
+ if (record.cmd() == AltosLib.AO_LOG_FLIGHT) {
+ cal_data.set_tick(record.tick());
+ cal_data.set_boost_tick();
+ break;
+ }
}
- return state;
- }
-
- public RecordIterator() {
- riterator = ordered.iterator();
- state = null;
}
+ return cal_data;
}
- public Iterator<AltosState> iterator() {
- return new RecordIterator();
+ public void capture_series(AltosDataListener listener) {
+ AltosCalData cal_data = cal_data();
+
+ cal_data.reset();
+ for (AltosEepromRecord record : ordered) {
+ record.provide_data(listener, cal_data);
+ }
+ listener.finish();
}
- public AltosEepromRecordSet(AltosEepromNew eeprom) {
+ public AltosEepromRecordSet(AltosEeprom eeprom) {
this.eeprom = eeprom;
AltosConfigData config_data = eeprom.config_data();
break;
case AltosLib.AO_LOG_FORMAT_TELEMINI2:
case AltosLib.AO_LOG_FORMAT_TELEMINI3:
- case AltosLib.AO_LOG_FORMAT_EASYMINI:
+ case AltosLib.AO_LOG_FORMAT_EASYMINI1:
+ case AltosLib.AO_LOG_FORMAT_EASYMINI2:
record = new AltosEepromRecordMini(eeprom);
break;
case AltosLib.AO_LOG_FORMAT_TELEGPS:
int tick = 0;
boolean first = true;
- start_state = new AltosState();
- start_state.set_config_data(record.eeprom.config_data());
-
for (;;) {
int t = record.tick();
}
}
- public AltosEepromRecordSet(Reader input) throws IOException {
- this(new AltosEepromNew(input));
+ public AltosEepromRecordSet(InputStream input) throws IOException {
+ this(new AltosEeprom(input));
}
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-public class AltosEepromRecordTiny extends AltosEepromRecord {
+public class AltosEepromRecordTiny extends AltosEepromRecord implements AltosDataProvider {
public static final int record_length = 2;
private int value() {
return tick;
}
- public void update_state(AltosState state) {
+ public void provide_data(AltosDataListener listener) {
int value = data16(-header_length);
- state.set_tick(tick());
+ listener.set_tick(tick());
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
- state.set_state(AltosLib.ao_flight_pad);
- state.set_flight(value);
- state.set_boost_tick(0);
+ listener.set_state(AltosLib.ao_flight_pad);
+ listener.cal_data().set_flight(value);
+ listener.cal_data().set_boost_tick();
break;
case AltosLib.AO_LOG_STATE:
- state.set_state(value & 0x7fff);
+ listener.set_state(value & 0x7fff);
break;
case AltosLib.AO_LOG_SENSOR:
- state.set_pressure(AltosConvert.barometer_to_pressure(value));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(value));
break;
}
}
return new AltosEepromRecordTiny(eeprom, s);
}
- public AltosEepromRecordTiny(AltosEepromNew eeprom, int start) {
+ public AltosEepromRecordTiny(AltosEeprom eeprom, int start) {
super(eeprom, start, record_length);
}
- public AltosEepromRecordTiny(AltosEepromNew eeprom) {
+ public AltosEepromRecordTiny(AltosEeprom eeprom) {
this(eeprom, 0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.File;
import java.util.*;
extension);
}
- public AltosFile(AltosState state) {
- this(state.serial, state.flight, state.receiver_serial, "telem");
+ public AltosFile(AltosCalData cal_data) {
+ this(cal_data.serial, cal_data.flight, cal_data.receiver_serial, "telem");
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFlashListener {
public void position(String label, int percent);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
void reset();
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public abstract class AltosFlightListener {
+
+ public int flight;
+ public int serial;
+ public int tick;
+ public int boost_tick;
+ public int state;
+
+ public double accel_plus_g;
+ public double accel_minus_g;
+ public double accel;
+
+ public double ground_pressure;
+ public double ground_altitude;
+
+ AltosGPS temp_gps;
+ int temp_gps_sat_tick;
+ int gps_sequence;
+
+ /* AltosEepromRecord */
+ public void set_boost_tick(int boost_tick) {
+ if (boost_tick != AltosLib.MISSING)
+ this.boost_tick = boost_tick;
+ }
+
+ public void set_tick(int tick) {
+ if (tick != AltosLib.MISSING)
+ this.tick = tick;
+ }
+
+ public double time() {
+ if (tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ if (boost_tick != AltosLib.MISSING)
+ return (tick - boost_tick) / 100.0;
+ else
+ return tick / 100.0;
+ }
+
+ public double boost_time() {
+ if (boost_tick == AltosLib.MISSING)
+ return AltosLib.MISSING;
+ return boost_tick / 100.0;
+ }
+
+ public abstract void set_rssi(int rssi, int status);
+ public abstract void set_received_time(long received_time);
+
+ /* AltosEepromRecordFull */
+
+ public void set_serial(int serial) {
+ if (serial != AltosLib.MISSING)
+ this.serial = serial;
+ }
+
+ public void set_state(int state) {
+ if (state != AltosLib.MISSING)
+ this.state = state;
+ }
+
+ public int state() { return state; }
+
+ public abstract void set_ground_accel(double ground_accel);
+ public void set_flight(int flight) {
+ if (flight != AltosLib.MISSING)
+ this.flight = flight;
+ }
+ public int flight() {
+ return flight;
+ }
+
+ public abstract void set_accel(double accel);
+ public abstract void set_acceleration(double accel);
+ public abstract void set_accel_g(double accel_plus_g, double accel_minus_g);
+ public abstract void set_pressure(double pa);
+ public abstract void set_thrust(double N);
+
+ public abstract void set_temperature(double deg_c);
+ public abstract void set_battery_voltage(double volts);
+
+ public abstract void set_apogee_voltage(double volts);
+ public abstract void set_main_voltage(double volts);
+
+ public void set_temp_gps() {
+ temp_gps = null;
+ }
+
+ public boolean gps_pending() {
+ return temp_gps != null;
+ }
+
+ public AltosGPS make_temp_gps(boolean sats) {
+ if (temp_gps == null) {
+ temp_gps = new AltosGPS();
+ }
+ if (sats) {
+ if (tick != temp_gps_sat_tick)
+ temp_gps.cc_gps_sat = null;
+ temp_gps_sat_tick = tick;
+ }
+ return temp_gps;
+ }
+
+ public void set_ground_pressure(double ground_pressure) {
+ if (ground_pressure != AltosLib.MISSING) {
+ this.ground_pressure = ground_pressure;
+ this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+ }
+ }
+
+ public abstract void set_accel_ground(double along, double across, double through);
+ public abstract void set_gyro_zero(double roll, double pitch, double yaw);
+ public abstract void check_imu_wrap(AltosIMU imu);
+ public abstract void set_imu(AltosIMU imu);
+ public abstract void set_mag(AltosMag mag);
+ public abstract void set_pyro_voltage(double volts);
+ public abstract void set_igniter_voltage(double[] voltage);
+ public abstract void set_pyro_fired(int pyro_mask);
+
+ public void copy(AltosFlightListener old) {
+ flight = old.flight;
+ serial = old.serial;
+ tick = old.tick;
+ boost_tick = old.boost_tick;
+ accel_plus_g = old.accel_plus_g;
+ accel_minus_g = old.accel_minus_g;
+ ground_pressure = old.ground_pressure;
+ ground_altitude = old.ground_altitude;
+ temp_gps = old.temp_gps;
+ temp_gps_sat_tick = old.temp_gps_sat_tick;
+ }
+
+ public void init() {
+ flight = AltosLib.MISSING;
+ serial = AltosLib.MISSING;
+ tick = AltosLib.MISSING;
+ boost_tick = AltosLib.MISSING;
+ accel_plus_g = AltosLib.MISSING;
+ accel_minus_g = AltosLib.MISSING;
+ accel = AltosLib.MISSING;
+ ground_pressure = AltosLib.MISSING;
+ ground_altitude = AltosLib.MISSING;
+ temp_gps = null;
+ temp_gps_sat_tick = AltosLib.MISSING;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
public abstract AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException;
+ public abstract AltosCalData cal_data();
+
public abstract void close(boolean interrupted);
public void set_frequency(double frequency) throws InterruptedException, TimeoutException { }
public void save_telemetry_rate() { }
- public void update(AltosState state) throws InterruptedException { }
-
public boolean supports_telemetry(int telemetry) { return false; }
public boolean supports_telemetry_rate(int telemetry_rate) { return false; }
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public class AltosFlightSeries extends AltosDataListener {
+
+ public ArrayList<AltosTimeSeries> series = new ArrayList<AltosTimeSeries>();
+
+ public double speed_filter_width = 4.0;
+ public double accel_filter_width = 4.0;
+
+ public int[] indices() {
+ int[] indices = new int[series.size()];
+ for (int i = 0; i < indices.length; i++)
+ indices[i] = -1;
+ step_indices(indices);
+ return indices;
+ }
+
+ private double time(int id, int index) {
+ AltosTimeSeries s = series.get(id);
+
+ if (index < 0)
+ return Double.NEGATIVE_INFINITY;
+
+ if (index < s.values.size())
+ return s.values.get(index).time;
+ return Double.POSITIVE_INFINITY;
+ }
+
+ public boolean step_indices(int[] indices) {
+ double min_next = time(0, indices[0]+1);
+
+ for (int i = 1; i < indices.length; i++) {
+ double next = time(i, indices[i]+1);
+ if (next < min_next)
+ min_next = next;
+ }
+
+ if (min_next == Double.POSITIVE_INFINITY)
+ return false;
+
+ for (int i = 0; i < indices.length; i++) {
+ double t = time(i, indices[i] + 1);
+
+ if (t <= min_next)
+ indices[i]++;
+ }
+ return true;
+ }
+
+ public double time(int[] indices) {
+ double max = time(0, indices[0]);
+
+ for (int i = 1; i < indices.length; i++) {
+ double t = time(i, indices[i]);
+ if (t >= max)
+ max = t;
+ }
+ return max;
+ }
+
+ public double value(String name, int[] indices) {
+ for (int i = 0; i < indices.length; i++) {
+ AltosTimeSeries s = series.get(i);
+ if (s.label.equals(name)) {
+ int index = indices[i];
+ if (index < 0)
+ index = 0;
+ if (index >= s.values.size())
+ index = s.values.size() - 1;
+ return s.values.get(index).value;
+ }
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value_before(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value_before(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public double value_after(String name, double time) {
+ for (AltosTimeSeries s : series) {
+ if (s.label.equals(name))
+ return s.value_after(time);
+ }
+ return AltosLib.MISSING;
+ }
+
+ public AltosTimeSeries make_series(String label, AltosUnits units) {
+ return new AltosTimeSeries(label, units);
+ }
+
+ public void add_series(AltosTimeSeries s) {
+ for (int e = 0; e < series.size(); e++) {
+ if (s.compareTo(series.get(e)) < 0){
+ series.add(e, s);
+ return;
+ }
+ }
+ series.add(s);
+ }
+
+ public AltosTimeSeries add_series(String label, AltosUnits units) {
+ AltosTimeSeries s = make_series(label, units);
+ add_series(s);
+ return s;
+ }
+
+ public void remove_series(AltosTimeSeries s) {
+ series.remove(s);
+ }
+
+ public boolean has_series(String label) {
+ for (AltosTimeSeries s : series)
+ if (s.label.equals(label))
+ return true;
+ return false;
+ }
+
+ public AltosTimeSeries state_series;
+
+ public static final String state_name = "State";
+
+ public void set_state(int state) {
+
+ if (state == AltosLib.ao_flight_pad)
+ return;
+
+ if (state_series == null)
+ state_series = add_series(state_name, AltosConvert.state_name);
+ else if (this.state == state)
+ return;
+ this.state = state;
+ state_series.add(time(), state);
+ }
+
+ public AltosTimeSeries accel_series;
+
+ public static final String accel_name = "Accel";
+
+ public AltosTimeSeries vert_accel_series;
+
+ public static final String vert_accel_name = "Vertical Accel";
+
+ public void set_acceleration(double acceleration) {
+ if (acceleration == AltosLib.MISSING)
+ return;
+ if (accel_series == null)
+ accel_series = add_series(accel_name, AltosConvert.accel);
+
+ accel_series.add(time(), acceleration);
+ }
+
+ private void compute_accel() {
+ if (accel_series != null)
+ return;
+
+ if (speed_series != null) {
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+ speed_series.filter(temp_series, accel_filter_width);
+ accel_series = add_series(accel_name, AltosConvert.accel);
+ temp_series.differentiate(accel_series);
+ }
+ }
+
+ public void set_received_time(long received_time) {
+ }
+
+ public AltosTimeSeries rssi_series;
+
+ public static final String rssi_name = "RSSI";
+
+ public AltosTimeSeries status_series;
+
+ public static final String status_name = "Radio Status";
+
+ public void set_rssi(int rssi, int status) {
+ if (rssi_series == null) {
+ rssi_series = add_series(rssi_name, null);
+ status_series = add_series(status_name, null);
+ }
+ rssi_series.add(time(), rssi);
+ status_series.add(time(), status);
+ }
+
+ public AltosTimeSeries pressure_series;
+
+ public static final String pressure_name = "Pressure";
+
+ public AltosTimeSeries altitude_series;
+
+ public static final String altitude_name = "Altitude";
+
+ public AltosTimeSeries height_series;
+
+ public static final String height_name = "Height";
+
+ public void set_pressure(double pa) {
+ if (pa == AltosLib.MISSING)
+ return;
+
+ if (pressure_series == null)
+ pressure_series = add_series(pressure_name, AltosConvert.pressure);
+ pressure_series.add(time(), pa);
+ if (altitude_series == null)
+ altitude_series = add_series(altitude_name, AltosConvert.height);
+
+ if (cal_data().ground_pressure == AltosLib.MISSING)
+ cal_data().set_ground_pressure(pa);
+
+ double altitude = AltosConvert.pressure_to_altitude(pa);
+ altitude_series.add(time(), altitude);
+ }
+
+ private void compute_height() {
+ double ground_altitude = cal_data().ground_altitude;
+ if (height_series == null && ground_altitude != AltosLib.MISSING && altitude_series != null) {
+ height_series = add_series(height_name, AltosConvert.height);
+ for (AltosTimeValue alt : altitude_series)
+ height_series.add(alt.time, alt.value - ground_altitude);
+ }
+
+ if (gps_height == null && cal_data().gps_pad != null && cal_data().gps_pad.alt != AltosLib.MISSING && gps_altitude != null) {
+ double gps_ground_altitude = cal_data().gps_pad.alt;
+ gps_height = add_series(gps_height_name, AltosConvert.height);
+ for (AltosTimeValue gps_alt : gps_altitude)
+ gps_height.add(gps_alt.time, gps_alt.value - gps_ground_altitude);
+ }
+ }
+
+ public AltosTimeSeries speed_series;
+
+ public static final String speed_name = "Speed";
+
+ private void compute_speed() {
+ if (speed_series != null)
+ return;
+
+ AltosTimeSeries alt_speed_series = null;
+ AltosTimeSeries accel_speed_series = null;
+
+ if (altitude_series != null) {
+ AltosTimeSeries temp_series = make_series(altitude_name, AltosConvert.height);
+ altitude_series.filter(temp_series, speed_filter_width);
+
+ alt_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.differentiate(alt_speed_series);
+ }
+ if (accel_series != null) {
+
+ if (orient_series != null) {
+ vert_accel_series = add_series(vert_accel_name, AltosConvert.accel);
+
+ for (AltosTimeValue a : accel_series) {
+ double orient = orient_series.value(a.time);
+ double a_abs = a.value + AltosConvert.gravity;
+ double v_a = a_abs * Math.cos(AltosConvert.degrees_to_radians(orient)) - AltosConvert.gravity;
+
+ vert_accel_series.add(a.time, v_a);
+ }
+ }
+
+ AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
+
+ if (vert_accel_series != null)
+ vert_accel_series.integrate(temp_series);
+ else
+ accel_series.integrate(temp_series);
+
+ accel_speed_series = make_series(speed_name, AltosConvert.speed);
+ temp_series.filter(accel_speed_series, 0.1);
+ }
+
+ if (alt_speed_series != null && accel_speed_series != null) {
+ double apogee_time = AltosLib.MISSING;
+ if (state_series != null) {
+ for (AltosTimeValue d : state_series) {
+ if (d.value >= AltosLib.ao_flight_drogue){
+ apogee_time = d.time;
+ break;
+ }
+ }
+ }
+ if (apogee_time == AltosLib.MISSING) {
+ speed_series = alt_speed_series;
+ } else {
+ speed_series = make_series(speed_name, AltosConvert.speed);
+ for (AltosTimeValue d : accel_speed_series) {
+ if (d.time <= apogee_time)
+ speed_series.add(d);
+ }
+ for (AltosTimeValue d : alt_speed_series) {
+ if (d.time > apogee_time)
+ speed_series.add(d);
+ }
+
+ }
+ } else if (alt_speed_series != null) {
+ speed_series = alt_speed_series;
+ } else if (accel_speed_series != null) {
+ speed_series = accel_speed_series;
+ }
+ if (speed_series != null)
+ add_series(speed_series);
+ }
+
+ public AltosTimeSeries orient_series;
+
+ public static final String orient_name = "Tilt Angle";
+
+ private void compute_orient() {
+
+ if (orient_series != null)
+ return;
+
+ if (accel_ground_across == AltosLib.MISSING)
+ return;
+
+ if (cal_data().pad_orientation == AltosLib.MISSING)
+ return;
+
+ if (cal_data().accel_zero_across == AltosLib.MISSING)
+ return;
+
+ AltosRotation rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
+ AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
+ AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
+ cal_data().pad_orientation);
+ double prev_time = ground_time;
+
+ orient_series = add_series(orient_name, AltosConvert.orient);
+ orient_series.add(ground_time, rotation.tilt());
+
+ for (AltosTimeValue roll_v : gyro_roll) {
+ double time = roll_v.time;
+ double dt = time - prev_time;
+
+ if (dt > 0) {
+ double roll = AltosConvert.degrees_to_radians(roll_v.value) * dt;
+ double pitch = AltosConvert.degrees_to_radians(gyro_pitch.value(time)) * dt;
+ double yaw = AltosConvert.degrees_to_radians(gyro_yaw.value(time)) * dt;
+
+ rotation.rotate(pitch, yaw, roll);
+ orient_series.add(time, rotation.tilt());
+ }
+ prev_time = time;
+ }
+ }
+
+ public AltosTimeSeries kalman_height_series, kalman_speed_series, kalman_accel_series;
+
+ public static final String kalman_height_name = "Kalman Height";
+ public static final String kalman_speed_name = "Kalman Speed";
+ public static final String kalman_accel_name = "Kalman Accel";
+
+ public void set_kalman(double height, double speed, double acceleration) {
+ if (kalman_height_series == null) {
+ kalman_height_series = add_series(kalman_height_name, AltosConvert.height);
+ kalman_speed_series = add_series(kalman_speed_name, AltosConvert.speed);
+ kalman_accel_series = add_series(kalman_accel_name, AltosConvert.accel);
+ }
+ kalman_height_series.add(time(), height);
+ kalman_speed_series.add(time(), speed);
+ kalman_accel_series.add(time(), acceleration);
+ }
+
+ public AltosTimeSeries thrust_series;
+
+ public static final String thrust_name = "Thrust";
+
+ public void set_thrust(double N) {
+ if (thrust_series == null)
+ thrust_series = add_series(thrust_name, AltosConvert.force);
+ thrust_series.add(time(), N);
+ }
+
+ public AltosTimeSeries temperature_series;
+
+ public static final String temperature_name = "Temperature";
+
+ public void set_temperature(double deg_c) {
+ if (temperature_series == null)
+ temperature_series = add_series(temperature_name, AltosConvert.temperature);
+ temperature_series.add(time(), deg_c);
+ }
+
+ public AltosTimeSeries battery_voltage_series;
+
+ public static final String battery_voltage_name = "Battery Voltage";
+
+ public void set_battery_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (battery_voltage_series == null)
+ battery_voltage_series = add_series(battery_voltage_name, AltosConvert.voltage);
+ battery_voltage_series.add(time(), volts);
+ }
+
+ public AltosTimeSeries apogee_voltage_series;
+
+ public static final String apogee_voltage_name = "Apogee Voltage";
+
+ public void set_apogee_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (apogee_voltage_series == null)
+ apogee_voltage_series = add_series(apogee_voltage_name, AltosConvert.voltage);
+ apogee_voltage_series.add(time(), volts);
+ }
+
+ public AltosTimeSeries main_voltage_series;
+
+ public static final String main_voltage_name = "Main Voltage";
+
+ public void set_main_voltage(double volts) {
+ if (volts == AltosLib.MISSING)
+ return;
+ if (main_voltage_series == null)
+ main_voltage_series = add_series(main_voltage_name, AltosConvert.voltage);
+ main_voltage_series.add(time(), volts);
+ }
+
+ public ArrayList<AltosGPSTimeValue> gps_series;
+
+ public AltosGPS gps_before(double time) {
+ AltosGPS gps = null;
+ for (AltosGPSTimeValue gtv : gps_series)
+ if (gtv.time <= time)
+ gps = gtv.gps;
+ else
+ break;
+ return gps;
+ }
+
+ public AltosTimeSeries sats_in_view;
+ public AltosTimeSeries sats_in_soln;
+ public AltosTimeSeries gps_altitude;
+ public AltosTimeSeries gps_height;
+ public AltosTimeSeries gps_ground_speed;
+ public AltosTimeSeries gps_ascent_rate;
+ public AltosTimeSeries gps_course;
+ public AltosTimeSeries gps_speed;
+ public AltosTimeSeries gps_pdop, gps_vdop, gps_hdop;
+
+ public static final String sats_in_view_name = "Satellites in view";
+ public static final String sats_in_soln_name = "Satellites in solution";
+ public static final String gps_altitude_name = "GPS Altitude";
+ public static final String gps_height_name = "GPS Height";
+ public static final String gps_ground_speed_name = "GPS Ground Speed";
+ public static final String gps_ascent_rate_name = "GPS Ascent Rate";
+ public static final String gps_course_name = "GPS Course";
+ public static final String gps_speed_name = "GPS Speed";
+ public static final String gps_pdop_name = "GPS Dilution of Precision";
+ public static final String gps_vdop_name = "GPS Vertical Dilution of Precision";
+ public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision";
+
+ public void set_gps(AltosGPS gps) {
+ if (gps_series == null)
+ gps_series = new ArrayList<AltosGPSTimeValue>();
+ gps_series.add(new AltosGPSTimeValue(time(), gps));
+
+ if (sats_in_soln == null) {
+ sats_in_soln = add_series(sats_in_soln_name, null);
+ }
+ sats_in_soln.add(time(), gps.nsat);
+ if (gps.pdop != AltosLib.MISSING) {
+ if (gps_pdop == null)
+ gps_pdop = add_series(gps_pdop_name, null);
+ gps_pdop.add(time(), gps.pdop);
+ }
+ if (gps.hdop != AltosLib.MISSING) {
+ if (gps_hdop == null)
+ gps_hdop = add_series(gps_hdop_name, null);
+ gps_hdop.add(time(), gps.hdop);
+ }
+ if (gps.vdop != AltosLib.MISSING) {
+ if (gps_vdop == null)
+ gps_vdop = add_series(gps_vdop_name, null);
+ gps_vdop.add(time(), gps.vdop);
+ }
+ if (gps.locked) {
+ if (gps.alt != AltosLib.MISSING) {
+ if (gps_altitude == null)
+ gps_altitude = add_series(gps_altitude_name, AltosConvert.height);
+ gps_altitude.add(time(), gps.alt);
+ }
+ if (gps.ground_speed != AltosLib.MISSING) {
+ if (gps_ground_speed == null)
+ gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed);
+ gps_ground_speed.add(time(), gps.ground_speed);
+ }
+ if (gps.climb_rate != AltosLib.MISSING) {
+ if (gps_ascent_rate == null)
+ gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed);
+ gps_ascent_rate.add(time(), gps.climb_rate);
+ }
+ if (gps.course != AltosLib.MISSING) {
+ if (gps_course == null)
+ gps_course = add_series(gps_course_name, null);
+ gps_course.add(time(), gps.course);
+ }
+ if (gps.ground_speed != AltosLib.MISSING && gps.climb_rate != AltosLib.MISSING) {
+ if (gps_speed == null)
+ gps_speed = add_series(gps_speed_name, null);
+ gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +
+ gps.climb_rate * gps.climb_rate));
+ }
+ }
+ if (gps.cc_gps_sat != null) {
+ if (sats_in_view == null)
+ sats_in_view = add_series(sats_in_view_name, null);
+ sats_in_view.add(time(), gps.cc_gps_sat.length);
+ }
+ }
+
+ public static final String accel_along_name = "Accel Along";
+ public static final String accel_across_name = "Accel Across";
+ public static final String accel_through_name = "Accel Through";
+
+ public AltosTimeSeries accel_along, accel_across, accel_through;
+
+ public static final String gyro_roll_name = "Roll Rate";
+ public static final String gyro_pitch_name = "Pitch Rate";
+ public static final String gyro_yaw_name = "Yaw Rate";
+
+ public AltosTimeSeries gyro_roll, gyro_pitch, gyro_yaw;
+
+ public static final String mag_along_name = "Magnetic Field Along";
+ public static final String mag_across_name = "Magnetic Field Across";
+ public static final String mag_through_name = "Magnetic Field Through";
+
+ public AltosTimeSeries mag_along, mag_across, mag_through;
+
+ public void set_accel(double along, double across, double through) {
+ if (accel_along == null) {
+ accel_along = add_series(accel_along_name, AltosConvert.accel);
+ accel_across = add_series(accel_across_name, AltosConvert.accel);
+ accel_through = add_series(accel_through_name, AltosConvert.accel);
+ }
+ accel_along.add(time(), along);
+ accel_across.add(time(), across);
+ accel_through.add(time(), through);
+ }
+
+ private double accel_ground_along = AltosLib.MISSING;
+ private double accel_ground_across = AltosLib.MISSING;
+ private double accel_ground_through = AltosLib.MISSING;
+
+ private double ground_time;
+
+ public void set_accel_ground(double along, double across, double through) {
+ accel_ground_along = along;
+ accel_ground_across = across;
+ accel_ground_through = through;
+ ground_time = time();
+ }
+
+ public void set_gyro(double roll, double pitch, double yaw) {
+ if (gyro_roll == null) {
+ gyro_roll = add_series(gyro_roll_name, AltosConvert.rotation_rate);
+ gyro_pitch = add_series(gyro_pitch_name, AltosConvert.rotation_rate);
+ gyro_yaw = add_series(gyro_yaw_name, AltosConvert.rotation_rate);
+ }
+ gyro_roll.add(time(), roll);
+ gyro_pitch.add(time(), pitch);
+ gyro_yaw.add(time(), yaw);
+ }
+
+ public void set_mag(double along, double across, double through) {
+ if (mag_along == null) {
+ mag_along = add_series(mag_along_name, AltosConvert.magnetic_field);
+ mag_across = add_series(mag_across_name, AltosConvert.magnetic_field);
+ mag_through = add_series(mag_through_name, AltosConvert.magnetic_field);
+ }
+ mag_along.add(time(), along);
+ mag_across.add(time(), across);
+ mag_through.add(time(), through);
+ }
+
+ public void set_orient(double orient) {
+ if (orient_series == null)
+ orient_series = add_series(orient_name, AltosConvert.orient);
+ orient_series.add(time(), orient);
+ }
+
+ public static final String pyro_voltage_name = "Pyro Voltage";
+
+ public AltosTimeSeries pyro_voltage;
+
+ public void set_pyro_voltage(double volts) {
+ if (pyro_voltage == null)
+ pyro_voltage = add_series(pyro_voltage_name, AltosConvert.voltage);
+ pyro_voltage.add(time(), volts);
+ }
+
+ private static String[] igniter_voltage_names;
+
+ public String igniter_voltage_name(int channel) {
+ if (igniter_voltage_names == null || igniter_voltage_names.length <= channel) {
+ String[] new_igniter_voltage_names = new String[channel + 1];
+ int i = 0;
+
+ if (igniter_voltage_names != null) {
+ for (; i < igniter_voltage_names.length; i++)
+ new_igniter_voltage_names[i] = igniter_voltage_names[i];
+ }
+ for (; i < channel+1; i++)
+ new_igniter_voltage_names[i] = AltosLib.igniter_name(i);
+ igniter_voltage_names = new_igniter_voltage_names;
+ }
+ return igniter_voltage_names[channel];
+ }
+
+ public AltosTimeSeries[] igniter_voltage;
+
+ public void set_igniter_voltage(double[] voltage) {
+ int channels = voltage.length;
+ if (igniter_voltage == null || igniter_voltage.length <= channels) {
+ AltosTimeSeries[] new_igniter_voltage = new AltosTimeSeries[channels + 1];
+ int i = 0;
+
+ if (igniter_voltage != null) {
+ for (; i < igniter_voltage.length; i++)
+ new_igniter_voltage[i] = igniter_voltage[i];
+ }
+ for (; i < channels; i++)
+ new_igniter_voltage[i] = add_series(igniter_voltage_name(i), AltosConvert.voltage);
+ igniter_voltage = new_igniter_voltage;
+ }
+ for (int channel = 0; channel < voltage.length; channel++)
+ igniter_voltage[channel].add(time(), voltage[channel]);
+ }
+
+ public static final String pyro_fired_name = "Pyro Channel State";
+
+ public AltosTimeSeries pyro_fired_series;
+
+ int last_pyro_mask;
+
+ public void set_pyro_fired(int pyro_mask) {
+ if (pyro_fired_series == null)
+ pyro_fired_series = add_series(pyro_fired_name, AltosConvert.pyro_name);
+ for (int channel = 0; channel < 32; channel++) {
+ if ((last_pyro_mask & (1 << channel)) == 0 &&
+ (pyro_mask & (1 << channel)) != 0) {
+ pyro_fired_series.add(time(), channel);
+ }
+ }
+ last_pyro_mask = pyro_mask;
+ }
+
+ public void set_companion(AltosCompanion companion) {
+ }
+
+ public void finish() {
+ compute_orient();
+ compute_speed();
+ compute_accel();
+ compute_height();
+ }
+
+ public AltosTimeSeries[] series() {
+ finish();
+ return series.toArray(new AltosTimeSeries[0]);
+ }
+
+ public AltosFlightSeries(AltosCalData cal_data) {
+ super(cal_data);
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
public double max_gps_height;
public double max_speed;
public double max_acceleration;
- public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
- public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
- public int[] state_count = new int[AltosLib.ao_flight_invalid + 1];
- public double[] state_start = new double[AltosLib.ao_flight_invalid + 1];
- public double[] state_end = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_time = new double[AltosLib.ao_flight_invalid + 1];
+ public String product;
+ public String firmware_version;
public int serial;
public int flight;
public int year, month, day;
public int hour, minute, second;
+ public double boost_time;
+ public double landed_time;
public double lat, lon;
public double pad_lat, pad_lon;
public boolean has_flight_data;
public boolean has_imu;
public boolean has_mag;
public boolean has_orient;
- public int num_ignitor;
+ public int num_igniter;
- double landed_time(AltosStateIterable states) {
- AltosState state = null;
+ double landed_time(AltosFlightSeries series) {
+ double landed_state_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
- if (state.state() == AltosLib.ao_flight_landed)
- break;
+ double prev_state_time = AltosLib.MISSING;
+ if (series.state_series != null) {
+ for (AltosTimeValue state : series.state_series) {
+ if (state.value == AltosLib.ao_flight_landed) {
+ landed_state_time = state.time;
+ break;
+ } else {
+ prev_state_time = state.time;
+ }
+ }
}
- if (state == null)
- return AltosLib.MISSING;
+ if (landed_state_time == AltosLib.MISSING && series.height_series != null)
+ landed_state_time = series.height_series.get(series.height_series.size()-1).time;
- double landed_height = state.height();
+ double landed_height = AltosLib.MISSING;
+
+ if (series.height_series != null) {
+ for (AltosTimeValue height : series.height_series) {
+ landed_height = height.value;
+ if (height.time >= landed_state_time)
+ break;
+ }
+ }
- state = null;
+ if (landed_height == AltosLib.MISSING)
+ return AltosLib.MISSING;
boolean above = true;
double landed_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
-
- if (state.height() > landed_height + 10) {
- above = true;
- } else {
- if (above && Math.abs(state.height() - landed_height) < 2) {
- above = false;
- landed_time = state.time;
+ if (series.height_series != null) {
+ for (AltosTimeValue height : series.height_series) {
+ if (height.value > landed_height + 10) {
+ above = true;
+ } else {
+ if (above && Math.abs(height.value - landed_height) < 2) {
+ above = false;
+ landed_time = height.time;
+ }
}
}
}
+
+ if (landed_time == AltosLib.MISSING || (prev_state_time != AltosLib.MISSING && landed_time < prev_state_time))
+ landed_time = landed_state_time;
return landed_time;
}
- double boost_time(AltosStateIterable states) {
- double boost_time = AltosLib.MISSING;
- AltosState state = null;
+ double boost_time(AltosFlightSeries series) {
+ double boost_time = AltosLib.MISSING;
+ double boost_state_time = AltosLib.MISSING;
- for (AltosState s : states) {
- state = s;
- if (state.acceleration() < 1)
- boost_time = state.time;
- if (state.state() >= AltosLib.ao_flight_boost && state.state() <= AltosLib.ao_flight_landed)
- break;
+ if (series.state_series != null) {
+ for (AltosTimeValue state : series.state_series) {
+ if (state.value >= AltosLib.ao_flight_boost && state.value <= AltosLib.ao_flight_landed) {
+ boost_state_time = state.time;
+ break;
+ }
+ }
}
- if (state == null)
- return AltosLib.MISSING;
-
+ if (series.accel_series != null) {
+ for (AltosTimeValue accel : series.accel_series) {
+ if (accel.value < 1)
+ boost_time = accel.time;
+ if (boost_state_time != AltosLib.MISSING && accel.time >= boost_state_time)
+ break;
+ }
+ }
+ if (boost_time == AltosLib.MISSING)
+ boost_time = boost_state_time;
return boost_time;
}
+ private void add_times(AltosFlightSeries series, int state, double start_time, double end_time) {
+ double delta_time = end_time - start_time;
+ if (0 <= state && state <= AltosLib.ao_flight_invalid && delta_time > 0) {
+ speeds[state].value += series.speed_series.average(start_time, end_time) * delta_time;
+ speeds[state].time += delta_time;
+ accels[state].value += series.accel_series.average(start_time, end_time) * delta_time;
+ accels[state].time += delta_time;
+ state_time[state] += delta_time;
+
+ if (state == AltosLib.ao_flight_boost) {
+ AltosTimeValue tv_speed = series.speed_series.max(start_time, end_time);
+ if (tv_speed != null && (max_speed == AltosLib.MISSING || tv_speed.value > max_speed))
+ max_speed = tv_speed.value;
+ AltosTimeValue tv_accel = series.accel_series.max(start_time, end_time);
+ if (tv_accel != null && (max_acceleration == AltosLib.MISSING || tv_accel.value > max_acceleration))
+ max_acceleration = tv_accel.value;
+ }
+ }
+ }
+
+ AltosTimeValue[] speeds = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
+ AltosTimeValue[] accels = new AltosTimeValue[AltosLib.ao_flight_invalid + 1];
- public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException {
- double boost_time = boost_time(states);
- double end_time = 0;
- double landed_time = landed_time(states);
+ public AltosFlightStats(AltosFlightSeries series) {
+ AltosCalData cal_data = series.cal_data();
+
+ series.finish();
+
+ boost_time = boost_time(series);
+ landed_time = landed_time(series);
+
+ if (series.state_series != null){
+ boolean fixed_boost = false;
+ boolean fixed_landed = false;
+ for (AltosTimeValue state : series.state_series) {
+ if ((int) state.value == AltosLib.ao_flight_boost)
+ if (boost_time != AltosLib.MISSING && !fixed_boost) {
+ state.time = boost_time;
+ fixed_boost = true;
+ }
+ if ((int) state.value == AltosLib.ao_flight_landed)
+ if (landed_time != AltosLib.MISSING && !fixed_landed) {
+ state.time = landed_time;
+ fixed_landed = true;
+ }
+ }
+ }
year = month = day = AltosLib.MISSING;
hour = minute = second = AltosLib.MISSING;
has_mag = false;
has_orient = false;
- for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) {
- state_count[s] = 0;
- state_speed[s] = 0.0;
- state_accel[s] = 0.0;
+ for (int s = 0; s < AltosLib.ao_flight_invalid + 1; s++) {
+ state_speed[s] = AltosLib.MISSING;
+ state_accel[s] = AltosLib.MISSING;
+ state_time[s] = 0;
+ speeds[s] = new AltosTimeValue(0, 0);
+ accels[s] = new AltosTimeValue(0, 0);
}
- for (AltosState state : states) {
- if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING)
- serial = state.serial;
- if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING)
- flight = state.flight;
- if (state.battery_voltage != AltosLib.MISSING)
- has_battery = true;
- if (state.main_voltage != AltosLib.MISSING)
- has_flight_adc = true;
- if (state.rssi != AltosLib.MISSING)
- has_rssi = true;
- end_time = state.time;
-
- if (state.pressure() != AltosLib.MISSING)
- has_flight_data = true;
-
- int state_id = state.state();
- if (boost_time != AltosLib.MISSING && state.time >= boost_time && state_id < AltosLib.ao_flight_boost) {
- state_id = AltosLib.ao_flight_boost;
- }
- if (landed_time != AltosLib.MISSING && state.time >= landed_time && state_id < AltosLib.ao_flight_landed) {
- state_id = AltosLib.ao_flight_landed;
- }
+ max_speed = AltosLib.MISSING;
+ max_acceleration = AltosLib.MISSING;
- if (state.gps != null && state.gps.locked) {
- year = state.gps.year;
- month = state.gps.month;
- day = state.gps.day;
- hour = state.gps.hour;
- minute = state.gps.minute;
- second = state.gps.second;
+ if (series.state_series != null) {
+ AltosTimeValue prev = null;
+ for (AltosTimeValue state : series.state_series) {
+ if (prev != null)
+ add_times(series, (int) prev.value, prev.time, state.time);
+ prev = state;
}
- max_height = state.max_height();
- max_speed = state.max_speed();
- max_acceleration = state.max_acceleration();
- max_gps_height = state.max_gps_height();
-
- if (0 <= state_id && state_id < AltosLib.ao_flight_invalid) {
- double acceleration = state.acceleration();
- double speed = state.speed();
- if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) {
- state_accel[state_id] += acceleration;
- state_speed[state_id] += speed;
- state_count[state_id]++;
+ if (prev != null)
+ add_times(series, (int) prev.value, prev.time, series.accel_series.last().time);
+ }
+
+ for (int s = 0; s <= AltosLib.ao_flight_invalid; s++) {
+ if (speeds[s].time > 0)
+ state_speed[s] = speeds[s].value / speeds[s].time;
+ if (accels[s].time > 0)
+ state_accel[s] = accels[s].value / accels[s].time;
+ }
+
+ product = cal_data.product;
+ firmware_version = cal_data.firmware_version;
+ serial = cal_data.serial;
+ flight = cal_data.flight;
+
+ has_battery = series.battery_voltage_series != null;
+ has_flight_adc = series.main_voltage_series != null;
+ has_rssi = series.rssi_series != null;
+ has_flight_data = series.pressure_series != null;
+
+ AltosGPS gps = series.cal_data().gps_pad;
+
+ if (gps != null) {
+ year = gps.year;
+ month = gps.month;
+ day = gps.day;
+ hour = gps.hour;
+ minute = gps.minute;
+ second = gps.second;
+ has_gps = true;
+ lat = pad_lat = gps.lat;
+ lon = pad_lon = gps.lon;
+ for (AltosGPSTimeValue gtv : series.gps_series) {
+ gps = gtv.gps;
+ if (gps.locked && gps.nsat >= 4) {
+ lat = gps.lat;
+ lon = gps.lon;
}
- if (state_start[state_id] == 0.0)
- state_start[state_id] = state.time;
- if (state_end[state_id] < state.time)
- state_end[state_id] = state.time;
- }
- if (state.pad_lat != AltosLib.MISSING) {
- pad_lat = state.pad_lat;
- pad_lon = state.pad_lon;
}
- if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
- lat = state.gps.lat;
- lon = state.gps.lon;
- has_gps = true;
- if (state.gps.cc_gps_sat != null)
- has_gps_sats = true;
- if (state.gps.course != AltosLib.MISSING)
- has_gps_detail = true;
- }
- if (state.imu != null)
- has_imu = true;
- if (state.mag != null)
- has_mag = true;
- if (state.orient() != AltosLib.MISSING)
- has_orient = true;
- if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor)
- num_ignitor = state.ignitor_voltage.length;
+
}
- for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) {
- if (state_count[s] > 0) {
- state_speed[s] /= state_count[s];
- state_accel[s] /= state_count[s];
- } else {
- state_speed[s] = AltosLib.MISSING;
- state_accel[s] = AltosLib.MISSING;
- }
- if (state_start[s] == 0)
- state_start[s] = end_time;
- if (state_end[s] == 0)
- state_end[s] = end_time;
+
+ max_height = AltosLib.MISSING;
+ if (series.height_series != null)
+ max_height = series.height_series.max().value;
+ max_gps_height = AltosLib.MISSING;
+ if (series.gps_height != null) {
+ AltosTimeValue tv = series.gps_height.max();
+ if (tv != null)
+ max_gps_height = tv.value;
}
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosFontListener {
void font_size_changed(int font_size);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosForce extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.concurrent.*;
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
- AltosGPS gps = new AltosGPS(link, config_data);
-
- if (gps != null) {
- state.set_gps(gps, state.gps_sequence++);
- return;
- }
+ AltosGPS gps = new AltosGPS(link, link.config_data());
+ if (gps != null)
+ listener.set_gps(gps);
} catch (TimeoutException te) {
}
- state.set_gps(null, 0);
}
public AltosGPS (AltosLink link, AltosConfigData config_data) throws TimeoutException, InterruptedException {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.text.*;
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosGPSTimeValue {
+ public double time;
+ public AltosGPS gps;
+
+ public AltosGPSTimeValue(double time, AltosGPS gps) {
+ this.time = time;
+ this.gps = gps;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.lang.Math;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosHeight extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.LinkedList;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosHexsym {
String name;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosIMU implements Cloneable {
- public int accel_along;
- public int accel_across;
- public int accel_through;
+ public int accel_x;
+ public int accel_y;
+ public int accel_z;
- public int gyro_roll;
- public int gyro_pitch;
- public int gyro_yaw;
+ public int gyro_x;
+ public int gyro_y;
+ public int gyro_z;
public static final double counts_per_g = 2048.0;
public static double convert_accel(double counts) {
- return counts / counts_per_g * (-AltosConvert.GRAVITATIONAL_ACCELERATION);
+ return counts / counts_per_g * AltosConvert.gravity;
}
- public static final double counts_per_degsec = 16.4;
+ /* In radians */
+ public static final double GYRO_FULLSCALE_DEGREES = 2000.0;
+ public static final double GYRO_COUNTS = 32767.0;
- public static double convert_gyro(double counts) {
- return counts / counts_per_degsec;
+ public static double gyro_degrees_per_second(double counts, double cal) {
+ return (counts - cal) * GYRO_FULLSCALE_DEGREES / GYRO_COUNTS;
}
public boolean parse_string(String line) {
String[] items = line.split("\\s+");
if (items.length >= 8) {
- accel_along = Integer.parseInt(items[1]);
- accel_across = Integer.parseInt(items[2]);
- accel_through = Integer.parseInt(items[3]);
- gyro_roll = Integer.parseInt(items[5]);
- gyro_pitch = Integer.parseInt(items[6]);
- gyro_yaw = Integer.parseInt(items[7]);
+ accel_x = Integer.parseInt(items[1]);
+ accel_y = Integer.parseInt(items[2]);
+ accel_z = Integer.parseInt(items[3]);
+ gyro_x = Integer.parseInt(items[5]);
+ gyro_y = Integer.parseInt(items[6]);
+ gyro_z = Integer.parseInt(items[7]);
}
return true;
}
public AltosIMU clone() {
AltosIMU n = new AltosIMU();
- n.accel_along = accel_along;
- n.accel_across = accel_across;
- n.accel_through = accel_through;
+ n.accel_x = accel_x;
+ n.accel_y = accel_y;
+ n.accel_z = accel_z;
- n.gyro_roll = gyro_roll;
- n.gyro_pitch = gyro_pitch;
- n.gyro_yaw = gyro_yaw;
+ n.gyro_x = gyro_x;
+ n.gyro_y = gyro_y;
+ n.gyro_z = gyro_z;
return n;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosIMU imu = new AltosIMU(link);
-
- if (imu != null)
- state.set_imu(imu);
+ AltosCalData cal_data = listener.cal_data();
+
+ if (imu != null) {
+ listener.set_gyro(cal_data.gyro_roll(imu.gyro_y),
+ cal_data.gyro_pitch(imu.gyro_x),
+ cal_data.gyro_yaw(imu.gyro_z));
+ listener.set_accel_ground(cal_data.accel_along(imu.accel_y),
+ cal_data.accel_across(imu.accel_x),
+ cal_data.accel_through(imu.accel_z));
+ }
} catch (TimeoutException te) {
}
}
public AltosIMU() {
- accel_along = AltosLib.MISSING;
- accel_across = AltosLib.MISSING;
- accel_through = AltosLib.MISSING;
-
- gyro_roll = AltosLib.MISSING;
- gyro_pitch = AltosLib.MISSING;
- gyro_yaw = AltosLib.MISSING;
- }
-
- public AltosIMU(int accel_along, int accel_across, int accel_through,
- int gyro_roll, int gyro_pitch, int gyro_yaw) {
-
- this.accel_along = accel_along;
- this.accel_across = accel_across;
- this.accel_through = accel_through;
+ accel_x = AltosLib.MISSING;
+ accel_y = AltosLib.MISSING;
+ accel_z = AltosLib.MISSING;
- this.gyro_roll = gyro_roll;
- this.gyro_pitch = gyro_pitch;
- this.gyro_yaw = gyro_yaw;
+ gyro_x = AltosLib.MISSING;
+ gyro_y = AltosLib.MISSING;
+ gyro_z = AltosLib.MISSING;
}
public AltosIMU(AltosLink link) throws InterruptedException, TimeoutException {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
static final int idle_gps = 0;
static final int idle_imu = 1;
static final int idle_mag = 2;
- static final int idle_ms5607 = 3;
static final int idle_mma655x = 4;
+ static final int idle_ms5607 = 5;
static final int idle_sensor_tm = 10;
static final int idle_sensor_metrum = 11;
static final int idle_sensor_mega = 12;
- static final int idle_sensor_emini = 13;
- static final int idle_sensor_tmini2 = 14;
- static final int idle_sensor_tgps = 15;
- static final int idle_sensor_tmini3 = 16;
+ static final int idle_sensor_emini1 = 13;
+ static final int idle_sensor_emini2 = 14;
+ static final int idle_sensor_tmini2 = 15;
+ static final int idle_sensor_tgps = 16;
+ static final int idle_sensor_tmini3 = 17;
- public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, TimeoutException, AltosUnknownProduct {
for (int idler : idlers) {
- AltosIdle idle = null;
switch (idler) {
case idle_gps:
- AltosGPS.update_state(state, link, config_data);
+ AltosGPS.provide_data(listener, link);
break;
case idle_imu:
- AltosIMU.update_state(state, link, config_data);
+ AltosIMU.provide_data(listener, link);
break;
case idle_mag:
- AltosMag.update_state(state, link, config_data);
- break;
- case idle_ms5607:
- AltosMs5607.update_state(state, link, config_data);
+ AltosMag.provide_data(listener, link);
break;
case idle_mma655x:
- AltosMma655x.update_state(state, link, config_data);
+ AltosMma655x.provide_data(listener, link);
+ break;
+ case idle_ms5607:
+ AltosMs5607.provide_data(listener, link);
break;
case idle_sensor_tm:
- AltosSensorTM.update_state(state, link, config_data);
+ AltosSensorTM.provide_data(listener, link);
break;
case idle_sensor_metrum:
- AltosSensorMetrum.update_state(state, link, config_data);
+ AltosSensorMetrum.provide_data(listener, link);
break;
case idle_sensor_mega:
- AltosSensorMega.update_state(state, link, config_data);
+ AltosSensorMega.provide_data(listener, link);
+ break;
+ case idle_sensor_emini1:
+ AltosSensorEMini.provide_data(listener, link, 1);
break;
- case idle_sensor_emini:
- AltosSensorEMini.update_state(state, link, config_data);
+ case idle_sensor_emini2:
+ AltosSensorEMini.provide_data(listener, link, 2);
break;
case idle_sensor_tmini2:
- AltosSensorTMini2.update_state(state, link, config_data);
+ AltosSensorTMini2.provide_data(listener, link);
break;
case idle_sensor_tgps:
- AltosSensorTGPS.update_state(state, link, config_data);
+ AltosSensorTGPS.provide_data(listener, link);
break;
case idle_sensor_tmini3:
- AltosSensorTMini3.update_state(state, link, config_data);
+ AltosSensorTMini3.provide_data(listener, link);
break;
}
- if (idle != null)
- idle.update_state(state);
}
}
}
-public class AltosIdleFetch implements AltosStateUpdate {
+public class AltosIdleFetch implements AltosDataProvider {
static final AltosIdler[] idlers = {
- new AltosIdler("EasyMini",
+ new AltosIdler("EasyMini-v1",
AltosIdler.idle_ms5607,
- AltosIdler.idle_sensor_emini),
+ AltosIdler.idle_sensor_emini1),
+
+ new AltosIdler("EasyMini-v2",
+ AltosIdler.idle_ms5607,
+ AltosIdler.idle_sensor_emini2),
new AltosIdler("TeleMini-v1",
AltosIdler.idle_sensor_tm),
new AltosIdler("TeleMetrum-v2",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_sensor_metrum),
new AltosIdler("TeleMega",
AltosIdler.idle_gps,
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("EasyMega",
- AltosIdler.idle_ms5607, AltosIdler.idle_mma655x,
+ AltosIdler.idle_mma655x,
+ AltosIdler.idle_ms5607,
AltosIdler.idle_imu, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleGPS",
AltosLink link;
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct {
+ public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct {
try {
boolean matched = false;
/* Fetch config data from remote */
AltosConfigData config_data = new AltosConfigData(link);
- state.set_state(AltosLib.ao_flight_stateless);
- state.set_serial(config_data.serial);
- state.set_callsign(config_data.callsign);
- state.set_ground_accel(config_data.accel_cal_plus);
- state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
- state.set_product(config_data.product);
- state.set_firmware_version(config_data.version);
- state.set_log_space(config_data.log_space);
+ listener.set_state(AltosLib.ao_flight_stateless);
for (AltosIdler idler : idlers) {
if (idler.matches(config_data)) {
- idler.update_state(state, link, config_data);
+ idler.provide_data(listener, link);
matched = true;
break;
}
}
if (!matched)
throw new AltosUnknownProduct(config_data.product);
- state.set_received_time(System.currentTimeMillis());
+ listener.set_received_time(System.currentTimeMillis());
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.concurrent.*;
return link.reply_abort;
}
- boolean update_state(AltosState state) throws InterruptedException, TimeoutException, AltosUnknownProduct {
+ boolean provide_data(AltosDataListener listener) throws InterruptedException, TimeoutException, AltosUnknownProduct {
boolean worked = false;
boolean aborted = false;
try {
start_link();
- fetch.update_state(state);
+ fetch.provide_data(listener);
if (!link.has_error && !link.reply_abort)
worked = true;
} finally {
aborted = stop_link();
if (worked) {
if (remote)
- state.set_rssi(link.rssi(), 0);
+ listener.set_rssi(link.rssi(), 0);
listener_state.battery = link.monitor_battery();
}
}
}
public void run() {
- AltosState state = new AltosState();
+ AltosState state = null;
try {
for (;;) {
try {
link.config_data();
- update_state(state);
+ if (state == null)
+ state = new AltosState(new AltosCalData(link.config_data()));
+ provide_data(state);
listener.update(state, listener_state);
} catch (TimeoutException te) {
} catch (AltosUnknownProduct ae) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosIdleMonitorListener {
public void update(AltosState state, AltosListenerState listener_state);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
public class AltosIdleReader extends AltosFlightReader {
AltosLink link;
boolean remote;
+ AltosCalData cal_data = null;
AltosState state = null;
AltosIdleFetch fetch;
long next_millis;
return link.reply_abort;
}
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ try {
+ cal_data = new AltosCalData(link.config_data());
+ } catch (InterruptedException ie) {
+ } catch (TimeoutException te) {
+ }
+ if (cal_data == null)
+ cal_data = new AltosCalData();
+ }
+ return cal_data;
+ }
+
public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException {
boolean worked = false;
boolean aborted = false;
- if (state == null)
- state = new AltosState();
- else
- state = state.clone();
-
long delay = next_millis - System.currentTimeMillis();
if (delay > 0)
try {
try {
start_link();
- fetch.update_state(state);
+ if (state == null)
+ state = new AltosState(cal_data());
+ fetch.provide_data(state);
if (!link.has_error && !link.reply_abort)
worked = true;
} catch (TimeoutException te) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.io.*;
private void get_npyro() throws InterruptedException, TimeoutException {
if (config_data == null)
config_data = new AltosConfigData(link);
- if (config_data != null)
+ if (config_data != null && config_data.npyro != AltosLib.MISSING)
npyro = config_data.npyro;
else
npyro = 0;
try {
start_link();
link.printf("i DoIt %s\n", igniter);
+ link.flush_output();
} catch (TimeoutException te) {
} finally {
stop_link();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* Lexer for json
*/
class JsonLexer extends JsonUtil {
- Reader f;
+ InputStream f;
int line;
int ungot = -2;
StringBuffer pending_token;
}
JsonLexer(String s) {
- f = new StringReader(s);
+ f = new AltosStringInputStream(s);
line = 1;
token = null;
}
- JsonLexer(Reader f) {
+ JsonLexer(InputStream f) {
this.f = f;
line = 1;
token = null;
lexer = new JsonLexer(s);
}
- JsonParse(Reader f) {
+ JsonParse(InputStream f) {
lexer = new JsonLexer(f);
}
}
}
}
- public static AltosJson fromReader(Reader f) {
+ public static AltosJson fromInputStream(InputStream f) {
JsonParse parse = new JsonParse(f);
try {
return parse.parse();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
File name;
PrintWriter out;
int flight_state = -1;
- AltosState prev = null;
- double gps_start_altitude;
+ AltosGPS prev = null;
+ double gps_start_altitude = AltosLib.MISSING;
+ AltosFlightStats stats;
static final String[] kml_state_colors = {
"FF000000", // startup
"</Document>\n" +
"</kml>\n";
- void start (AltosState record) {
- out.printf(kml_header_start, record.flight, record.serial);
+ void start (AltosCalData cal_data) {
+ AltosGPS gps = cal_data.gps_pad;
+
+ gps_start_altitude = cal_data.gps_pad_altitude;
+ out.printf(kml_header_start, cal_data.flight, cal_data.serial);
out.printf("Date: %04d-%02d-%02d\n",
- record.gps.year, record.gps.month, record.gps.day);
+ gps.year, gps.month, gps.day);
out.printf("Time: %2d:%02d:%02d\n",
- record.gps.hour, record.gps.minute, record.gps.second);
+ gps.hour, gps.minute, gps.second);
out.printf("%s", kml_header_end);
}
boolean started = false;
- void state_start(AltosState state) {
- String state_name = AltosLib.state_name(state.state());
- String state_color = state_color(state.state());
+ void state_start(int state) {
+ String state_name = AltosLib.state_name(state);
+ String state_color = state_color(state);
out.printf(kml_style_start, state_name, state_color);
- out.printf("\tState: %s\n", state_name);
+ out.printf("State: %s\n", state_name);
+ out.printf("Time: %6.2f s\n", stats.state_end[state] - stats.state_start[state]);
+ out.printf("Average speed: %s\n", AltosConvert.speed.show(6, stats.state_speed[state]));
+ out.printf("Average accel: %s\n", AltosConvert.accel.show(6, stats.state_accel[state]));
out.printf("%s", kml_style_end);
out.printf(kml_placemark_start, state_name, state_name);
}
- void state_end(AltosState state) {
+ void state_end() {
out.printf("%s", kml_placemark_end);
}
- void coord(AltosState state) {
- AltosGPS gps = state.gps;
+ void coord(double time, AltosGPS gps, int state, double height) {
double altitude;
- if (state.height() != AltosLib.MISSING)
- altitude = state.height() + gps_start_altitude;
+ if (height != AltosLib.MISSING)
+ altitude = height + gps_start_altitude;
else
altitude = gps.alt;
out.printf(kml_coord_fmt,
gps.lon, gps.lat,
altitude, (double) gps.alt,
- state.time, gps.nsat);
+ time, gps.nsat);
}
void end() {
public void close() {
if (prev != null) {
- state_end(prev);
+ state_end();
end();
prev = null;
}
}
}
- public void write(AltosState state) {
- AltosGPS gps = state.gps;
-
- if (gps == null)
- return;
-
+ public void write(AltosGPSTimeValue gtv, AltosCalData cal_data, int state, double height) {
+ AltosGPS gps = gtv.gps;
if (gps.lat == AltosLib.MISSING)
return;
if (gps.lon == AltosLib.MISSING)
return;
- if (!started) {
- start(state);
- started = true;
- gps_start_altitude = gps.alt;
- }
- if (prev != null && prev.gps_sequence == state.gps_sequence)
- return;
- if (state.state() != flight_state) {
- flight_state = state.state();
+ if (state != flight_state) {
+ flight_state = state;
if (prev != null) {
- coord(state);
- state_end(prev);
+ coord(gtv.time, gps, state, height);
+ state_end();
}
state_start(state);
}
- coord(state);
- prev = state;
+ coord(0, gps, state, height);
+ prev = gps;
}
- public void write(AltosStateIterable states) {
- for (AltosState state : states) {
- if ((state.set & AltosState.set_gps) != 0)
- write(state);
- }
+ private int state(AltosFlightSeries series, double time) {
+ return (int) series.value_before(AltosFlightSeries.state_name, time);
+ }
+
+ private double height(AltosFlightSeries series, double time) {
+ return series.value(AltosFlightSeries.height_name, time);
+ }
+
+ public void write(AltosFlightSeries series) {
+ stats = new AltosFlightStats(series);
+ start(series.cal_data());
+ for (AltosGPSTimeValue gtv : series.gps_series)
+ write(gtv, series.cal_data(), state(series, gtv.time), height(series, gtv.time));
}
public AltosKML(File in_name) throws FileNotFoundException {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLatLon {
public double lat;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLatitude extends AltosLocation {
public String pos() { return "N"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.io.*;
public static final int AO_LOG_GPS_DATE = 'Y';
public static final int AO_LOG_PRESSURE = 'P';
+ public static boolean is_gps_cmd(int cmd) {
+ switch (cmd) {
+ case AltosLib.AO_LOG_GPS_POS:
+ case AltosLib.AO_LOG_GPS_TIME:
+ case AltosLib.AO_LOG_GPS_LAT:
+ case AltosLib.AO_LOG_GPS_LON:
+ case AltosLib.AO_LOG_GPS_ALT:
+ case AltosLib.AO_LOG_GPS_SAT:
+ case AltosLib.AO_LOG_GPS_DATE:
+ return true;
+ }
+ return false;
+ }
+
/* Added for header fields in eeprom files */
public static final int AO_LOG_CONFIG_VERSION = 1000;
public static final int AO_LOG_MAIN_DEPLOY = 1001;
return product_any;
}
+ public static boolean has_9dof(int device_type) {
+ return device_type == product_telemega || device_type == product_easymega;
+ }
+
+ public static boolean has_gps(int device_type) {
+ return device_type == product_telemetrum ||
+ device_type == product_telemega ||
+ device_type == product_telegps;
+ }
+
/* Bluetooth "identifier" (bluetooth sucks) */
public final static String bt_product_telebt = "TeleBT";
public static final int AO_LOG_FORMAT_TELEMETRY = 3;
public static final int AO_LOG_FORMAT_TELESCIENCE = 4;
public static final int AO_LOG_FORMAT_TELEMEGA_OLD = 5;
- public static final int AO_LOG_FORMAT_EASYMINI = 6;
+ public static final int AO_LOG_FORMAT_EASYMINI1 = 6;
public static final int AO_LOG_FORMAT_TELEMETRUM = 7;
public static final int AO_LOG_FORMAT_TELEMINI2 = 8;
public static final int AO_LOG_FORMAT_TELEGPS = 9;
public static final int AO_LOG_FORMAT_DETHERM = 11;
public static final int AO_LOG_FORMAT_TELEMINI3 = 12;
public static final int AO_LOG_FORMAT_TELEFIRETWO = 13;
+ public static final int AO_LOG_FORMAT_EASYMINI2 = 14;
public static final int AO_LOG_FORMAT_NONE = 127;
public static boolean isspace(int c) {
}
}
- public static String ignitor_name(int i) {
+ public static String igniter_name(int i) {
return String.format("Ignitor %c", 'A' + i);
}
+
+ public static AltosRecordSet record_set(File file) throws FileNotFoundException, IOException {
+ FileInputStream in;
+ in = new FileInputStream(file);
+ if (file.getName().endsWith("telem")) {
+ return new AltosTelemetryFile(in);
+ } else if (file.getName().endsWith("eeprom")) {
+ return new AltosEepromFile(in);
+ } else {
+ String name = file.getName();
+ int dot = name.lastIndexOf('.');
+ String extension;
+
+ if (dot == -1)
+ throw new IOException(String.format("%s (Missing extension)", file.toString()));
+ else {
+ extension = name.substring(dot);
+ throw new IOException(String.format("%s (Invalid extension '%s')",
+ file.toString(),
+ extension));
+ }
+ }
+ }
+
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLine {
public String line;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public abstract class AltosLocation extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.text.*;
return file;
}
- boolean open (AltosState state) throws IOException, InterruptedException {
- AltosFile a = new AltosFile(state);
+ boolean open (AltosCalData cal_data) throws IOException, InterruptedException {
+ AltosFile a = new AltosFile(cal_data);
log_file = new FileWriter(a, true);
if (log_file != null) {
public void run () {
try {
- AltosState state = new AltosState();
AltosConfigData receiver_config = link.config_data();
- state.set_receiver_serial(receiver_config.serial);
+ AltosCalData cal_data = new AltosCalData();
+ AltosState state = null;
+ cal_data.set_receiver_serial(receiver_config.serial);
for (;;) {
AltosLine line = input_queue.take();
if (line.line == null)
continue;
try {
AltosTelemetry telem = AltosTelemetry.parse(line.line);
- state = state.clone();
- telem.update_state(state);
- if (state.serial != serial || state.flight != flight || log_file == null)
+ if (state == null)
+ state = new AltosState(cal_data);
+ telem.provide_data(state);
+
+ if (cal_data.serial != serial ||
+ cal_data.flight != flight ||
+ log_file == null)
{
close_log_file();
- serial = state.serial;
- flight = state.flight;
- if (state.serial != AltosLib.MISSING && state.flight != AltosLib.MISSING)
- open(state);
+ serial = cal_data.serial;
+ flight = cal_data.flight;
+ state = null;
+ if (cal_data.serial != AltosLib.MISSING &&
+ cal_data.flight != AltosLib.MISSING)
+ open(cal_data);
}
} catch (ParseException pe) {
} catch (AltosCRCException ce) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosLongitude extends AltosLocation {
public String pos() { return "E"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosMag implements Cloneable {
- public int along;
- public int across;
- public int through;
+ public int x;
+ public int z;
+ public int y;
public static final double counts_per_gauss = 1090;
}
public boolean parse_string(String line) {
-// if (line.startsWith("Syntax error")) {
-// along = across = through = 0;
-// return true;
-// }
if (!line.startsWith("X:"))
return false;
String[] items = line.split("\\s+");
if (items.length >= 6) {
- along = Integer.parseInt(items[1]);
- across = Integer.parseInt(items[3]);
- through = Integer.parseInt(items[5]);
+ x = Integer.parseInt(items[1]);
+ z = Integer.parseInt(items[3]);
+ y = Integer.parseInt(items[5]);
}
return true;
}
public AltosMag clone() {
AltosMag n = new AltosMag();
- n.along = along;
- n.across = across;
- n.through = through;
+ n.x = x;
+ n.z = z;
+ n.y = y;
return n;
}
public AltosMag() {
- along = AltosLib.MISSING;
- across = AltosLib.MISSING;
- through = AltosLib.MISSING;
+ x = AltosLib.MISSING;
+ z = AltosLib.MISSING;
+ y = AltosLib.MISSING;
}
- public AltosMag(int along, int across, int through) {
- this.along = along;
- this.across = across;
- this.through = through;
- }
-
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosMag mag = new AltosMag(link);
+ AltosCalData cal_data = listener.cal_data();
if (mag != null)
- state.set_mag(mag);
+ listener.set_mag(cal_data.mag_along(mag.y),
+ cal_data.mag_across(mag.x),
+ cal_data.mag_through(mag.z));
} catch (TimeoutException te) {
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.*;
return false;
}
- public void show(AltosState state, AltosListenerState listener_state) {
+ public void show(AltosGPS gps, int state) {
- /* If insufficient gps data, nothing to update
+ /*
+ * If insufficient gps data, nothing to update
*/
- AltosGPS gps = state.gps;
if (gps == null)
return;
if (!gps.locked && gps.nsat < 4)
return;
- switch (state.state()) {
+ switch (state) {
case AltosLib.ao_flight_boost:
if (!have_boost) {
- add_mark(gps.lat, gps.lon, state.state());
+ add_mark(gps.lat, gps.lon, state);
have_boost = true;
}
break;
case AltosLib.ao_flight_landed:
if (!have_landed) {
- add_mark(gps.lat, gps.lon, state.state());
+ add_mark(gps.lat, gps.lon, state);
have_landed = true;
}
break;
}
if (path != null) {
- AltosMapRectangle damage = path.add(gps.lat, gps.lon, state.state());
+ AltosMapRectangle damage = path.add(gps.lat, gps.lon, state);
if (damage != null)
repaint(damage, AltosMapPath.stroke_width);
maybe_centre(gps.lat, gps.lon);
}
+ public void show(AltosState state, AltosListenerState listener_state) {
+ show(state.gps, state.state());
+ }
+
public void centre(AltosLatLon lat_lon) {
centre = lat_lon;
set_transform();
centre(new AltosLatLon(lat, lon));
}
- public void centre(AltosState state) {
- if (!state.gps.locked && state.gps.nsat < 4)
+ public void centre(AltosGPS gps) {
+ if (!gps.locked && gps.nsat < 4)
return;
- centre(state.gps.lat, state.gps.lon);
+ centre(gps.lat, gps.lon);
+ }
+
+ public void centre(AltosState state) {
+ centre(state.gps);
}
public void maybe_centre(double lat, double lon) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapCacheListener {
public void map_cache_changed(int map_cache);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
}
public String line_dist() {
- String format;
AltosGreatCircle g = new AltosGreatCircle(start.lat, start.lon,
end.lat, end.lon);
- double distance = g.distance;
- if (AltosConvert.imperial_units) {
- distance = AltosConvert.meters_to_feet(distance);
- if (distance < 1000) {
- format = "%4.0fft";
- } else {
- distance /= 5280;
- if (distance < 10)
- format = "%5.3fmi";
- else if (distance < 100)
- format = "%5.2fmi";
- else if (distance < 1000)
- format = "%5.1fmi";
- else
- format = "%5.0fmi";
- }
- } else {
- if (distance < 1000) {
- format = "%4.0fm";
- } else {
- distance /= 1000;
- if (distance < 100)
- format = "%5.2fkm";
- else if (distance < 1000)
- format = "%5.1fkm";
- else
- format = "%5.0fkm";
- }
- }
- return String.format(format, distance);
+ return AltosConvert.distance.show(7, g.distance);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapLoaderListener {
public abstract void loader_start(int max);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosMapRectangle {
AltosLatLon ul, lr;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.net.*;
static Object forbidden_lock = new Object();
static long forbidden_time;
static boolean forbidden_set;
+ public static int forbidden_response;
private int fetch_url() {
URL u;
synchronized (forbidden_lock) {
forbidden_time = System.nanoTime();
forbidden_set = true;
+ forbidden_response = response;
return AltosMapTile.forbidden;
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapStoreListener {
abstract void notify_store(AltosMapStore store, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapTileListener {
abstract public void notify_tile(AltosMapTile tile, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapTypeListener {
public void map_type_changed(int map_type);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosMapZoomListener {
abstract public void zoom_changed(int zoom);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
return n;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, AltosUnknownProduct {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, AltosUnknownProduct {
try {
AltosMma655x mma655x = new AltosMma655x(link);
+ AltosCalData cal_data = listener.cal_data();
if (mma655x != null) {
int accel = mma655x.accel;
- if (config_data.mma655x_inverted())
+ if (cal_data.mma655x_inverted)
accel = 4095 - accel;
- if (config_data.pad_orientation == 1)
+ if (cal_data.pad_orientation == 1)
accel = 4095 - accel;
- state.set_accel(accel);
+ listener.set_acceleration(cal_data.acceleration(accel));
}
} catch (TimeoutException te) {
} catch (NumberFormatException ne) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.*;
import java.io.*;
public class AltosMs5607 {
- public int reserved;
- public int sens;
- public int off;
- public int tcs;
- public int tco;
- public int tref;
- public int tempsens;
- public int crc;
-
- public int raw_pres;
- public int raw_temp;
- public int pa;
- public int cc;
-
- static final boolean ms5611 = false;
-
- void convert() {
+ public int reserved = AltosLib.MISSING;
+ public int sens = AltosLib.MISSING;
+ public int off = AltosLib.MISSING;
+ public int tcs = AltosLib.MISSING;
+ public int tco = AltosLib.MISSING;
+ public int tref = AltosLib.MISSING;
+ public int tempsens = AltosLib.MISSING;
+ public int crc = AltosLib.MISSING;
+ private boolean ms5611 = false;
+
+ public boolean valid_config() {
+ return reserved != AltosLib.MISSING &&
+ sens != AltosLib.MISSING &&
+ off != AltosLib.MISSING &&
+ tcs != AltosLib.MISSING &&
+ tco != AltosLib.MISSING &&
+ tref != AltosLib.MISSING &&
+ tempsens != AltosLib.MISSING &&
+ crc != AltosLib.MISSING;
+ }
+
+ public AltosPresTemp pres_temp(int raw_pres, int raw_temp) {
int dT;
- int TEMP;
- long OFF;
- long SENS;
- //int P;
+ int TEMP;
+ long OFF;
+ long SENS;
+ int P;
+
+ if (raw_pres == AltosLib.MISSING || raw_temp == AltosLib.MISSING)
+ return new AltosPresTemp(AltosLib.MISSING, AltosLib.MISSING);
dT = raw_temp - ((int) tref << 8);
SENS -= SENS2;
}
- pa = (int) (((((long) raw_pres * SENS) >> 21) - OFF) >> 15);
- cc = TEMP;
- }
+ P = (int) (((((long) raw_pres * SENS) >> 21) - OFF) >> 15);
- public int set(int in_pres, int in_temp) {
- raw_pres = in_pres;
- raw_temp = in_temp;
- convert();
- return pa;
+ return new AltosPresTemp(P, TEMP / 100.0);
}
- public boolean parse_line(String line) {
- String[] items = line.split("\\s+");
- if (line.startsWith("Pressure:")) {
- if (items.length >= 2) {
- raw_pres = Integer.parseInt(items[1]);
- }
- } else if (line.startsWith("Temperature:")) {
- if (items.length >= 2)
- raw_temp = Integer.parseInt(items[1]);
- } else if (line.startsWith("ms5607 reserved:")) {
- if (items.length >= 3)
- reserved = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 sens:")) {
- if (items.length >= 3) {
- sens = Integer.parseInt(items[2]);
+ public AltosPresTemp pres_temp(AltosLink link) throws InterruptedException, TimeoutException {
+ int raw_pres = AltosLib.MISSING;
+ int raw_temp = AltosLib.MISSING;
+ boolean done = false;
+
+ link.printf("B\n");
+ while (!done) {
+ String line = link.get_reply_no_dialog(5000);
+ if (line == null)
+ throw new TimeoutException();
+
+ String[] items = line.split("\\s+");
+ if (line.startsWith("Pressure:")) {
+ if (items.length >= 2) {
+ raw_pres = Integer.parseInt(items[1]);
+ }
+ } else if (line.startsWith("Temperature:")) {
+ if (items.length >= 2)
+ raw_temp = Integer.parseInt(items[1]);
+ } else if (line.startsWith("Altitude:")) {
+ done = true;
}
- } else if (line.startsWith("ms5607 off:")) {
- if (items.length >= 3)
- off = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tcs:")) {
- if (items.length >= 3)
- tcs = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tco:")) {
- if (items.length >= 3)
- tco = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tref:")) {
- if (items.length >= 3)
- tref = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tempsens:")) {
- if (items.length >= 3)
- tempsens = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 crc:")) {
- if (items.length >= 3)
- crc = Integer.parseInt(items[2]);
- } else if (line.startsWith("Altitude:")) {
- return false;
}
- return true;
+ return pres_temp(raw_pres, raw_temp);
+ }
+
+ public AltosMs5607(boolean ms5611) {
+ this.ms5611 = ms5611;
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ public AltosMs5607() {
+ this(false);
+ }
+
+ public AltosMs5607(AltosMs5607 old) {
+ reserved = old.reserved;
+ sens = old.sens;
+ off = old.off;
+ tcs = old.tcs;
+ tco = old.tco;
+ tref = old.tref;
+ tempsens = old.tempsens;
+ crc = old.crc;
+ }
+
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
- AltosMs5607 ms5607 = new AltosMs5607(link, config_data);
+ AltosCalData cal_data = listener.cal_data();
+ AltosMs5607 ms5607 = cal_data.ms5607;
if (ms5607 != null) {
- state.set_ms5607(ms5607);
- return;
+ AltosPresTemp pt = ms5607.pres_temp(link);
+ listener.set_temperature(pt.temp);
+ listener.set_pressure(pt.pres);
}
} catch (TimeoutException te) {
}
}
- public boolean valid_config() {
- return reserved != AltosLib.MISSING &&
- sens != AltosLib.MISSING &&
- off != AltosLib.MISSING &&
- tcs != AltosLib.MISSING &&
- tco != AltosLib.MISSING &&
- tref != AltosLib.MISSING &&
- tempsens != AltosLib.MISSING &&
- crc != AltosLib.MISSING;
- }
-
- public AltosMs5607() {
- raw_pres = AltosLib.MISSING;
- raw_temp = AltosLib.MISSING;
- pa = AltosLib.MISSING;
- cc = AltosLib.MISSING;
- }
-
public AltosMs5607(AltosConfigData config_data) {
- this();
- reserved = config_data.ms5607_reserved;
- sens = config_data.ms5607_sens;
- off = config_data.ms5607_off;
- tcs = config_data.ms5607_tcs;
- tco = config_data.ms5607_tco;
- tref = config_data.ms5607_tref;
- tempsens = config_data.ms5607_tempsens;
- crc = config_data.ms5607_crc;
+ this(config_data.ms5607());
}
public AltosMs5607 (AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException {
this(config_data);
- link.printf("B\n");
- for (;;) {
- String line = link.get_reply_no_dialog(5000);
- if (line == null) {
- throw new TimeoutException();
- }
- if (!parse_line(line)) {
- break;
- }
- }
- convert();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosNoSymbol extends Exception {
public AltosNoSymbol(String name) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosOrient extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosPointDouble {
public double x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosPointInt {
public int x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
}
}
- public static void set_state(AltosState state) {
+ public static void set_state(AltosState state, int serial) {
synchronized(backend) {
- backend.putJson(String.format(statePreferenceFormat, state.serial), new AltosJson(state));
- backend.putInt(statePreferenceLatest, state.serial);
+ backend.putJson(String.format(statePreferenceFormat, serial), new AltosJson(state));
+ backend.putInt(statePreferenceLatest, serial);
flush_preferences();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosPresTemp {
+ double pres = AltosLib.MISSING;
+ double temp = AltosLib.MISSING;
+
+ public AltosPresTemp(double pres, double temp) {
+ this.pres = pres;
+ this.temp = temp;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosPressure extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.*;
import java.text.*;
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosPyroName extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_units) { return v; }
+
+ public String string_value(double v, boolean imperial_units) {
+ return AltosLib.igniter_name((int) v);
+ }
+
+ public String show_units(boolean imperial_units) { return "state"; }
+
+ public String say_units(boolean imperial_units) { return "state"; }
+
+ public int show_fraction(int width, boolean imperial_units) { return 0; }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosQuaternion {
double r; /* real bit */
double x, y, z; /* imaginary bits */
+ /* Multiply by b */
public AltosQuaternion multiply(AltosQuaternion b) {
return new AltosQuaternion(
this.r * b.r - this.x * b.x - this.y * b.y - this.z * b.z,
}
public AltosQuaternion conjugate() {
- return new AltosQuaternion(
- this.r,
- -this.x,
- -this.y,
- -this.z);
+ return new AltosQuaternion(this.r,
+ -this.x,
+ -this.y,
+ -this.z);
}
public double normal() {
- return (this.r * this.r +
- this.x * this.x +
- this.y * this.y +
- this.z * this.z);
+ return Math.sqrt(this.r * this.r +
+ this.x * this.x +
+ this.y * this.y +
+ this.z * this.z);
}
+ /* Scale by a real value */
public AltosQuaternion scale(double b) {
- return new AltosQuaternion(
- this.r * b,
- this.x * b,
- this.y * b,
- this.z * b);
+ return new AltosQuaternion(this.r * b,
+ this.x * b,
+ this.y * b,
+ this.z * b);
}
+ /* Divide by the length to end up with a quaternion of length 1 */
public AltosQuaternion normalize() {
double n = normal();
if (n <= 0)
return this;
- return scale(1/Math.sqrt(n));
+ return scale(1/n);
}
+ /* dot product */
public double dot(AltosQuaternion b) {
return (this.r * b.r +
this.x * b.x +
this.z * b.z);
}
+ /* Rotate 'this' by 'b' */
public AltosQuaternion rotate(AltosQuaternion b) {
return (b.multiply(this)).multiply(b.conjugate());
}
+ /* Given two vectors (this and b), compute a quaternion
+ * representing the rotation between them
+ */
public AltosQuaternion vectors_to_rotation(AltosQuaternion b) {
/*
* The cross product will point orthogonally to the two
return new AltosQuaternion(1, 0, 0, 0);
}
- static public AltosQuaternion half_euler(double x, double y, double z) {
+ static public AltosQuaternion euler(double x, double y, double z) {
+
+ /* Halve the euler angles */
+ x = x / 2.0;
+ y = y / 2.0;
+ z = z / 2.0;
+
double s_x = Math.sin(x), c_x = Math.cos(x);
double s_y = Math.sin(y), c_y = Math.cos(y);
double s_z = Math.sin(z), c_z = Math.cos(z);;
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public interface AltosRecordSet {
+ public AltosCalData cal_data();
+ public void capture_series(AltosDataListener listener);
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosRectangle {
public int x, y, width, height;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
+import java.util.concurrent.*;
/*
* Open an existing telemetry file and replay it in realtime
*/
+class AltosReplay extends AltosDataListener implements Runnable {
+
+ AltosState state;
+ AltosRecordSet record_set;
+ double last_time = AltosLib.MISSING;
+ Semaphore semaphore = new Semaphore(1);;
+ boolean done = false;
+
+ public void set_time(double time) {
+ if (last_time != AltosLib.MISSING) {
+ semaphore.release();
+ double delay = Math.min(time - last_time,10);
+ if (delay > 0) {
+ try {
+ Thread.sleep((int) (delay * 1000));
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ last_time = time;
+ super.set_time(time);
+ state.set_time(time);
+ }
+
+ public void set_state(int state) {
+ super.set_state(state);
+ this.state.set_state(state);
+ }
+
+ public void set_rssi(int rssi, int status) { state.set_rssi(rssi, status); }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { state.set_acceleration(accel); }
+ public void set_pressure(double pa) { state.set_pressure(pa); }
+ public void set_thrust(double N) { state.set_thrust(N); }
+
+ public void set_kalman(double height, double speed, double accel) { state.set_kalman(height, speed, accel); }
+
+ public void set_temperature(double deg_c) { state.set_temperature(deg_c); }
+ public void set_battery_voltage(double volts) { state.set_battery_voltage(volts); }
+
+ public void set_apogee_voltage(double volts) { state.set_apogee_voltage(volts); }
+ public void set_main_voltage(double volts) { state.set_main_voltage(volts); }
+
+ public void set_gps(AltosGPS gps) { state.set_gps(gps); }
+
+ public void set_orient(double orient) { state.set_orient(orient); }
+ public void set_gyro(double roll, double pitch, double yaw) { state.set_gyro(roll, pitch, yaw); }
+ public void set_accel_ground(double along, double across, double through) { state.set_accel_ground(along, across, through); }
+ public void set_accel(double along, double across, double through) { state.set_accel(along, across, through); }
+ public void set_mag(double along, double across, double through) { state.set_mag(along, across, through); }
+ public void set_pyro_voltage(double volts) { state.set_pyro_voltage(volts); }
+ public void set_igniter_voltage(double[] voltage) { state.set_igniter_voltage(voltage); }
+ public void set_pyro_fired(int pyro_mask) { state.set_pyro_fired(pyro_mask); }
+ public void set_companion(AltosCompanion companion) { state.set_companion(companion); }
+
+ public void run () {
+ /* Run the flight */
+ record_set.capture_series(this);
+ /* All done, signal that it's over */
+ done = true;
+ semaphore.release();
+ }
+
+ public AltosReplay(AltosRecordSet record_set) {
+ super(record_set.cal_data());
+ state = new AltosState(record_set.cal_data());
+ this.record_set = record_set;
+ try {
+ semaphore.acquire();
+ } catch (InterruptedException ie) {
+ }
+ }
+}
+
public class AltosReplayReader extends AltosFlightReader {
- Iterator<AltosState> iterator;
- File file;
+ File file;
+ AltosReplay replay;
+ Thread t;
+ int reads;
- public AltosState read() {
- if (iterator.hasNext())
- return iterator.next();
- return null;
+ public AltosCalData cal_data() {
+ return replay.state.cal_data();
}
- public void close (boolean interrupted) {
+ public AltosState read() {
+ switch (reads) {
+ case 0:
+ /* Tell the display that we're in pad mode */
+ replay.state.set_state(AltosLib.ao_flight_pad);
+ break;
+ case 1:
+ t = new Thread(replay);
+ t.start();
+ /* fall through */
+ default:
+ /* Wait for something to change */
+ try {
+ replay.semaphore.acquire();
+ } catch (InterruptedException ie) {
+ }
+ break;
+ }
+ reads++;
+
+ /* When done, let the display know */
+ if (replay.done)
+ return null;
+
+ /* Fake out the received time */
+ replay.state.set_received_time(System.currentTimeMillis());
+ return replay.state;
}
- public void update(AltosState state) throws InterruptedException {
- /* Make it run in realtime after the rocket leaves the pad */
- if (state.state() > AltosLib.ao_flight_pad && state.time_change > 0)
- Thread.sleep((int) (Math.min(state.time_change,10) * 1000));
- state.set_received_time(System.currentTimeMillis());
+ public void close (boolean interrupted) {
}
public File backing_file() { return file; }
- public AltosReplayReader(Iterator<AltosState> in_iterator, File in_file) {
- iterator = in_iterator;
+ public AltosReplayReader(AltosRecordSet record_set, File in_file) {
+ reads = 0;
file = in_file;
name = file.getName();
+ replay = new AltosReplay(record_set);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosRotation extends AltosQuaternion {
private AltosQuaternion rotation;
+ /* Compute pitch angle from vertical by taking the pad
+ * orientation vector and rotating it by the current total
+ * rotation value. That will be a unit vector pointing along
+ * the airframe axis. The Z value will be the cosine of the
+ * angle from vertical.
+ *
+ * rot = ao_rotation * vertical * ao_rotation°
+ * rot = ao_rotation * (0,0,0,1) * ao_rotation°
+ * = ((a.z, a.y, -a.x, a.r) * (a.r, -a.x, -a.y, -a.z)) .z
+ *
+ * = (-a.z * -a.z) + (a.y * -a.y) - (-a.x * -a.x) + (a.r * a.r)
+ * = a.z² - a.y² - a.x² + a.r²
+ *
+ * rot = ao_rotation * (0, 0, 0, -1) * ao_rotation°
+ * = ((-a.z, -a.y, a.x, -a.r) * (a.r, -a.x, -a.y, -a.z)) .z
+ *
+ * = (a.z * -a.z) + (-a.y * -a.y) - (a.x * -a.x) + (-a.r * a.r)
+ * = -a.z² + a.y² + a.x² - a.r²
+ *
+ * tilt = acos(rot) (in radians)
+ */
+
public double tilt() {
double rotz = rotation.z * rotation.z - rotation.y * rotation.y - rotation.x * rotation.x + rotation.r * rotation.r;
return tilt;
}
- public void rotate(double dt, double x, double y, double z) {
- AltosQuaternion rot = AltosQuaternion.half_euler(x * dt / 2.0, y * dt / 2.0, z * dt / 2.0);
+ /* Given euler rotations in three axes, perform a combined rotation using
+ * quaternions
+ */
+ public void rotate(double x, double y, double z) {
+ AltosQuaternion rot = AltosQuaternion.euler(x, y, z);
rotation = rot.multiply(rotation).normalize();
}
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosRotationRate 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 "°/sec";
+ }
+
+ public String say_units(boolean imperial_units) {
+ return "degrees per second";
+ }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ return 1;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link, int version) throws InterruptedException {
try {
AltosSensorEMini sensor_emini = new AltosSensorEMini(link);
+ AltosCalData cal_data = listener.cal_data();
if (sensor_emini == null)
return;
- state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_emini.batt, config_data.serial));
- state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_emini.apogee, config_data.serial));
- state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main, config_data.serial));
+ switch (version) {
+ case 1:
+ listener.set_battery_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.batt, cal_data.serial));
+ listener.set_apogee_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.apogee, cal_data.serial));
+ listener.set_main_voltage(AltosConvert.easy_mini_1_voltage(sensor_emini.main, cal_data.serial));
+ break;
+ case 2:
+ listener.set_battery_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.batt));
+ listener.set_apogee_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.apogee));
+ listener.set_main_voltage(AltosConvert.easy_mini_2_voltage(sensor_emini.main));
+ break;
+ }
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorMega sensor_mega = new AltosSensorMega(link);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5]));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5]));
- double[] ignitor_voltage = new double[4];
+ double[] igniter_voltage = new double[4];
for (int i = 0; i < 4; i++)
- ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]);
- state.set_ignitor_voltage(ignitor_voltage);
+ igniter_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]);
+ listener.set_igniter_voltage(igniter_voltage);
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
}
}
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorMetrum sensor_metrum = new AltosSensorMetrum(link);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m));
} catch (TimeoutException te) {
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
public int tick;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTGPS sensor_tgps = new AltosSensorTGPS(link);
if (sensor_tgps == null)
return;
- state.set_battery_voltage(AltosConvert.tele_gps_voltage(sensor_tgps.batt));
+ listener.set_battery_voltage(AltosConvert.tele_gps_voltage(sensor_tgps.batt));
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
public int drogue;
public int main;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTM sensor_tm = new AltosSensorTM(link);
+ AltosCalData cal_data = listener.cal_data();
if (sensor_tm == null)
return;
- state.set_accel(sensor_tm.accel);
- state.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres));
- state.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt));
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.drogue));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main));
+ listener.set_acceleration(cal_data.acceleration((sensor_tm.accel)));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres));
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt));
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.drogue));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.main));
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTMini2 sensor_tmini = new AltosSensorTMini2(link);
if (sensor_tmini == null)
return;
- state.set_battery_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.apogee));
- state.set_main_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.main));
+ listener.set_battery_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.batt));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.apogee));
+ listener.set_main_voltage(AltosConvert.tele_mini_2_voltage(sensor_tmini.main));
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.util.concurrent.TimeoutException;
public int main;
public int batt;
- static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
try {
AltosSensorTMini3 sensor_tmini = new AltosSensorTMini3(link);
if (sensor_tmini == null)
return;
- state.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(sensor_tmini.batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.apogee));
- state.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.main));
+ listener.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(sensor_tmini.batt));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.apogee));
+ listener.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sensor_tmini.main));
} catch (TimeoutException te) {
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosSpeed extends AltosUnits {
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
-import java.io.*;
-
-public class AltosState implements Cloneable {
+public class AltosState extends AltosDataListener {
public static final int set_position = 1;
public static final int set_gps = 2;
public long received_time;
- public double time;
- public double prev_time;
- public double time_change;
- public int tick;
- private int prev_tick;
- public int boost_tick;
+ public int rssi;
+ public int status;
class AltosValue {
double value;
}
}
- private int state;
- public int flight;
- public int serial;
- public int altitude_32;
- public int receiver_serial;
public boolean landed;
public boolean ascent; /* going up? */
public boolean boost; /* under power */
- public int rssi;
- public int status;
- public int device_type;
- public int config_major;
- public int config_minor;
- public int apogee_delay;
- public int main_deploy;
- public int flight_log_max;
private double pressure_to_altitude(double p) {
if (p == AltosLib.MISSING)
}
public void set_altitude(double new_altitude) {
+ double old_altitude = altitude.value();
+ if (old_altitude != AltosLib.MISSING) {
+ while (old_altitude - new_altitude > 32000)
+ new_altitude += 65536.0;
+ }
altitude.set_measured(new_altitude, time);
}
pressure.set(p, time);
}
+ public void set_thrust(double N) {
+ }
+
public double baro_height() {
double a = altitude();
double g = ground_altitude();
public AltosValue kalman_height, kalman_speed, kalman_acceleration;
public void set_kalman(double height, double speed, double acceleration) {
+ double old_height = kalman_height.value();
+ if (old_height != AltosLib.MISSING) {
+ while (old_height - height > 32000)
+ height += 65536;
+ }
kalman_height.set(height, time);
kalman_speed.set(speed, time);
kalman_acceleration.set(acceleration, time);
public double apogee_voltage;
public double main_voltage;
- public double ignitor_voltage[];
+ public double igniter_voltage[];
public AltosGPS gps;
- public AltosGPS temp_gps;
- public int temp_gps_sat_tick;
public boolean gps_pending;
- public int gps_sequence;
-
- public AltosIMU imu;
- public AltosMag mag;
public static final int MIN_PAD_SAMPLES = 10;
public AltosGreatCircle from_pad;
public double elevation; /* from pad */
+ public double distance; /* distance along ground */
public double range; /* total distance */
public double gps_height;
public int speak_tick;
public double speak_altitude;
- public String callsign;
- public String firmware_version;
-
- public double accel_plus_g;
- public double accel_minus_g;
- public double accel;
public double ground_accel;
- public double ground_accel_avg;
-
- public int log_format;
- public int log_space;
- public String product;
-
- public AltosMs5607 baro;
public AltosCompanion companion;
received_time = System.currentTimeMillis();
time = AltosLib.MISSING;
- time_change = AltosLib.MISSING;
- prev_time = AltosLib.MISSING;
- tick = AltosLib.MISSING;
- prev_tick = AltosLib.MISSING;
- boost_tick = AltosLib.MISSING;
state = AltosLib.ao_flight_invalid;
- flight = AltosLib.MISSING;
landed = false;
boost = false;
rssi = AltosLib.MISSING;
status = 0;
- device_type = AltosLib.MISSING;
- config_major = AltosLib.MISSING;
- config_minor = AltosLib.MISSING;
- apogee_delay = AltosLib.MISSING;
- main_deploy = AltosLib.MISSING;
- flight_log_max = AltosLib.MISSING;
ground_altitude = new AltosCValue();
ground_pressure = new AltosGroundPressure();
pyro_voltage = AltosLib.MISSING;
apogee_voltage = AltosLib.MISSING;
main_voltage = AltosLib.MISSING;
- ignitor_voltage = null;
+ igniter_voltage = null;
kalman_height = new AltosValue();
kalman_speed = new AltosValue();
kalman_acceleration = new AltosValue();
gps = null;
- temp_gps = null;
- temp_gps_sat_tick = 0;
- gps_sequence = 0;
gps_pending = false;
- imu = null;
last_imu_time = AltosLib.MISSING;
rotation = null;
- ground_rotation = null;
-
- mag = null;
- accel_zero_along = AltosLib.MISSING;
- accel_zero_across = AltosLib.MISSING;
- accel_zero_through = AltosLib.MISSING;
accel_ground_along = AltosLib.MISSING;
accel_ground_across = AltosLib.MISSING;
accel_ground_through = AltosLib.MISSING;
- pad_orientation = AltosLib.MISSING;
+ accel_along = AltosLib.MISSING;
+ accel_across = AltosLib.MISSING;
+ accel_through = AltosLib.MISSING;
- gyro_zero_roll = AltosLib.MISSING;
- gyro_zero_pitch = AltosLib.MISSING;
- gyro_zero_yaw = AltosLib.MISSING;
+ gyro_roll = AltosLib.MISSING;
+ gyro_pitch = AltosLib.MISSING;
+ gyro_yaw = AltosLib.MISSING;
+
+ mag_along = AltosLib.MISSING;
+ mag_across = AltosLib.MISSING;
+ mag_through = AltosLib.MISSING;
set_npad(0);
ngps = 0;
from_pad = null;
elevation = AltosLib.MISSING;
+ distance = AltosLib.MISSING;
range = AltosLib.MISSING;
gps_height = AltosLib.MISSING;
speak_tick = AltosLib.MISSING;
speak_altitude = AltosLib.MISSING;
- callsign = null;
- firmware_version = null;
-
- accel_plus_g = AltosLib.MISSING;
- accel_minus_g = AltosLib.MISSING;
- accel = AltosLib.MISSING;
-
ground_accel = AltosLib.MISSING;
- ground_accel_avg = AltosLib.MISSING;
-
- log_format = AltosLib.MISSING;
- log_space = AltosLib.MISSING;
- product = null;
- serial = AltosLib.MISSING;
- receiver_serial = AltosLib.MISSING;
- altitude_32 = AltosLib.MISSING;
- baro = null;
companion = null;
pyro_fired = 0;
}
void finish_update() {
- prev_tick = tick;
-
ground_altitude.finish_update();
altitude.finish_update();
pressure.finish_update();
kalman_acceleration.finish_update();
}
- void copy(AltosState old) {
-
- if (old == null) {
- init();
- return;
- }
-
- received_time = old.received_time;
- time = old.time;
- time_change = old.time_change;
- prev_time = old.time;
-
- tick = old.tick;
- prev_tick = old.tick;
- boost_tick = old.boost_tick;
-
- state = old.state;
- flight = old.flight;
- landed = old.landed;
- ascent = old.ascent;
- boost = old.boost;
- rssi = old.rssi;
- status = old.status;
- device_type = old.device_type;
- config_major = old.config_major;
- config_minor = old.config_minor;
- apogee_delay = old.apogee_delay;
- main_deploy = old.main_deploy;
- flight_log_max = old.flight_log_max;
-
- set = 0;
-
- ground_pressure.copy(old.ground_pressure);
- ground_altitude.copy(old.ground_altitude);
- altitude.copy(old.altitude);
- pressure.copy(old.pressure);
- speed.copy(old.speed);
- acceleration.copy(old.acceleration);
- orient.copy(old.orient);
-
- battery_voltage = old.battery_voltage;
- pyro_voltage = old.pyro_voltage;
- temperature = old.temperature;
- apogee_voltage = old.apogee_voltage;
- main_voltage = old.main_voltage;
- ignitor_voltage = old.ignitor_voltage;
-
- kalman_height.copy(old.kalman_height);
- kalman_speed.copy(old.kalman_speed);
- kalman_acceleration.copy(old.kalman_acceleration);
-
- if (old.gps != null)
- gps = old.gps.clone();
- else
- gps = null;
- if (old.temp_gps != null)
- temp_gps = old.temp_gps.clone();
- else
- temp_gps = null;
- temp_gps_sat_tick = old.temp_gps_sat_tick;
- gps_sequence = old.gps_sequence;
- gps_pending = old.gps_pending;
-
- if (old.imu != null)
- imu = old.imu.clone();
- else
- imu = null;
- last_imu_time = old.last_imu_time;
-
- if (old.rotation != null)
- rotation = new AltosRotation (old.rotation);
-
- if (old.ground_rotation != null) {
- ground_rotation = new AltosRotation(old.ground_rotation);
- }
-
- accel_zero_along = old.accel_zero_along;
- accel_zero_across = old.accel_zero_across;
- accel_zero_through = old.accel_zero_through;
-
- accel_ground_along = old.accel_ground_along;
- accel_ground_across = old.accel_ground_across;
- accel_ground_through = old.accel_ground_through;
- pad_orientation = old.pad_orientation;
-
- gyro_zero_roll = old.gyro_zero_roll;
- gyro_zero_pitch = old.gyro_zero_pitch;
- gyro_zero_yaw = old.gyro_zero_yaw;
-
- if (old.mag != null)
- mag = old.mag.clone();
- else
- mag = null;
-
- npad = old.npad;
- gps_waiting = old.gps_waiting;
- gps_ready = old.gps_ready;
- ngps = old.ngps;
-
- if (old.from_pad != null)
- from_pad = old.from_pad.clone();
- else
- from_pad = null;
-
- elevation = old.elevation;
- range = old.range;
-
- gps_height = old.gps_height;
-
- gps_altitude.copy(old.gps_altitude);
- gps_ground_altitude.copy(old.gps_ground_altitude);
- gps_ground_speed.copy(old.gps_ground_speed);
- gps_ascent_rate.copy(old.gps_ascent_rate);
- gps_course.copy(old.gps_course);
- gps_speed.copy(old.gps_speed);
-
- pad_lat = old.pad_lat;
- pad_lon = old.pad_lon;
- pad_alt = old.pad_alt;
-
- speak_tick = old.speak_tick;
- speak_altitude = old.speak_altitude;
-
- callsign = old.callsign;
- firmware_version = old.firmware_version;
-
- accel_plus_g = old.accel_plus_g;
- accel_minus_g = old.accel_minus_g;
- accel = old.accel;
- ground_accel = old.ground_accel;
- ground_accel_avg = old.ground_accel_avg;
-
- log_format = old.log_format;
- log_space = old.log_space;
- product = old.product;
- serial = old.serial;
- receiver_serial = old.receiver_serial;
- altitude_32 = old.altitude_32;
-
- baro = old.baro;
- companion = old.companion;
-
- pyro_fired = old.pyro_fired;
- }
-
void update_time() {
}
void update_gps() {
elevation = AltosLib.MISSING;
+ distance = AltosLib.MISSING;
range = AltosLib.MISSING;
if (gps == null)
h = 0;
from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h);
elevation = from_pad.elevation;
+ distance = from_pad.distance;
range = from_pad.range;
}
}
- public void set_tick(int new_tick) {
- if (new_tick != AltosLib.MISSING) {
- if (prev_tick != AltosLib.MISSING) {
- while (new_tick < prev_tick - 1000) {
- new_tick += 65536;
- }
- }
- tick = new_tick;
- time = tick / 100.0;
- time_change = time - prev_time;
- }
- }
-
- public void set_boost_tick(int boost_tick) {
- if (boost_tick != AltosLib.MISSING)
- this.boost_tick = boost_tick;
- }
-
public String state_name() {
return AltosLib.state_name(state);
}
- public void set_product(String product) {
- this.product = product;
- }
-
public void set_state(int state) {
if (state != AltosLib.ao_flight_invalid) {
this.state = state;
return state;
}
- public void set_device_type(int device_type) {
- this.device_type = device_type;
- switch (device_type) {
- case AltosLib.product_telegps:
- this.state = AltosLib.ao_flight_stateless;
- break;
- }
- }
-
- public void set_log_format(int log_format) {
- this.log_format = log_format;
- switch (log_format) {
- case AltosLib.AO_LOG_FORMAT_TELEGPS:
- this.state = AltosLib.ao_flight_stateless;
- break;
- }
- }
-
- public void set_log_space(int log_space) {
- this.log_space = log_space;
- }
-
- public void set_flight_params(int apogee_delay, int main_deploy) {
- this.apogee_delay = apogee_delay;
- this.main_deploy = main_deploy;
- }
-
- public void set_config(int major, int minor, int flight_log_max) {
- config_major = major;
- config_minor = minor;
- this.flight_log_max = flight_log_max;
- }
-
- public void set_callsign(String callsign) {
- this.callsign = callsign;
- }
-
- public void set_firmware_version(String version) {
- 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;
init();
- boost_tick = bt;
- receiver_serial = rs;
- }
-
- public void set_flight(int flight) {
-
- /* When the flight changes, reset the state */
- if (flight != AltosLib.MISSING) {
- if (this.flight != AltosLib.MISSING &&
- this.flight != flight) {
- re_init();
- }
- this.flight = flight;
- }
- }
-
- public void set_serial(int serial) {
- /* When the serial changes, reset the state */
- if (serial != AltosLib.MISSING) {
- if (this.serial != AltosLib.MISSING &&
- this.serial != serial) {
- re_init();
- }
- this.serial = serial;
- }
- }
-
- public void set_receiver_serial(int serial) {
- if (serial != AltosLib.MISSING)
- 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() {
received_time = ms;
}
- public void set_gps(AltosGPS gps, int sequence) {
+ public void set_gps(AltosGPS gps) {
if (gps != null) {
- this.gps = gps.clone();
- gps_sequence = sequence;
+ this.gps = gps;
update_gps();
set |= set_gps;
}
}
-
- public double accel_zero_along;
- public double accel_zero_across;
- public double accel_zero_through;
-
public AltosRotation rotation;
- public AltosRotation ground_rotation;
-
- public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
- if (zero_along != AltosLib.MISSING) {
- accel_zero_along = zero_along;
- accel_zero_across = zero_across;
- accel_zero_through = zero_through;
- }
- }
-
- public int pad_orientation;
public double accel_ground_along, accel_ground_across, accel_ground_through;
void update_pad_rotation() {
- if (pad_orientation != AltosLib.MISSING && accel_ground_along != AltosLib.MISSING) {
- rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - accel_zero_across),
- AltosIMU.convert_accel(accel_ground_through - accel_zero_through),
- AltosIMU.convert_accel(accel_ground_along - accel_zero_along),
- pad_orientation);
- ground_rotation = rotation;
+ if (cal_data().pad_orientation != AltosLib.MISSING && accel_ground_along != AltosLib.MISSING) {
+ rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
+ AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
+ AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
+ cal_data().pad_orientation);
orient.set_computed(rotation.tilt(), time);
}
}
update_pad_rotation();
}
- public void set_pad_orientation(int pad_orientation) {
- this.pad_orientation = pad_orientation;
- update_pad_rotation();
- }
-
- public double gyro_zero_roll;
- public double gyro_zero_pitch;
- public double gyro_zero_yaw;
-
- public void set_gyro_zero(double roll, double pitch, double yaw) {
- if (roll != AltosLib.MISSING) {
- gyro_zero_roll = roll;
- gyro_zero_pitch = pitch;
- gyro_zero_yaw = yaw;
- }
- }
-
public double last_imu_time;
- private double radians(double degrees) {
- if (degrees == AltosLib.MISSING)
- return AltosLib.MISSING;
- return degrees * Math.PI / 180.0;
- }
-
private void update_orient() {
if (last_imu_time != AltosLib.MISSING) {
double t = time - last_imu_time;
- double pitch = radians(gyro_pitch());
- double yaw = radians(gyro_yaw());
- double roll = radians(gyro_roll());
+ if (t > 0 && gyro_pitch != AltosLib.MISSING && rotation != null) {
+ double pitch = AltosConvert.degrees_to_radians(gyro_pitch) * t;
+ double yaw = AltosConvert.degrees_to_radians(gyro_yaw) * t;
+ double roll = AltosConvert.degrees_to_radians(gyro_roll) * t;
- if (t > 0 & pitch != AltosLib.MISSING && rotation != null) {
- rotation.rotate(t, pitch, yaw, roll);
+ rotation.rotate(pitch, yaw, roll);
orient.set_computed(rotation.tilt(), time);
}
}
last_imu_time = time;
}
- public void set_imu(AltosIMU imu) {
- if (imu != null)
- imu = imu.clone();
- this.imu = imu;
+ private double gyro_roll, gyro_pitch, gyro_yaw;
+
+ public void set_gyro(double roll, double pitch, double yaw) {
+ gyro_roll = roll;
+ gyro_pitch = pitch;
+ gyro_yaw = yaw;
update_orient();
}
- private double gyro_zero_overflow(double first) {
- double v = first / 128.0;
- if (v < 0)
- v = Math.ceil(v);
- else
- v = Math.floor(v);
- return v * 128.0;
- }
+ private double accel_along, accel_across, accel_through;
- public void check_imu_wrap(AltosIMU imu) {
- if (this.imu == null) {
- gyro_zero_roll += gyro_zero_overflow(imu.gyro_roll);
- gyro_zero_pitch += gyro_zero_overflow(imu.gyro_pitch);
- gyro_zero_yaw += gyro_zero_overflow(imu.gyro_yaw);
- }
+ public void set_accel(double along, double across, double through) {
+ accel_along = along;
+ accel_across = across;
+ accel_through = through;
+ update_orient();
}
public double accel_along() {
- if (imu != null && accel_zero_along != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_along - accel_zero_along);
- return AltosLib.MISSING;
+ return accel_along;
}
public double accel_across() {
- if (imu != null && accel_zero_across != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_across - accel_zero_across);
- return AltosLib.MISSING;
+ return accel_across;
}
public double accel_through() {
- if (imu != null && accel_zero_through != AltosLib.MISSING)
- return AltosIMU.convert_accel(imu.accel_through - accel_zero_through);
- return AltosLib.MISSING;
+ return accel_through;
}
public double gyro_roll() {
- if (imu != null && gyro_zero_roll != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_roll - gyro_zero_roll);
- }
- return AltosLib.MISSING;
+ return gyro_roll;
}
public double gyro_pitch() {
- if (imu != null && gyro_zero_pitch != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_pitch - gyro_zero_pitch);
- }
- return AltosLib.MISSING;
+ return gyro_pitch;
}
public double gyro_yaw() {
- if (imu != null && gyro_zero_yaw != AltosLib.MISSING) {
- return AltosIMU.convert_gyro(imu.gyro_yaw - gyro_zero_yaw);
- }
- return AltosLib.MISSING;
+ return gyro_yaw;
}
- public void set_mag(AltosMag mag) {
- this.mag = mag.clone();
+ private double mag_along, mag_across, mag_through;
+
+ public void set_mag(double along, double across, double through) {
+ mag_along = along;
+ mag_across = across;
+ mag_through = through;
}
public double mag_along() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.along);
- return AltosLib.MISSING;
+ return mag_along;
}
public double mag_across() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.across);
- return AltosLib.MISSING;
+ return mag_across;
}
public double mag_through() {
- if (mag != null)
- return AltosMag.convert_gauss(mag.through);
- return AltosLib.MISSING;
- }
-
- public AltosMs5607 make_baro() {
- if (baro == null)
- baro = new AltosMs5607();
- return baro;
- }
-
- public void set_ms5607(AltosMs5607 ms5607) {
- baro = ms5607;
-
- if (baro != null && baro.pa != AltosLib.MISSING && baro.cc != AltosLib.MISSING) {
- set_pressure(baro.pa);
- set_temperature(baro.cc / 100.0);
- }
- }
-
- public void set_ms5607(int pres, int temp) {
- if (baro != null) {
- baro.set(pres, temp);
-
- set_pressure(baro.pa);
- set_temperature(baro.cc / 100.0);
- }
+ return mag_through;
}
public void set_companion(AltosCompanion companion) {
this.companion = companion;
}
- void update_accel() {
- if (accel == AltosLib.MISSING)
- return;
- if (accel_plus_g == AltosLib.MISSING)
- return;
- if (accel_minus_g == AltosLib.MISSING)
- return;
-
- double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0;
- double counts_per_mss = counts_per_g / 9.80665;
- acceleration.set_measured((accel_plus_g - accel) / counts_per_mss, time);
- }
-
- public void set_accel_g(double accel_plus_g, double accel_minus_g) {
- if (accel_plus_g != AltosLib.MISSING) {
- this.accel_plus_g = accel_plus_g;
- this.accel_minus_g = accel_minus_g;
- update_accel();
- }
- }
-
- public void set_ground_accel(double ground_accel) {
- if (ground_accel != AltosLib.MISSING)
- this.ground_accel = ground_accel;
- }
-
- public void set_accel(double accel) {
- if (accel != AltosLib.MISSING) {
- this.accel = accel;
- if (state == AltosLib.ao_flight_pad) {
- if (ground_accel_avg == AltosLib.MISSING)
- ground_accel_avg = accel;
- else
- ground_accel_avg = (ground_accel_avg * 7 + accel) / 8;
- }
+ public void set_acceleration(double acceleration) {
+ if (acceleration != AltosLib.MISSING) {
+ this.acceleration.set_measured(acceleration, time);
+ set |= set_data;
}
- update_accel();
}
public void set_temperature(double temperature) {
}
}
- public void set_ignitor_voltage(double[] voltage) {
- this.ignitor_voltage = voltage;
+ public void set_igniter_voltage(double[] voltage) {
+ this.igniter_voltage = voltage;
}
public void set_pyro_fired(int fired) {
this.pyro_fired = fired;
}
- public double time_since_boost() {
- if (tick == AltosLib.MISSING)
- return 0.0;
-
- if (boost_tick == AltosLib.MISSING)
- return tick / 100.0;
- return (tick - boost_tick) / 100.0;
- }
-
- public boolean valid() {
- return tick != AltosLib.MISSING && serial != AltosLib.MISSING;
- }
-
- public AltosGPS make_temp_gps(boolean sats) {
- if (temp_gps == null) {
- temp_gps = new AltosGPS(gps);
- }
- gps_pending = true;
- if (sats) {
- if (tick != temp_gps_sat_tick)
- temp_gps.cc_gps_sat = null;
- temp_gps_sat_tick = tick;
- }
- return temp_gps;
- }
-
- public void set_temp_gps() {
- set_gps(temp_gps, gps_sequence + 1);
- gps_pending = false;
- temp_gps = null;
- }
-
- public void set_config_data(AltosConfigData config_data) {
- if (config_data.callsign != null)
- set_callsign(config_data.callsign);
- if (config_data.accel_cal_plus != AltosLib.MISSING &&
- config_data.accel_cal_minus != AltosLib.MISSING)
- set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
- if (config_data.product != null)
- set_product(config_data.product);
- if (config_data.log_format != AltosLib.MISSING)
- set_log_format(config_data.log_format);
- if (config_data.serial != AltosLib.MISSING)
- set_serial(config_data.serial);
- AltosMs5607 ms5607 = new AltosMs5607(config_data);
- if (ms5607.valid_config())
- set_ms5607(ms5607);
- }
-
- public AltosState clone() {
- AltosState s = new AltosState();
- s.copy(this);
-
- /* Code to test state save/restore. Enable only for that purpose
- */
- if (false) {
- AltosJson json = new AltosJson(this);
- String onetrip = json.toPrettyString();
- AltosJson back = AltosJson.fromString(onetrip);
- AltosState tripstate = (AltosState) back.make(this.getClass());
- AltosJson tripjson = new AltosJson(tripstate);
- String twotrip = tripjson.toPrettyString();
-
- if (!onetrip.equals(twotrip)) {
- try {
- FileWriter one_file = new FileWriter("one.json", true);
- one_file.write(onetrip);
- one_file.flush();
- FileWriter two_file = new FileWriter("two.json", true);
- two_file.write(twotrip);
- two_file.flush();
- } catch (Exception e) {
- }
- System.out.printf("json error\n");
- System.exit(1);
- }
- }
- return s;
+ public AltosState() {
+ Thread.dumpStack();
+ init();
}
- public AltosState () {
+ public AltosState (AltosCalData cal_data) {
+ super(cal_data);
init();
}
}
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altoslib_11;
-
-import java.io.*;
-import java.util.*;
-
-public abstract class AltosStateIterable implements Iterable<AltosState> {
-
- public void write_comments (PrintStream out) {
- }
-
- public abstract void write(PrintStream out);
-
- public static AltosStateIterable iterable(File file) {
- try {
- if (file.getName().endsWith("telem"))
- return new AltosTelemetryFile(new FileInputStream(file));
- else
- return new AltosEepromFile(new FileReader(file));
- } catch (Exception e) {
- return null;
- }
- }
-}
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosStateName extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_units) { return v; }
+
+ public String string_value(double v, boolean imperial_units) {
+ return AltosLib.state_name((int) v);
+ }
+
+ public String show_units(boolean imperial_units) { return "state"; }
+
+ public String say_units(boolean imperial_units) { return "state"; }
+
+ public int show_fraction(int width, boolean imperial_units) { return 0; }
+}
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altoslib_11;
-
-public interface AltosStateUpdate {
- public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct;
-}
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+import java.io.*;
+
+public class AltosStringInputStream extends InputStream {
+
+ String s;
+ int at;
+ int mark;
+
+ public int available() {
+ return s.length() - at;
+ }
+
+ public void mark(int read_limit) {
+ mark = at;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public int read() {
+ if (at == s.length())
+ return -1;
+ return (int) s.charAt(at++);
+ }
+
+ public void reset() {
+ at = mark;
+ }
+
+ public long skip(long n) throws IOException {
+ if (n < 0) n = 0;
+
+ if (at + n > s.length())
+ n = s.length() - at;
+ at += n;
+ return n;
+ }
+
+ public AltosStringInputStream(String s) {
+ this.s = s;
+ this.at = 0;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
* Telemetry data contents
*/
-public abstract class AltosTelemetry implements AltosStateUpdate {
+public abstract class AltosTelemetry implements AltosDataProvider {
+ int[] bytes;
/* All telemetry packets have these fields */
- public int tick;
- public int serial;
- public int rssi;
- public int status;
+ public int rssi() { return AltosConvert.telem_to_rssi(AltosLib.int8(bytes, bytes.length - 3)); }
+ public int status() { return AltosLib.uint8(bytes, bytes.length - 2); }
+
+ /* All telemetry packets report these fields in some form */
+ public abstract int serial();
+ public abstract int tick();
/* Mark when we received the packet */
long received_time;
return sum == bytes[bytes.length - 1];
}
- public void update_state(AltosState state) {
- state.set_serial(serial);
- if (state.state() == AltosLib.ao_flight_invalid)
- state.set_state(AltosLib.ao_flight_startup);
- state.set_tick(tick);
- state.set_rssi(rssi, status);
- state.set_received_time(received_time);
+ public void provide_data(AltosDataListener listener) {
+ listener.set_serial(serial());
+ if (listener.state == AltosLib.ao_flight_invalid)
+ listener.set_state(AltosLib.ao_flight_startup);
+ listener.set_tick(tick());
+ listener.set_rssi(rssi(), status());
+ listener.set_received_time(received_time);
}
final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7);
if (!cksum(bytes))
throw new ParseException(String.format("invalid line \"%s\"", hex), 0);
- int rssi = AltosLib.int8(bytes, bytes.length - 3) / 2 - 74;
- int status = AltosLib.uint8(bytes, bytes.length - 2);
-
- if ((status & PKT_APPEND_STATUS_1_CRC_OK) == 0)
- throw new AltosCRCException(rssi);
-
/* length, data ..., rssi, status, checksum -- 4 bytes extra */
switch (bytes.length) {
case AltosLib.ao_telemetry_standard_len + 4:
default:
throw new ParseException(String.format("Invalid packet length %d", bytes.length), 0);
}
- if (telem != null) {
- telem.received_time = System.currentTimeMillis();
- telem.rssi = rssi;
- telem.status = status;
- }
return telem;
}
- public static int extend_height(AltosState state, int height_16) {
- double compare_height;
- int height = height_16;
-
- 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);
+ public AltosTelemetry() {
+ this.received_time = System.currentTimeMillis();
+ }
- 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;
- }
- return height;
+ public AltosTelemetry(int[] bytes) throws AltosCRCException {
+ this();
+ this.bytes = bytes;
+ if ((status() & PKT_APPEND_STATUS_1_CRC_OK) == 0)
+ throw new AltosCRCException(rssi());
}
public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException {
throw new AltosCRCException(AltosParse.parse_int(word[i++]));
}
- AltosTelemetry telem;
+ AltosTelemetry telem = null;
if (word[i].equals("TELEM")) {
telem = parse_hex(word[i+1]);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryCompanion extends AltosTelemetryStandard {
- AltosCompanion companion;
-
- static final public int max_channels = 12;
-
- public AltosTelemetryCompanion(int[] bytes) {
- super(bytes);
+ AltosCompanion companion() {
int channels = uint8(7);
if (channels > max_channels)
channels = max_channels;
- companion = new AltosCompanion(channels);
+ AltosCompanion companion = new AltosCompanion(channels);
- companion.tick = tick;
+ companion.tick = tick();
companion.board_id = uint8(5);
companion.update_period = uint8(6);
for (int i = 0; i < channels; i++)
companion.companion_data[i] = uint16(8 + i * 2);
}
+ return companion;
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ static final public int max_channels = 12;
+
+ public AltosTelemetryCompanion(int[] bytes) throws AltosCRCException {
+ super(bytes);
+ }
- state.set_companion(companion);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+ listener.set_companion(companion());
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
- int device_type;
- int flight;
- int config_major;
- int config_minor;
- int apogee_delay;
- int main_deploy;
- int v_batt;
- int flight_log_max;
- String callsign;
- String version;
-
- public AltosTelemetryConfiguration(int[] bytes) {
- super(bytes);
+ int device_type() { return uint8(5); }
+ int flight() { return uint16(6); }
+ int config_major() { return uint8(8); }
+ int config_minor() { return uint8(9); }
+ int apogee_delay() { return uint16(10); }
+ int main_deploy() { return uint16(12); }
+ int v_batt() { return uint16(10); }
+ int flight_log_max() { return uint16(14); }
+ String callsign() { return string(16, 8); }
+ String version() { return string(24, 8); }
- device_type = uint8(5);
- flight = uint16(6);
- config_major = uint8(8);
- config_minor = uint8(9);
- v_batt = uint16(10);
- apogee_delay = uint16(10);
- main_deploy = uint16(12);
- flight_log_max = uint16(14);
- callsign = string(16, 8);
- version = string(24, 8);
+ public AltosTelemetryConfiguration(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
- state.set_device_type(device_type);
- state.set_flight(flight);
- state.set_config(config_major, config_minor, flight_log_max);
- if (device_type == AltosLib.product_telegps)
- state.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt));
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ AltosCalData cal_data = listener.cal_data();
+
+ cal_data.set_device_type(device_type());
+ cal_data.set_flight(flight());
+ cal_data.set_config(config_major(), config_minor(), flight_log_max());
+ if (device_type() == AltosLib.product_telegps)
+ listener.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt()));
else
- state.set_flight_params(apogee_delay, main_deploy);
+ cal_data.set_flight_params(apogee_delay() / 100.0, main_deploy());
- state.set_callsign(callsign);
- state.set_firmware_version(version);
+ cal_data.set_callsign(callsign());
+ cal_data.set_firmware_version(version());
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
import java.text.*;
-class AltosTelemetryIterator implements Iterator<AltosState> {
- AltosState state;
- Iterator<AltosTelemetry> telems;
- AltosTelemetry next;
- boolean seen;
-
- public boolean hasNext() {
- return !seen || telems.hasNext();
- }
-
- public AltosState next() {
- if (seen) {
- AltosState n = state.clone();
- AltosTelemetry t = telems.next();
-
- t.update_state(n);
- state = n;
- }
- seen = true;
- return state;
+class AltosTelemetryNullListener extends AltosDataListener {
+ public void set_rssi(int rssi, int status) { }
+ public void set_received_time(long received_time) { }
+
+ public void set_acceleration(double accel) { }
+ public void set_pressure(double pa) { }
+ public void set_thrust(double N) { }
+
+ public void set_kalman(double height, double speed, double accel) { }
+
+ public void set_temperature(double deg_c) { }
+ public void set_battery_voltage(double volts) { }
+
+ public void set_apogee_voltage(double volts) { }
+ public void set_main_voltage(double volts) { }
+
+ public void set_gps(AltosGPS gps) { }
+
+ public void set_orient(double orient) { }
+ public void set_gyro(double roll, double pitch, double yaw) { }
+ public void set_accel_ground(double along, double across, double through) { }
+ public void set_accel(double along, double across, double through) { }
+ public void set_mag(double along, double across, double through) { }
+ public void set_pyro_voltage(double volts) { }
+ public void set_igniter_voltage(double[] voltage) { }
+ public void set_pyro_fired(int pyro_mask) { }
+ public void set_companion(AltosCompanion companion) { }
+
+ public boolean cal_data_complete() {
+ /* All telemetry packets */
+ AltosCalData cal_data = cal_data();
+
+ if (cal_data.serial == AltosLib.MISSING)
+ return false;
+
+ if (cal_data.boost_tick == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetryConfiguration:
+ *
+ * device_type, flight, config version, log max,
+ * flight params, callsign and version
+ */
+ if (cal_data.device_type == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetrySensor or TelemetryMegaData:
+ *
+ * ground_accel, accel+/-, ground pressure
+ */
+ if (cal_data.ground_pressure == AltosLib.MISSING)
+ return false;
+
+ /*
+ * TelemetryLocation
+ */
+ if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_pad == null)
+ return false;
+
+ return true;
}
- public void remove () {
- }
-
- public AltosTelemetryIterator(AltosState start, Iterator<AltosTelemetry> telems) {
- this.state = start;
- this.telems = telems;
- this.seen = false;
+ public AltosTelemetryNullListener(AltosCalData cal_data) {
+ super(cal_data);
}
}
-public class AltosTelemetryFile extends AltosStateIterable {
+public class AltosTelemetryFile implements AltosRecordSet {
AltosTelemetryIterable telems;
- AltosState start;
+ AltosCalData cal_data;
public void write_comments(PrintStream out) {
}
public void write(PrintStream out) {
-
}
- public AltosTelemetryFile(FileInputStream input) {
- telems = new AltosTelemetryIterable(input);
- start = new AltosState();
-
- /* Find boost tick */
- AltosState state = start.clone();
+ /* Construct cal data by walking through the telemetry data until we've found everything available */
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ cal_data = new AltosCalData();
+ AltosTelemetryNullListener l = new AltosTelemetryNullListener(cal_data);
- for (AltosTelemetry telem : telems) {
- telem.update_state(state);
- state.finish_update();
- if (state.state() != AltosLib.ao_flight_invalid && state.state() >= AltosLib.ao_flight_boost) {
- start.set_boost_tick(state.tick);
- break;
+ for (AltosTelemetry telem : telems) {
+ telem.provide_data(l);
+ if (l.cal_data_complete())
+ break;
}
}
+ return cal_data;
}
- public Iterator<AltosState> iterator() {
- AltosState state = start.clone();
- Iterator<AltosTelemetry> i = telems.iterator();
+ public void capture_series(AltosDataListener listener) {
+ AltosCalData cal_data = cal_data();
+
+ cal_data.reset();
+ for (AltosTelemetry telem : telems) {
+ int tick = telem.tick();
+ cal_data.set_tick(tick);
- while (i.hasNext() && !state.valid()) {
- AltosTelemetry t = i.next();
- t.update_state(state);
- state.finish_update();
+ /* Try to pick up at least one pre-boost value */
+ if (cal_data.time() >= -2)
+ telem.provide_data(listener);
+ if (listener.state == AltosLib.ao_flight_landed)
+ break;
}
- return new AltosTelemetryIterator(state, i);
+ listener.finish();
+ }
+
+ public AltosTelemetryFile(FileInputStream input) throws IOException {
+ telems = new AltosTelemetryIterable(input);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.io.*;
import java.util.*;
int index;
public void add (AltosTelemetry telem) {
- int t = telem.tick;
+ int t = telem.tick();
if (!telems.isEmpty()) {
while (t < tick - 1000)
t += 65536;
return new AltosTelemetryOrderedIterator(telems);
}
- public AltosTelemetryIterable (FileInputStream input) {
+ public AltosTelemetryIterable (FileInputStream input) throws IOException {
telems = new TreeSet<AltosTelemetryOrdered> ();
tick = 0;
index = 0;
- try {
- for (;;) {
- String line = AltosLib.gets(input);
- if (line == null) {
+ for (;;) {
+ String line = AltosLib.gets(input);
+ if (line == null) {
+ break;
+ }
+ try {
+ AltosTelemetry telem = AltosTelemetry.parse(line);
+ if (telem == null)
break;
- }
- try {
- AltosTelemetry telem = AltosTelemetry.parse(line);
- if (telem == null)
- break;
- add(telem);
- } catch (ParseException pe) {
- System.out.printf("parse exception %s\n", pe.getMessage());
- } catch (AltosCRCException ce) {
- }
+ add(telem);
+ } catch (ParseException pe) {
+ System.out.printf("parse exception %s\n", pe.getMessage());
+ } catch (AltosCRCException ce) {
}
- } catch (IOException io) {
- System.out.printf("io exception\n");
}
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
final static String AO_TELEM_SAT_SVID = "s_v";
final static String AO_TELEM_SAT_C_N_0 = "s_c";
+ public int tick;
+ public int serial;
+ public int rssi;
+ public int status;
+
+ public int tick() { return tick; }
+ public int serial() { return serial; }
+
+ public int rssi() { return rssi; }
+ public int status() { return status; }
+
public int version;
public String callsign;
public int flight;
flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING);
rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING);
state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid"));
- tick = map.get_int(AO_TELEM_TICK, 0);
/* raw sensor values */
accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING);
* Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that
*/
- int[] bytes;
int adjust;
/*
static final int AO_GPS_DATE_VALID = (1 << 6);
static final int AO_GPS_COURSE_VALID = (1 << 7);
- public AltosTelemetryLegacy(int[] in_bytes) {
- bytes = in_bytes;
+ public AltosTelemetryLegacy(int[] in_bytes) throws AltosCRCException {
+ super(in_bytes);
+
version = 4;
adjust = 0;
} else
serial = uint16(0);
+ rssi = super.rssi();
callsign = string(62, 8);
flight = uint16(2);
state = uint8(4);
}
}
- public void update_state(AltosState state) {
- state.set_tick(tick);
- state.set_state(this.state);
- state.set_flight(flight);
- state.set_serial(serial);
- state.set_rssi(rssi, status);
+ public void provide_data(AltosDataListener listener) {
+ listener.set_serial(serial);
+ listener.set_tick(tick);
+ listener.set_state(this.state);
+ listener.set_flight(flight);
+ listener.set_rssi(rssi, status);
+
+ listener.set_pressure(AltosConvert.barometer_to_pressure(pres));
+
+ AltosCalData cal_data = listener.cal_data();
- state.set_pressure(AltosConvert.barometer_to_pressure(pres));
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_accel(accel);
+ cal_data.set_accel_plus_minus(accel_plus_g, accel_minus_g);
+ listener.set_acceleration(cal_data.acceleration(accel));
if (kalman_height != AltosLib.MISSING)
- state.set_kalman(kalman_height, kalman_speed, kalman_acceleration);
- state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main));
+ listener.set_kalman(kalman_height, kalman_speed, kalman_acceleration);
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(temp));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(apogee));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(main));
if (gps != null)
- state.set_gps(gps, gps_sequence);
+ listener.set_gps(gps);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryLocation extends AltosTelemetryStandard {
- int flags;
- int altitude;
- int latitude;
- int longitude;
- int year;
- int month;
- int day;
- int hour;
- int minute;
- int second;
- int pdop;
- int hdop;
- int vdop;
- int mode;
- int ground_speed;
- int climb_rate;
- int course;
+ int flags() { return uint8(5); }
+ int altitude() {
+ if ((mode() & AO_GPS_MODE_ALTITUDE_24) != 0)
+ return (int8(31) << 16) | uint16(6);
+ else
+ return int16(6);
+ }
+ int latitude() { return uint32(8); }
+ int longitude() { return uint32(12); }
+ int year() { return uint8(16); }
+ int month() { return uint8(17); }
+ int day() { return uint8(18); }
+ int hour() { return uint8(19); }
+ int minute() { return uint8(20); }
+ int second() { return uint8(21); }
+ int pdop() { return uint8(22); }
+ int hdop() { return uint8(23); }
+ int vdop() { return uint8(24); }
+ int mode() { return uint8(25); }
+ int ground_speed() { return uint16(26); }
+ int climb_rate() { return int16(28); }
+ int course() { return uint8(30); }
public static final int AO_GPS_MODE_ALTITUDE_24 = (1 << 0); /* Reports 24-bits of altitude */
- public AltosTelemetryLocation(int[] bytes) {
+ public AltosTelemetryLocation(int[] bytes) throws AltosCRCException {
super(bytes);
+ }
- flags = uint8(5);
- latitude = uint32(8);
- longitude = uint32(12);
- year = uint8(16);
- month = uint8(17);
- day = uint8(18);
- hour = uint8(19);
- minute = uint8(20);
- second = uint8(21);
- pdop = uint8(22);
- hdop = uint8(23);
- vdop = uint8(24);
- mode = uint8(25);
- ground_speed = uint16(26);
- climb_rate = int16(28);
- course = uint8(30);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- if ((mode & AO_GPS_MODE_ALTITUDE_24) != 0) {
- altitude = (int8(31) << 16) | uint16(6);
- } else
- altitude = int16(6);
- }
+ AltosCalData cal_data = listener.cal_data();
- public void update_state(AltosState state) {
- super.update_state(state);
- AltosGPS gps = state.make_temp_gps(false);
+ AltosGPS gps = cal_data.make_temp_gps(tick(), false);
+ int flags = flags();
gps.nsat = flags & 0xf;
gps.locked = (flags & (1 << 4)) != 0;
gps.connected = (flags & (1 << 5)) != 0;
+ gps.pdop = pdop() / 10.0;
+ gps.hdop = hdop() / 10.0;
+ gps.vdop = vdop() / 10.0;
if (gps.locked) {
- gps.lat = latitude * 1.0e-7;
- gps.lon = longitude * 1.0e-7;
- gps.alt = altitude;
- gps.year = 2000 + year;
- gps.month = month;
- gps.day = day;
- gps.hour = hour;
- gps.minute = minute;
- gps.second = second;
- gps.ground_speed = ground_speed * 1.0e-2;
- gps.course = course * 2;
- gps.climb_rate = climb_rate * 1.0e-2;
- gps.pdop = pdop / 10.0;
- gps.hdop = hdop / 10.0;
- gps.vdop = vdop / 10.0;
+ gps.lat = latitude() * 1.0e-7;
+ gps.lon = longitude() * 1.0e-7;
+ gps.alt = altitude();
+ gps.year = 2000 + year();
+ gps.month = month();
+ gps.day = day();
+ gps.hour = hour();
+ gps.minute = minute();
+ gps.second = second();
+ gps.ground_speed = ground_speed() * 1.0e-2;
+ gps.course = course() * 2;
+ gps.climb_rate = climb_rate() * 1.0e-2;
+
+ if (gps.nsat >= 4)
+ cal_data.set_gps(gps);
}
- state.set_temp_gps();
+ listener.set_gps(gps);
+ cal_data.set_gps(gps);
+ cal_data.reset_temp_gps();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.util.HashMap;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMegaData extends AltosTelemetryStandard {
- int state;
- int v_batt;
- int v_pyro;
- int sense[];
+ int state() { return uint8(5); }
- int ground_pres;
- int ground_accel;
- int accel_plus_g;
- int accel_minus_g;
+ int v_batt() { return int16(6); }
+ int v_pyro() { return int16(8); }
+ int sense(int i) { int v = uint8(10+i); return v << 4 | v >> 8; }
- int acceleration;
- int speed;
- int height_16;
+ int ground_pres() { return int32(16); }
+ int ground_accel() { return int16(20); }
+ int accel_plus_g() { return int16(22); }
+ int accel_minus_g() { return int16(24);}
- public AltosTelemetryMegaData(int[] bytes) {
- super(bytes);
-
- state = uint8(5);
-
- v_batt = int16(6);
- v_pyro = int16(8);
-
- sense = new int[6];
-
- for (int i = 0; i < 6; i++) {
- sense[i] = uint8(10 + i) << 4;
- sense[i] |= sense[i] >> 8;
- }
+ int acceleration() { return int16(26); }
+ int speed() { return int16(28); }
+ int height_16() { return int16(30); }
- ground_pres = int32(16);
- ground_accel = int16(20);
- accel_plus_g = int16(22);
- accel_minus_g = int16(24);
-
- acceleration = int16(26);
- speed = int16(28);
-
- height_16 = int16(30);
+ public AltosTelemetryMegaData(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
- state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+ listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro()));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4]));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5]));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(4)));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(5)));
double voltages[] = new double[4];
for (int i = 0; i < 4; i++)
- voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]);
+ voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+
+ listener.set_igniter_voltage(voltages);
- state.set_ignitor_voltage(voltages);
+ AltosCalData cal_data = listener.cal_data();
- state.set_ground_accel(ground_accel);
- state.set_ground_pressure(ground_pres);
- state.set_accel_g(accel_plus_g, accel_minus_g);
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_ground_pressure(ground_pres());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
/* 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);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration() / 16.0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
- int accel;
- int pres;
- int temp;
+ int orient() { return int8(5); }
- int accel_x;
- int accel_y;
- int accel_z;
+ int accel() { return int16(6); }
+ int pres() { return int32(8); }
+ int temp() { return int16(12); }
- int gyro_x;
- int gyro_y;
- int gyro_z;
+ int accel_x() { return int16(14); }
+ int accel_y() { return int16(16); }
+ int accel_z() { return int16(18); }
- int mag_x;
- int mag_y;
- int mag_z;
+ int gyro_x() { return int16(20); }
+ int gyro_y() { return int16(22); }
+ int gyro_z() { return int16(24); }
- int orient;
+ int mag_x() { return int16(26); }
+ int mag_z() { return int16(28); }
+ int mag_y() { return int16(30); }
- public AltosTelemetryMegaSensor(int[] bytes) {
+ public AltosTelemetryMegaSensor(int[] bytes) throws AltosCRCException {
super(bytes);
+ }
- orient = int8(5);
- accel = int16(6);
- pres = int32(8);
- temp = int16(12);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- accel_x = int16(14);
- accel_y = int16(16);
- accel_z = int16(18);
+ AltosCalData cal_data = listener.cal_data();
- gyro_x = int16(20);
- gyro_y = int16(22);
- gyro_z = int16(24);
+ listener.set_acceleration(cal_data.acceleration(accel()));
+ listener.set_pressure(pres());
+ listener.set_temperature(temp() / 100.0);
- mag_x = int16(26);
- mag_y = int16(28);
- mag_z = int16(30);
- }
+ listener.set_orient(orient());
- public void update_state(AltosState state) {
- super.update_state(state);
+ /* XXX we have no calibration data for these values */
- state.set_accel(accel);
- state.set_pressure(pres);
- state.set_temperature(temp / 100.0);
+ if (cal_data.accel_zero_along == AltosLib.MISSING)
+ cal_data.set_accel_zero(0, 0, 0);
+ if (cal_data.gyro_zero_roll == AltosLib.MISSING)
+ cal_data.set_gyro_zero(0, 0, 0);
- state.set_orient(orient);
+ int accel_along = accel_y();
+ int accel_across = accel_x();
+ int accel_through = accel_z();
+ int gyro_roll = gyro_y();
+ int gyro_pitch = gyro_x();
+ int gyro_yaw = gyro_z();
- state.set_imu(new AltosIMU(accel_y, /* along */
- accel_x, /* across */
- accel_z, /* through */
- gyro_y, /* along */
- gyro_x, /* across */
- gyro_z)); /* through */
+ int mag_along = mag_y();
+ int mag_across = mag_x();
+ int mag_through = mag_z();
- state.set_mag(new AltosMag(mag_x, mag_y, mag_z));
+ listener.set_accel(cal_data.accel_along(accel_along),
+ cal_data.accel_across(accel_across),
+ cal_data.accel_through(accel_through));
+ listener.set_gyro(cal_data.gyro_roll(gyro_roll),
+ cal_data.gyro_pitch(gyro_pitch),
+ cal_data.gyro_yaw(gyro_yaw));
+ listener.set_mag(cal_data.mag_along(mag_along),
+ cal_data.mag_across(mag_across),
+ cal_data.mag_through(mag_through));
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
- int ground_pres;
- int ground_accel;
- int accel_plus_g;
- int accel_minus_g;
+ int ground_pres() { return int32(8); }
+ int ground_accel() { return int16(12); }
+ int accel_plus_g() { return int16(14); }
+ int accel_minus_g() { return int16(16); }
- public AltosTelemetryMetrumData(int[] bytes) {
+ public AltosTelemetryMetrumData(int[] bytes) throws AltosCRCException {
super(bytes);
-
- ground_pres = int32(8);
- ground_accel = int16(12);
- accel_plus_g = int16(14);
- accel_minus_g = int16(16);
}
- public void update_state(AltosState state) {
- state.set_ground_accel(ground_accel);
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_ground_pressure(ground_pres);
+ public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
+ cal_data.set_ground_pressure(ground_pres());
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
- int state;
+ int state() { return uint8(5); }
- int accel;
- int pres;
- int temp;
+ int accel() { return int16(6); }
+ int pres() { return int32(8); }
+ int temp() { return int16(12); }
- int acceleration;
- int speed;
- int height_16;
+ int acceleration() { return int16(14); }
+ int speed() { return int16(16); }
+ int height_16() { return int16(18); }
- int v_batt;
- int sense_a;
- int sense_m;
+ int v_batt() { return int16(20); }
+ int sense_a() { return int16(22); }
+ int sense_m() { return int16(24); }
- public AltosTelemetryMetrumSensor(int[] bytes) {
+ public AltosTelemetryMetrumSensor(int[] bytes) throws AltosCRCException {
super(bytes);
-
- state = int8(5);
- accel = int16(6);
- pres = int32(8);
- temp = int16(12);
-
- acceleration = int16(14);
- speed = int16(16);
- height_16 = int16(18);
-
- v_batt = int16(20);
- sense_a = int16(22);
- sense_m = int16(24);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_accel(accel);
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.set_acceleration(listener.cal_data().acceleration(accel()));
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_kalman(extend_height(state, height_16),
- speed/16.0, acceleration/16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
- state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
+ listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
- state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a));
- state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m));
+ listener.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMini2 extends AltosTelemetryStandard {
- int state;
- int v_batt;
- int sense_a;
- int sense_m;
+ int state() { return uint8(5); }
- int pres;
- int temp;
+ int v_batt() { return int16(6); }
+ int sense_a() { return int16(8); }
+ int sense_m() { return int16(10); }
- int acceleration;
- int speed;
- int height;
+ int pres() { return int32(12); }
+ int temp() { return int16(16); }
- int ground_pres;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height() { return int16(22); }
- public AltosTelemetryMini2(int[] bytes) {
- super(bytes);
-
- state = int8(5);
-
- v_batt = int16(6);
- sense_a = int16(8);
- sense_m = int16(10);
-
- pres = int32(12);
- temp = int16(16);
+ int ground_pres() { return int32(24); }
- acceleration = int16(18);
- speed = int16(20);
- height = int16(22);
-
- ground_pres = int32(24);
+ public AltosTelemetryMini2(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ listener.set_state(state());
- state.set_state(this.state);
+ listener.set_battery_voltage(AltosConvert.tele_mini_2_voltage(v_batt()));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.tele_mini_2_voltage(sense_m()));
- state.set_battery_voltage(AltosConvert.tele_mini_2_voltage(v_batt));
- state.set_apogee_voltage(AltosConvert.tele_mini_2_voltage(sense_a));
- state.set_main_voltage(AltosConvert.tele_mini_2_voltage(sense_m));
+ AltosCalData cal_data = listener.cal_data();
- state.set_ground_pressure(ground_pres);
+ cal_data.set_ground_pressure(ground_pres());
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_kalman(height, speed/16.0, acceleration/16.0);
+ listener.set_kalman(height(), speed()/16.0, acceleration()/16.0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryMini3 extends AltosTelemetryStandard {
- int state;
+ int state() { return uint8(5); }
- int v_batt;
- int sense_a;
- int sense_m;
+ int v_batt() { return int16(6); }
+ int sense_a() { return int16(8); }
+ int sense_m() { return int16(10); }
- int pres;
- int temp;
+ int pres() { return int32(12); }
+ int temp() { return int16(16); }
- int acceleration;
- int speed;
- int height_16;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height_16() { return int16(22); }
- int ground_pres;
+ int ground_pres() { return int32(24); }
- public AltosTelemetryMini3(int[] bytes) {
+ public AltosTelemetryMini3(int[] bytes) throws AltosCRCException {
super(bytes);
-
- state = int8(5);
-
- v_batt = int16(6);
- sense_a = int16(8);
- sense_m = int16(10);
-
- pres = int32(12);
- temp = int16(16);
-
- acceleration = int16(18);
- speed = int16(20);
- height_16 = int16(22);
-
- ground_pres = int32(24);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- state.set_state(this.state);
+ listener.set_state(state());
- state.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt));
+ listener.set_battery_voltage(AltosConvert.tele_mini_3_battery_voltage(v_batt()));
- state.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_a));
- state.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_m));
+ listener.set_apogee_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_a()));
+ listener.set_main_voltage(AltosConvert.tele_mini_3_pyro_voltage(sense_m()));
- state.set_pressure(pres);
- state.set_temperature(temp/100.0);
+ listener.cal_data().set_ground_pressure(ground_pres());
- state.set_kalman(extend_height(state, height_16),
- speed/16.0, acceleration/16.0);
+ listener.set_pressure(pres());
+ listener.set_temperature(temp()/100.0);
- state.set_ground_pressure(ground_pres);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetryRaw extends AltosTelemetryStandard {
- public AltosTelemetryRaw(int[] bytes) {
+ public AltosTelemetryRaw(int[] bytes) throws AltosCRCException {
super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
import java.io.*;
import java.util.concurrent.*;
public class AltosTelemetryReader extends AltosFlightReader {
- AltosLink link;
- AltosLog log;
- double frequency;
- int telemetry;
- int telemetry_rate;
- AltosState state = null;
+ AltosLink link;
+ AltosLog log;
+ double frequency;
+ int telemetry;
+ int telemetry_rate;
+ private AltosState state = null;
+ private AltosCalData cal_data = null;
LinkedBlockingQueue<AltosLine> telem;
throw new IOException("IO error");
} while (!link.get_monitor());
AltosTelemetry telem = AltosTelemetry.parse(l.line);
- if (state == null)
- state = new AltosState();
- else
- state = state.clone();
- telem.update_state(state);
+ if (state == null) {
+ System.out.printf("Make state\n");
+ state = new AltosState(cal_data());
+ }
+ telem.provide_data(state);
return state;
}
+ public AltosCalData cal_data() {
+ if (cal_data == null) {
+ System.out.printf("Make cal data\n");
+ cal_data = new AltosCalData();
+ }
+ return cal_data;
+ }
+
public void flush() {
telem.clear();
}
public void reset() {
flush();
state = null;
+ cal_data = null;
}
public void close(boolean interrupted) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetrySatellite extends AltosTelemetryStandard {
- int channels;
- AltosGPSSat[] sats;
+ int channels() { return uint8(5); }
- public AltosTelemetrySatellite(int[] bytes) {
- super(bytes);
+ AltosGPSSat[] sats() {
+ int channels = channels();
+ AltosGPSSat[] sats = null;
- channels = uint8(5);
if (channels > 12)
channels = 12;
if (channels == 0)
sats[i] = new AltosGPSSat(svid, c_n_1);
}
}
+ return sats;
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public AltosTelemetrySatellite(int[] bytes) throws AltosCRCException {
+ super(bytes);
+ }
+
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
+
+ AltosCalData cal_data = listener.cal_data();
- AltosGPS gps = state.make_temp_gps(true);
+ AltosGPS gps = cal_data.make_temp_gps(tick(), true);
- gps.cc_gps_sat = sats;
- state.set_temp_gps();
+ gps.cc_gps_sat = sats();
+ listener.set_gps(gps);
+ cal_data.reset_temp_gps();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTelemetrySensor extends AltosTelemetryStandard {
- int state;
- int accel;
- int pres;
- int temp;
- int v_batt;
- int sense_d;
- int sense_m;
+ int state() { return uint8(5); }
+ int accel() { return int16(6); }
+ int pres() { return int16(8); }
+ int temp() { return int16(10); }
+ int v_batt() { return int16(12); }
+ int sense_d() { return int16(14); }
+ int sense_m() { return int16(16); }
- int acceleration;
- int speed;
- int height;
+ int acceleration() { return int16(18); }
+ int speed() { return int16(20); }
+ int height_16() { return int16(22); }
- int ground_accel;
- int ground_pres;
- int accel_plus_g;
- int accel_minus_g;
+ int ground_accel() { return int16(24); }
+ int ground_pres() { return int16(26); }
+ int accel_plus_g() { return int16(28); }
+ int accel_minus_g() { return int16(30); }
- public AltosTelemetrySensor(int[] bytes) {
+ public AltosTelemetrySensor(int[] bytes) throws AltosCRCException {
super(bytes);
- state = uint8(5);
-
- accel = int16(6);
- pres = int16(8);
- temp = int16(10);
- v_batt = int16(12);
- sense_d = int16(14);
- sense_m = int16(16);
+ }
- acceleration = int16(18);
- speed = int16(20);
- height = int16(22);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
- ground_pres = int16(24);
- ground_accel = int16(26);
- accel_plus_g = int16(28);
- accel_minus_g = int16(30);
- }
+ listener.set_state(state());
- public void update_state(AltosState state) {
- super.update_state(state);
+ AltosCalData cal_data = listener.cal_data();
- state.set_state(this.state);
- if (type == packet_type_TM_sensor) {
- state.set_ground_accel(ground_accel);
- state.set_accel_g(accel_plus_g, accel_minus_g);
- state.set_accel(accel);
+ if (type() == packet_type_TM_sensor) {
+ cal_data.set_ground_accel(ground_accel());
+ cal_data.set_accel_plus_minus(accel_plus_g(), accel_minus_g());
+ listener.set_acceleration(cal_data.acceleration(accel()));
}
- state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres));
- state.set_pressure(AltosConvert.barometer_to_pressure(pres));
- state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
- state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt));
- if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) {
- state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d));
- state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m));
+ cal_data.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres()));
+ listener.set_pressure(AltosConvert.barometer_to_pressure(pres()));
+ listener.set_temperature(AltosConvert.thermometer_to_temperature(temp()));
+ listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt()));
+ if (type() == packet_type_TM_sensor || type() == packet_type_Tm_sensor) {
+ listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sense_d()));
+ listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sense_m()));
}
- state.set_kalman(height, speed/16.0, acceleration / 16.0);
+ listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public abstract class AltosTelemetryStandard extends AltosTelemetry {
- int[] bytes;
- int type;
-
public int int8(int off) {
return AltosLib.int8(bytes, off + 1);
}
return AltosLib.string(bytes, off + 1, l);
}
- public static AltosTelemetry parse_hex(int[] bytes) {
- int type = AltosLib.uint8(bytes, 4 + 1);
+ public int type() { return uint8(4); }
+
+ public int serial() { return uint16(0); }
+
+ public int tick() { return uint16(2); }
+ public static AltosTelemetry parse_hex(int[] bytes) throws AltosCRCException {
AltosTelemetry telem;
+
+ int type = AltosLib.uint8(bytes, 4+1);
switch (type) {
case packet_type_TM_sensor:
case packet_type_Tm_sensor:
return telem;
}
- public AltosTelemetryStandard(int[] bytes) {
- this.bytes = bytes;
-
- serial = uint16(0);
- tick = uint16(2);
- type = uint8(4);
+ public AltosTelemetryStandard(int[] bytes) throws AltosCRCException {
+ super(bytes);
}
- public void update_state(AltosState state) {
- super.update_state(state);
+ public void provide_data(AltosDataListener listener) {
+ super.provide_data(listener);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosTemperature extends AltosUnits {
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosTime extends AltosUnits {
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_unis) { return v; }
+
+ public String show_units(boolean imperial_units) { return "s"; }
+
+ public String say_units(boolean imperial_units) { return "seconds"; }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ if (width < 5)
+ return 0;
+ return width - 5;
+ }
+
+ public int say_fraction(boolean imperial_units) { return 0; }
+}
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.util.*;
+
+public class AltosTimeSeries implements Iterable<AltosTimeValue>, Comparable<AltosTimeSeries> {
+ public String label;
+ public AltosUnits units;
+ ArrayList<AltosTimeValue> values;
+
+ public int compareTo(AltosTimeSeries other) {
+ return label.compareTo(other.label);
+ }
+
+ public void add(AltosTimeValue tv) {
+ values.add(tv);
+ }
+
+ public void add(double time, double value) {
+ add(new AltosTimeValue(time, value));
+ }
+
+ public AltosTimeValue get(int i) {
+ return values.get(i);
+ }
+
+ private double lerp(AltosTimeValue v0, AltosTimeValue v1, double t) {
+ /* degenerate case */
+ if (v0.time == v1.time)
+ return (v0.value + v1.value) / 2;
+
+ return (v0.value * (v1.time - t) + v1.value * (t - v0.time)) / (v1.time - v0.time);
+ }
+
+ private int after_index(double time) {
+ int lo = 0;
+ int hi = values.size() - 1;
+
+ while (lo <= hi) {
+ int mid = (lo + hi) / 2;
+
+ if (values.get(mid).time < time)
+ lo = mid + 1;
+ else
+ hi = mid - 1;
+ }
+ return lo;
+ }
+
+ /* Compute a value for an arbitrary time */
+ public double value(double time) {
+ int after = after_index(time);
+ double ret;
+
+ if (after == 0)
+ ret = values.get(0).value;
+ else if (after == values.size())
+ ret = values.get(after - 1).value;
+ else {
+ AltosTimeValue b = values.get(after-1);
+ AltosTimeValue a = values.get(after);
+ ret = lerp(b, a, time);
+ }
+ return ret;
+ }
+
+ /* Find the value just before an arbitrary time */
+ public double value_before(double time) {
+ int after = after_index(time);
+
+ if (after == 0)
+ return values.get(0).value;
+ return values.get(after-1).value;
+ }
+
+ /* Find the value just after an arbitrary time */
+ public double value_after(double time) {
+ int after = after_index(time);
+
+ if (after == values.size())
+ return values.get(after-1).value;
+ return values.get(after).value;
+ }
+
+ public double time_of(double value) {
+ double last = AltosLib.MISSING;
+ for (AltosTimeValue v : values) {
+ if (v.value >= value)
+ return v.time;
+ last = v.time;
+ }
+ return last;
+ }
+
+ public int size() {
+ return values.size();
+ }
+
+ public Iterator<AltosTimeValue> iterator() {
+ return values.iterator();
+ }
+
+ public AltosTimeValue max() {
+ AltosTimeValue max = null;
+ for (AltosTimeValue tv : values)
+ if (max == null || tv.value > max.value)
+ max = tv;
+ return max;
+ }
+
+ public AltosTimeValue max(double start_time, double end_time) {
+ AltosTimeValue max = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time)
+ if (max == null || tv.value > max.value)
+ max = tv;
+ }
+ return max;
+ }
+
+ public AltosTimeValue min() {
+ AltosTimeValue min = null;
+ for (AltosTimeValue tv : values) {
+ if (min == null || tv.value < min.value)
+ min = tv;
+ }
+ return min;
+ }
+
+ public AltosTimeValue min(double start_time, double end_time) {
+ AltosTimeValue min = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time)
+ if (min == null || tv.value < min.value)
+ min = tv;
+ }
+ return min;
+ }
+
+ public AltosTimeValue first() {
+ return values.get(0);
+ }
+
+ public AltosTimeValue last() {
+ return values.get(values.size() - 1);
+ }
+
+ public double average() {
+ double total_value = 0;
+ double total_time = 0;
+ AltosTimeValue prev = null;
+ for (AltosTimeValue tv : values) {
+ if (prev != null) {
+ total_value += (tv.value + prev.value) / 2 * (tv.time - prev.time);
+ total_time += (tv.time - prev.time);
+ }
+ prev = tv;
+ }
+ if (total_time == 0)
+ return AltosLib.MISSING;
+ return total_value / total_time;
+ }
+
+ public double average(double start_time, double end_time) {
+ double total_value = 0;
+ double total_time = 0;
+ AltosTimeValue prev = null;
+ for (AltosTimeValue tv : values) {
+ if (start_time <= tv.time && tv.time <= end_time) {
+ if (prev != null) {
+ total_value += (tv.value + prev.value) / 2 * (tv.time - start_time);
+ total_time += (tv.time - start_time);
+ }
+ start_time = tv.time;
+ }
+ prev = tv;
+ }
+ if (total_time == 0)
+ return AltosLib.MISSING;
+ return total_value / total_time;
+ }
+
+ public AltosTimeSeries integrate(AltosTimeSeries integral) {
+ double value = 0.0;
+ double pvalue = 0.0;
+ double time = 0.0;
+ boolean start = true;
+
+ for (AltosTimeValue v : values) {
+ if (start) {
+ value = 0.0;
+ start = false;
+ } else {
+ value += (pvalue + v.value) / 2.0 * (v.time - time);
+ }
+ pvalue = v.value;
+ time = v.time;
+ integral.add(time, value);
+
+ }
+ return integral;
+ }
+
+ public AltosTimeSeries differentiate(AltosTimeSeries diff) {
+ double value = 0.0;
+ double time = 0.0;
+ boolean start = true;
+
+ for (AltosTimeValue v: values) {
+ if (start) {
+ value = v.value;
+ time = v.time;
+ start = false;
+ } else {
+ double dx = v.time - time;
+ double dy = v.value - value;
+
+ if (dx != 0)
+ diff.add(time, dy/dx);
+
+ time = v.time;
+ value = v.value;
+ }
+ }
+ return diff;
+ }
+
+ private int find_left(int i, double dt) {
+ int j;
+ double t = values.get(i).time - dt;
+ for (j = i; j >= 0; j--) {
+ if (values.get(j).time < t)
+ break;
+ }
+ return j + 1;
+
+ }
+
+ private int find_right(int i, double dt) {
+ int j;
+ double t = values.get(i).time + dt;
+ for (j = i; j < values.size(); j++) {
+ if (values.get(j).time > t)
+ break;
+ }
+ return j - 1;
+
+ }
+
+ private double filter_coeff(double dist, double width) {
+ double ratio = dist / (width / 2);
+
+ return Math.cos(ratio * Math.PI / 2);
+ }
+
+ public AltosTimeSeries filter(AltosTimeSeries f, double width) {
+ double half_width = width/2;
+ for (int i = 0; i < values.size(); i++) {
+ double center_time = values.get(i).time;
+ double left_time = center_time - half_width;
+ double right_time = center_time + half_width;
+ double total_coeff = 0.0;
+ double total_value = 0.0;
+
+ int left = find_left(i, half_width);
+ int right = find_right(i, half_width);
+
+ for (int j = left; j <= right; j++) {
+ double j_time = values.get(j).time;
+
+ if (left_time <= j_time && j_time <= right_time) {
+ double j_left = j == left ? left_time : values.get(j-1).time;
+ double j_right = j == right ? right_time : values.get(j+1).time;
+ double interval = (j_right - j_left) / 2.0;
+ double coeff = filter_coeff(j_time - center_time, width) * interval;
+ double value = values.get(j).value;
+ double partial = value * coeff;
+
+ total_coeff += coeff;
+ total_value += partial;
+ }
+ }
+ if (total_coeff != 0.0)
+ f.add(center_time, total_value / total_coeff);
+ }
+ return f;
+ }
+
+ public AltosTimeSeries(String label, AltosUnits units) {
+ this.label = label;
+ this.units = units;
+ this.values = new ArrayList<AltosTimeValue>();
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+public class AltosTimeValue {
+ public double time;
+ public double value;
+
+ public AltosTimeValue(double time, double value) {
+ this.time = time;
+ this.value = value;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
public abstract double inverse(double v, boolean imperial_units);
+ public String string_value(double v, boolean imperial_units) {
+ return new Double(value(v, imperial_units)).toString();
+ }
+
public abstract String show_units(boolean imperial_units);
public abstract String say_units(boolean imperial_units);
return say_units(v, AltosConvert.imperial_units);
}
+ public String string_value(double v) {
+ return string_value(v, AltosConvert.imperial_units);
+ }
+
/* Parsing functions. Use the first range of the type */
public String parse_units(boolean imperial_units) {
return first_range(imperial_units).show_units;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosUnitsListener {
public void units_changed(boolean imperial_units);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosUnknownProduct extends Exception {
public String product;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosVersion {
public final static String version = "@VERSION@";
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public class AltosVoltage extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
public interface AltosWriter {
- public void write(AltosStateIterable states);
+ public void write(AltosFlightSeries series);
public void close();
}
altoslib_JAVA = \
AltosLib.java \
+ AltosCalData.java \
AltosCompanion.java \
AltosConfigData.java \
AltosConfigDataException.java \
AltosCRCException.java \
AltosCSV.java \
AltosDebug.java \
- AltosEepromNew.java \
+ AltosEeprom.java \
+ AltosRecordSet.java \
AltosEepromRecord.java \
AltosEepromRecordFull.java \
AltosEepromRecordTiny.java \
AltosEepromRecordGps.java \
AltosEepromRecordFireTwo.java \
AltosEepromRecordSet.java \
- AltosEeprom.java \
AltosEepromChunk.java \
AltosEepromDownload.java \
AltosEepromMonitor.java \
AltosFile.java \
AltosFlash.java \
AltosFlashListener.java \
+ AltosDataListener.java \
+ AltosDataProvider.java \
+ AltosFlightSeries.java \
AltosFlightReader.java \
AltosFlightStats.java \
AltosForce.java \
AltosFrequency.java \
AltosGPS.java \
+ AltosGPSTimeValue.java \
AltosGPSSat.java \
AltosGreatCircle.java \
AltosHexfile.java \
AltosOrient.java \
AltosParse.java \
AltosPressure.java \
+ AltosPresTemp.java \
AltosPreferences.java \
AltosPreferencesBackend.java \
AltosProgrammer.java \
+ AltosPyroName.java \
AltosReplayReader.java \
AltosRomconfig.java \
AltosSavedState.java \
AltosSensorMetrum.java \
AltosSensorTGPS.java \
AltosState.java \
- AltosStateIterable.java \
- AltosStateUpdate.java \
+ AltosStateName.java \
+ AltosStringInputStream.java \
AltosTelemetry.java \
AltosTelemetryConfiguration.java \
AltosTelemetryCompanion.java \
AltosTelemetrySensor.java \
AltosTelemetrySatellite.java \
AltosTelemetryStandard.java \
+ AltosTime.java \
+ AltosTimeSeries.java \
+ AltosTimeValue.java \
AltosUnitsListener.java \
AltosUnknownProduct.java \
AltosMs5607.java \
AltosLocation.java \
AltosLatitude.java \
AltosLongitude.java \
+ AltosRotationRate.java \
AltosPyro.java \
AltosWriter.java \
AltosQuaternion.java \
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class Altos extends AltosUILib {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosAscent extends AltosUIFlightTab {
JLabel cur, max;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosCompanionInfo extends JTable implements AltosFlightDisplay {
private AltosFlightInfoTableModel model;
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfigPyroUI
extends AltosUIDialog
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfigTD implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfigTDUI
extends AltosUIDialog
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfigUI
extends AltosUIDialog
}
void set_radio_enable_tool_tip() {
- if (radio_enable_value.isEnabled())
+ if (radio_enable_value.isVisible())
radio_enable_value.setToolTipText("Enable/Disable telemetry and RDF transmissions");
else
radio_enable_value.setToolTipText("Firmware version does not support disabling radio");
}
void set_rate_tool_tip() {
- if (rate_value.isEnabled())
+ if (rate_value.isVisible())
rate_value.setToolTipText("Select telemetry baud rate");
else
rate_value.setToolTipText("Firmware version does not support variable telemetry rates");
}
void set_aprs_interval_tool_tip() {
- if (aprs_interval_value.isEnabled())
+ if (aprs_interval_value.isVisible())
aprs_interval_value.setToolTipText("Enable APRS and set the interval between APRS reports");
else
aprs_interval_value.setToolTipText("Hardware doesn't support APRS");
}
void set_aprs_ssid_tool_tip() {
- if (aprs_ssid_value.isEnabled())
+ if (aprs_ssid_value.isVisible())
aprs_ssid_value.setToolTipText("Set the APRS SSID (secondary station identifier)");
- else if (aprs_ssid_value.isEnabled())
+ else if (aprs_ssid_value.isVisible())
aprs_ssid_value.setToolTipText("Software version doesn't support setting the APRS SSID");
else
aprs_ssid_value.setToolTipText("Hardware doesn't support APRS");
}
void set_aprs_format_tool_tip() {
- if (aprs_format_value.isEnabled())
+ if (aprs_format_value.isVisible())
aprs_format_value.setToolTipText("Set the APRS format (compressed/uncompressed)");
- else if (aprs_format_value.isEnabled())
+ else if (aprs_format_value.isVisible())
aprs_format_value.setToolTipText("Software version doesn't support setting the APRS format");
else
aprs_format_value.setToolTipText("Hardware doesn't support APRS");
}
void set_flight_log_max_tool_tip() {
- if (flight_log_max_value.isEnabled())
+ if (flight_log_max_value.isVisible())
flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)");
else {
if (is_telemini_v1())
}
void set_ignite_mode_tool_tip() {
- if (ignite_mode_value.isEnabled())
+ if (ignite_mode_value.isVisible())
ignite_mode_value.setToolTipText("Select when igniters will be fired");
else
ignite_mode_value.setToolTipText("Older firmware could not select ignite mode");
}
void set_pad_orientation_tool_tip() {
- if (pad_orientation_value.isEnabled())
+ if (pad_orientation_value.isVisible())
pad_orientation_value.setToolTipText("How will the computer be mounted in the airframe");
else {
if (is_telemetrum())
}
void set_beep_tool_tip() {
- if (beep_value.isEnabled())
+ if (beep_value.isVisible())
beep_value.setToolTipText("What frequency the beeper will sound at");
else
beep_value.setToolTipText("Older firmware could not select beeper frequency");
}
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);
-
- main_deploy_value.setVisible(new_main_deploy >= 0);
- main_deploy_label.setVisible(new_main_deploy >= 0);
-
+ if (new_main_deploy != AltosLib.MISSING)
+ main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy));
+ main_deploy_value.setVisible(new_main_deploy != AltosLib.MISSING);
+ main_deploy_label.setVisible(new_main_deploy != AltosLib.MISSING);
}
public int main_deploy() throws AltosConfigDataException {
} catch (ParseException pe) {
}
- if (tracker_motion_value.isEnabled()) {
+ if (tracker_motion_value.isVisible()) {
String motion = tracker_motion_value.getSelectedItem().toString();
tracker_motion_label.setText(get_tracker_motion_label());
set_tracker_motion_values();
}
public void set_apogee_delay(int new_apogee_delay) {
- apogee_delay_value.setVisible(new_apogee_delay >= 0);
- apogee_delay_label.setVisible(new_apogee_delay >= 0);
-
- apogee_delay_value.setSelectedItem(Integer.toString(new_apogee_delay));
- apogee_delay_value.setEnabled(new_apogee_delay >= 0);
+ if (new_apogee_delay != AltosLib.MISSING)
+ apogee_delay_value.setSelectedItem(Integer.toString(new_apogee_delay));
+ apogee_delay_value.setVisible(new_apogee_delay != AltosLib.MISSING);
+ apogee_delay_label.setVisible(new_apogee_delay != AltosLib.MISSING);
}
private int parse_int(String name, String s, boolean split) throws AltosConfigDataException {
}
public void set_apogee_lockout(int new_apogee_lockout) {
- apogee_lockout_value.setSelectedItem(Integer.toString(new_apogee_lockout));
- apogee_lockout_value.setEnabled(new_apogee_lockout >= 0);
+ if (new_apogee_lockout != AltosLib.MISSING)
+ apogee_lockout_value.setSelectedItem(Integer.toString(new_apogee_lockout));
- apogee_lockout_value.setVisible(new_apogee_lockout >= 0);
- apogee_lockout_label.setVisible(new_apogee_lockout >= 0);
+ apogee_lockout_value.setVisible(new_apogee_lockout != AltosLib.MISSING);
+ apogee_lockout_label.setVisible(new_apogee_lockout != AltosLib.MISSING);
}
public int apogee_lockout() throws AltosConfigDataException {
}
public void set_radio_frequency(double new_radio_frequency) {
- radio_frequency_label.setVisible(new_radio_frequency >= 0);
- radio_frequency_value.set_frequency(new_radio_frequency);
+ if (new_radio_frequency != AltosLib.MISSING)
+ radio_frequency_value.set_frequency(new_radio_frequency);
+ radio_frequency_label.setVisible(new_radio_frequency != AltosLib.MISSING);
+ radio_frequency_value.setVisible(new_radio_frequency != AltosLib.MISSING);
}
public double radio_frequency() {
}
public void set_radio_calibration(int new_radio_calibration) {
- radio_calibration_value.setVisible(new_radio_calibration >= 0);
- radio_calibration_label.setVisible(new_radio_calibration >= 0);
-
- if (new_radio_calibration < 0)
- radio_calibration_value.setText("Disabled");
- else
+ if (new_radio_calibration != AltosLib.MISSING)
radio_calibration_value.setText(String.format("%d", new_radio_calibration));
+ radio_calibration_value.setVisible(new_radio_calibration != AltosLib.MISSING);
+ radio_calibration_label.setVisible(new_radio_calibration != AltosLib.MISSING);
}
public void set_radio_enable(int new_radio_enable) {
- radio_enable_label.setVisible(new_radio_enable >= 0);
- radio_enable_value.setVisible(new_radio_enable >= 0);
-
- if (new_radio_enable >= 0) {
- radio_enable_value.setSelected(new_radio_enable > 0);
- radio_enable_value.setEnabled(true);
- } else {
- radio_enable_value.setSelected(true);
- radio_enable_value.setEnabled(false);
- }
+ if (new_radio_enable != AltosLib.MISSING)
+ radio_enable_value.setSelected(new_radio_enable != 0);
+ radio_enable_label.setVisible(new_radio_enable != AltosLib.MISSING);
+ radio_enable_value.setVisible(new_radio_enable != AltosLib.MISSING);
set_radio_enable_tool_tip();
}
public int radio_enable() {
- if (radio_enable_value.isEnabled())
+ if (radio_enable_value.isVisible())
return radio_enable_value.isSelected() ? 1 : 0;
else
- return -1;
+ return AltosLib.MISSING;
}
public void set_telemetry_rate(int new_rate) {
- rate_label.setVisible(new_rate >= 0);
-
- rate_value.set_rate(new_rate);
+ if (new_rate != AltosLib.MISSING)
+ rate_value.set_rate(new_rate);
+ rate_label.setVisible(new_rate != AltosLib.MISSING);
+ rate_value.setVisible(new_rate != AltosLib.MISSING);
+ set_rate_tool_tip();
}
public int telemetry_rate() {
}
public void set_callsign(String new_callsign) {
+ if (new_callsign != null)
+ callsign_value.setText(new_callsign);
callsign_value.setVisible(new_callsign != null);
callsign_label.setVisible(new_callsign != null);
-
- callsign_value.setText(new_callsign);
}
public String callsign() {
- return callsign_value.getText();
+ if (callsign_value.isVisible())
+ return callsign_value.getText();
+ return null;
}
int flight_log_max_limit;
}
public void set_flight_log_max(int new_flight_log_max) {
- flight_log_max_value.setVisible(new_flight_log_max >= 0);
- flight_log_max_label.setVisible(new_flight_log_max >= 0);
-
- flight_log_max_value.setSelectedItem(flight_log_max_label(new_flight_log_max));
- flight_log_max = new_flight_log_max;
+ if (new_flight_log_max != AltosLib.MISSING) {
+ flight_log_max_value.setSelectedItem(flight_log_max_label(new_flight_log_max));
+ flight_log_max = new_flight_log_max;
+ }
+ flight_log_max_value.setVisible(new_flight_log_max != AltosLib.MISSING);
+ flight_log_max_label.setVisible(new_flight_log_max != AltosLib.MISSING);
set_flight_log_max_tool_tip();
}
}
public int flight_log_max() throws AltosConfigDataException {
- return parse_int("flight log max", flight_log_max_value.getSelectedItem().toString(), true);
+ if (flight_log_max_value.isVisible())
+ return parse_int("flight log max", flight_log_max_value.getSelectedItem().toString(), true);
+ return AltosLib.MISSING;
}
public void set_flight_log_max_limit(int new_flight_log_max_limit) {
flight_log_max_limit = new_flight_log_max_limit;
- flight_log_max_value.removeAllItems();
- for (int i = 8; i >= 1; i--) {
- int size = flight_log_max_limit / i;
- flight_log_max_value.addItem(String.format("%d (%d flights)", size, i));
+ if (new_flight_log_max_limit != AltosLib.MISSING) {
+ flight_log_max_value.removeAllItems();
+ for (int i = 8; i >= 1; i--) {
+ int size = flight_log_max_limit / i;
+ flight_log_max_value.addItem(String.format("%d (%d flights)", size, i));
+ }
}
if (flight_log_max != 0)
set_flight_log_max(flight_log_max);
}
public void set_ignite_mode(int new_ignite_mode) {
- ignite_mode_value.setVisible(new_ignite_mode >= 0);
- ignite_mode_label.setVisible(new_ignite_mode >= 0);
-
- if (new_ignite_mode >= ignite_mode_values.length)
- new_ignite_mode = 0;
- if (new_ignite_mode < 0) {
- ignite_mode_value.setEnabled(false);
- new_ignite_mode = 0;
- } else {
- ignite_mode_value.setEnabled(true);
+ if (new_ignite_mode != AltosLib.MISSING) {
+ if (new_ignite_mode >= ignite_mode_values.length)
+ new_ignite_mode = 0;
+ if (new_ignite_mode < 0) {
+ ignite_mode_value.setEnabled(false);
+ new_ignite_mode = 0;
+ } else {
+ ignite_mode_value.setEnabled(true);
+ }
+ ignite_mode_value.setSelectedIndex(new_ignite_mode);
}
- ignite_mode_value.setSelectedIndex(new_ignite_mode);
+ ignite_mode_value.setVisible(new_ignite_mode != AltosLib.MISSING);
+ ignite_mode_label.setVisible(new_ignite_mode != AltosLib.MISSING);
+
set_ignite_mode_tool_tip();
}
public int ignite_mode() {
- if (ignite_mode_value.isEnabled())
+ if (ignite_mode_value.isVisible())
return ignite_mode_value.getSelectedIndex();
else
- return -1;
+ return AltosLib.MISSING;
}
public void set_pad_orientation(int new_pad_orientation) {
- pad_orientation_value.setVisible(new_pad_orientation >= 0);
- pad_orientation_label.setVisible(new_pad_orientation >= 0);
-
- if (new_pad_orientation >= pad_orientation_values.length)
- new_pad_orientation = 0;
- if (new_pad_orientation < 0)
- new_pad_orientation = 0;
- pad_orientation_value.setSelectedIndex(new_pad_orientation);
+ if (new_pad_orientation != AltosLib.MISSING) {
+ if (new_pad_orientation >= pad_orientation_values.length)
+ new_pad_orientation = 0;
+ if (new_pad_orientation < 0)
+ new_pad_orientation = 0;
+ pad_orientation_value.setSelectedIndex(new_pad_orientation);
+ }
+ pad_orientation_value.setVisible(new_pad_orientation != AltosLib.MISSING);
+ pad_orientation_label.setVisible(new_pad_orientation != AltosLib.MISSING);
+
set_pad_orientation_tool_tip();
}
public int pad_orientation() {
- if (pad_orientation_value.isEnabled())
+ if (pad_orientation_value.isVisible())
return pad_orientation_value.getSelectedIndex();
else
- return -1;
+ return AltosLib.MISSING;
}
public void set_beep(int new_beep) {
- beep_value.setVisible(new_beep >= 0);
- beep_label.setVisible(new_beep >= 0);
-
- int new_freq = (int) Math.floor (AltosConvert.beep_value_to_freq(new_beep) + 0.5);
- for (int i = 0; i < beep_values.length; i++)
- if (new_beep == AltosConvert.beep_freq_to_value(Integer.parseInt(beep_values[i]))) {
- beep_value.setSelectedIndex(i);
- set_beep_tool_tip();
- return;
- }
- beep_value.setSelectedItem(String.format("%d", new_freq));
- beep_value.setEnabled(new_beep >= 0);
+ if (new_beep != AltosLib.MISSING) {
+ int new_freq = (int) Math.floor (AltosConvert.beep_value_to_freq(new_beep) + 0.5);
+ for (int i = 0; i < beep_values.length; i++)
+ if (new_beep == AltosConvert.beep_freq_to_value(Integer.parseInt(beep_values[i]))) {
+ beep_value.setSelectedIndex(i);
+ set_beep_tool_tip();
+ return;
+ }
+ beep_value.setSelectedItem(String.format("%d", new_freq));
+ }
+ beep_value.setVisible(new_beep != AltosLib.MISSING);
+ beep_label.setVisible(new_beep != AltosLib.MISSING);
set_beep_tool_tip();
}
public int beep() {
- if (beep_value.isEnabled())
+ if (beep_value.isVisible())
return AltosConvert.beep_freq_to_value(Integer.parseInt(beep_value.getSelectedItem().toString()));
else
- return -1;
+ return AltosLib.MISSING;
}
String[] tracker_motion_values() {
}
void set_tracker_tool_tip() {
- if (tracker_motion_value.isEnabled())
+ if (tracker_motion_value.isVisible())
tracker_motion_value.setToolTipText("How far the device must move before logging");
else
tracker_motion_value.setToolTipText("This device doesn't disable logging when stationary");
- if (tracker_interval_value.isEnabled())
+ if (tracker_interval_value.isVisible())
tracker_interval_value.setToolTipText("How often to report GPS position");
else
tracker_interval_value.setToolTipText("This device can't configure interval");
}
public void set_tracker_motion(int tracker_motion) {
- tracker_motion_label.setVisible(tracker_motion >= 0);
- tracker_motion_value.setVisible(tracker_motion >= 0);
-
- if (tracker_motion < 0) {
- tracker_motion_value.setEnabled(false);
- } else {
- tracker_motion_value.setEnabled(true);
+ if (tracker_motion != AltosLib.MISSING)
tracker_motion_value.setSelectedItem(AltosConvert.height.say(tracker_motion));
- }
+ tracker_motion_label.setVisible(tracker_motion != AltosLib.MISSING);
+ tracker_motion_value.setVisible(tracker_motion != AltosLib.MISSING);
}
public int tracker_motion() throws AltosConfigDataException {
- String str = tracker_motion_value.getSelectedItem().toString();
- try {
- return (int) (AltosConvert.height.parse_locale(str) + 0.5);
- } catch (ParseException pe) {
- throw new AltosConfigDataException("invalid tracker motion %s", str);
+ if (tracker_motion_value.isVisible()) {
+ String str = tracker_motion_value.getSelectedItem().toString();
+ try {
+ return (int) (AltosConvert.height.parse_locale(str) + 0.5);
+ } catch (ParseException pe) {
+ throw new AltosConfigDataException("invalid tracker motion %s", str);
+ }
}
+ return AltosLib.MISSING;
}
public void set_tracker_interval(int tracker_interval) {
- tracker_interval_label.setVisible(tracker_interval >= 0);
- tracker_interval_value.setVisible(tracker_interval >= 0);
-
- if (tracker_interval< 0) {
- tracker_interval_value.setEnabled(false);
- } else {
- tracker_interval_value.setEnabled(true);
+ if (tracker_interval != AltosLib.MISSING)
tracker_interval_value.setSelectedItem(String.format("%d", tracker_interval));
- }
+ tracker_interval_label.setVisible(tracker_interval != AltosLib.MISSING);
+ tracker_interval_value.setVisible(tracker_interval != AltosLib.MISSING);
}
public int tracker_interval() throws AltosConfigDataException {
- return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
+ if (tracker_interval_value.isVisible())
+ return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
+ return AltosLib.MISSING;
}
public void set_pyros(AltosPyro[] new_pyros) {
pyros = new_pyros;
- pyro.setVisible(pyros != null);
if (pyros != null && pyro_ui != null)
pyro_ui.set_pyros(pyros);
+ pyro.setVisible(pyros != null);
}
public AltosPyro[] pyros() throws AltosConfigDataException {
public void set_pyro_firing_time(double new_pyro_firing_time) {
pyro_firing_time = new_pyro_firing_time;
- pyro.setVisible(pyro_firing_time >= 0);
- if (pyro_firing_time >= 0 && pyro_ui != null)
+ if (pyro_firing_time != AltosLib.MISSING && pyro_ui != null)
pyro_ui.set_pyro_firing_time(pyro_firing_time);
+ pyro.setVisible(pyro_firing_time != AltosLib.MISSING);
}
public double pyro_firing_time() throws AltosConfigDataException {
}
public void set_aprs_interval(int new_aprs_interval) {
- aprs_interval_value.setVisible(new_aprs_interval >= 0);
- aprs_interval_label.setVisible(new_aprs_interval >= 0);
-
- String s;
-
- if (new_aprs_interval <= 0)
- s = "Disabled";
- else
- s = Integer.toString(new_aprs_interval);
- aprs_interval_value.setSelectedItem(s);
+ if (new_aprs_interval != AltosLib.MISSING)
+ aprs_interval_value.setSelectedItem(Integer.toString(new_aprs_interval));
+ aprs_interval_value.setVisible(new_aprs_interval != AltosLib.MISSING);
+ aprs_interval_label.setVisible(new_aprs_interval != AltosLib.MISSING);
set_aprs_interval_tool_tip();
}
public int aprs_interval() throws AltosConfigDataException {
- String s = aprs_interval_value.getSelectedItem().toString();
+ if (aprs_interval_value.isVisible()) {
+ String s = aprs_interval_value.getSelectedItem().toString();
- if (s.equals("Disabled"))
- return 0;
- return parse_int("aprs interval", s, false);
+ return parse_int("aprs interval", s, false);
+ }
+ return AltosLib.MISSING;
}
public void set_aprs_ssid(int new_aprs_ssid) {
- aprs_ssid_value.setVisible(new_aprs_ssid >= 0);
- aprs_ssid_label.setVisible(new_aprs_ssid >= 0);
-
- aprs_ssid_value.setSelectedItem(Math.max(0,new_aprs_ssid));
+ if (new_aprs_ssid != AltosLib.MISSING)
+ aprs_ssid_value.setSelectedItem(new_aprs_ssid);
+ aprs_ssid_value.setVisible(new_aprs_ssid != AltosLib.MISSING);
+ aprs_ssid_label.setVisible(new_aprs_ssid != AltosLib.MISSING);
set_aprs_ssid_tool_tip();
}
public int aprs_ssid() throws AltosConfigDataException {
- Integer i = (Integer) aprs_ssid_value.getSelectedItem();
- return i;
+ if (aprs_ssid_value.isVisible()) {
+ Integer i = (Integer) aprs_ssid_value.getSelectedItem();
+ return i;
+ }
+ return AltosLib.MISSING;
}
public void set_aprs_format(int new_aprs_format) {
- aprs_format_value.setVisible(new_aprs_format >= 0);
- aprs_format_label.setVisible(new_aprs_format >= 0);
-
- aprs_format_value.setSelectedIndex(Math.max(0,new_aprs_format));
+ if (new_aprs_format != AltosLib.MISSING)
+ aprs_format_value.setSelectedIndex(new_aprs_format);
+ aprs_format_value.setVisible(new_aprs_format != AltosLib.MISSING);
+ aprs_format_label.setVisible(new_aprs_format != AltosLib.MISSING);
set_aprs_format_tool_tip();
}
public int aprs_format() throws AltosConfigDataException {
- return aprs_format_value.getSelectedIndex();
+ if (aprs_format_value.isVisible())
+ return aprs_format_value.getSelectedIndex();
+ return AltosLib.MISSING;
}
}
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosConfigureUI
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosDescent extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
}
void show(AltosState state, AltosListenerState listener_state) {
- if (!same_call(state.callsign)) {
+ if (!same_call(state.cal_data().callsign)) {
show();
- value.setText(state.callsign);
- if (state.callsign == null)
+ value.setText(state.cal_data().callsign);
+ if (state.cal_data().callsign == null)
setVisible(false);
else
setVisible(true);
- last_call = state.callsign;
+ last_call = state.cal_data().callsign;
}
}
int last_serial = -1;
void show(AltosState state, AltosListenerState listener_state) {
- if (state.serial != last_serial) {
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.serial != last_serial) {
show();
- if (state.serial == AltosLib.MISSING)
+ if (cal_data.serial == AltosLib.MISSING)
value.setText("none");
else
- value.setText(String.format("%d", state.serial));
- last_serial = state.serial;
+ value.setText(String.format("%d", cal_data.serial));
+ last_serial = cal_data.serial;
}
}
int last_flight = -1;
void show(AltosState state, AltosListenerState listener_state) {
- if (state.flight != last_flight) {
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.flight != last_flight) {
show();
- if (state.flight == AltosLib.MISSING)
+ if (cal_data.flight == AltosLib.MISSING)
value.setText("none");
else
- value.setText(String.format("%d", state.flight));
- last_flight = state.flight;
+ value.setText(String.format("%d", cal_data.flight));
+ last_flight = cal_data.flight;
}
}
import java.text.*;
import java.util.prefs.*;
import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosFlightStatusTableModel extends AbstractTableModel {
private String[] columnNames = {
package altosui;
import java.awt.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosFlightStatusUpdate implements ActionListener {
import javax.swing.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
AltosVoice voice;
JTabbedPane pane;
AltosPad pad;
- AltosIgnitor ignitor;
+ AltosIgnitor igniter;
AltosAscent ascent;
AltosDescent descent;
AltosLanded landed;
boolean has_map;
boolean has_companion;
boolean has_state;
- boolean has_ignitor;
+ boolean has_igniter;
private AltosFlightStatus flightStatus;
private AltosInfoTable flightInfo;
status_update.saved_listener_state = listener_state;
if (state == null)
- state = new AltosState();
+ state = new AltosState(new AltosCalData());
if (state.state() != Altos.ao_flight_startup) {
if (!has_state) {
JComponent tab = which_tab(state);
if (tab != cur_tab) {
- if (cur_tab == pane.getSelectedComponent()) {
+ if (cur_tab == pane.getSelectedComponent())
pane.setSelectedComponent(tab);
- }
cur_tab = tab;
}
- if (ignitor.should_show(state)) {
- if (!has_ignitor) {
- pane.add("Ignitor", ignitor);
- has_ignitor = true;
+ if (igniter.should_show(state)) {
+ if (!has_igniter) {
+ pane.add("Ignitor", igniter);
+ has_igniter = true;
}
} else {
- if (has_ignitor) {
- pane.remove(ignitor);
- has_ignitor = false;
+ if (has_igniter) {
+ pane.remove(igniter);
+ has_igniter = false;
}
}
}
}
- if (state.gps != null && state.gps.connected) {
+ if (state.gps != null) {
if (!has_map) {
pane.add("Site Map", sitemap);
has_map = true;
displays.add(pad);
pane.add("Status", pad);
- ignitor = new AltosIgnitor();
- displays.add(ignitor);
+ igniter = new AltosIgnitor();
+ displays.add(igniter);
ascent = new AltosAscent();
displays.add(ascent);
descent = new AltosDescent();
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
AltosGraph graph;
AltosUIEnable enable;
AltosUIMap map;
- AltosState state;
- AltosGraphDataSet graphDataSet;
AltosFlightStats stats;
AltosFlightStatsTable statsTable;
+ AltosGPS gps;
boolean has_gps;
- void fill_map(AltosStateIterable states) {
- boolean any_gps = false;
- for (AltosState state : states) {
- if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
- if (map == null)
- map = new AltosUIMap();
- map.show(state, null);
- has_gps = true;
+ void fill_map(AltosFlightSeries flight_series) {
+ boolean any_gps = false;
+ AltosGPSTimeValue gtv_last = null;
+
+ if (flight_series.gps_series != null) {
+ for (AltosGPSTimeValue gtv : flight_series.gps_series) {
+ gtv_last = gtv;
+ AltosGPS gps = gtv.gps;
+ if (gps != null &&
+ gps.locked &&
+ gps.nsat >= 4) {
+ if (map == null)
+ map = new AltosUIMap();
+ map.show(gps, (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time));
+ this.gps = gps;
+ has_gps = true;
+ }
}
}
+ if (gtv_last != null) {
+ int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time);
+ if (state == AltosLib.ao_flight_landed)
+ map.show(gtv_last.gps, state);
+ }
}
public void font_size_changed(int font_size) {
enable.units_changed(imperial_units);
}
- AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException {
+ AltosGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException {
super(file.getName());
- state = null;
+ AltosCalData cal_data = set.cal_data();
+
pane = new JTabbedPane();
enable = new AltosUIEnable();
- stats = new AltosFlightStats(states);
- graphDataSet = new AltosGraphDataSet(states);
+ AltosUIFlightSeries flight_series = new AltosUIFlightSeries(cal_data);
+
+ set.capture_series(flight_series);
+
+ flight_series.finish();
+
+ stats = new AltosFlightStats(flight_series);
- graph = new AltosGraph(enable, stats, graphDataSet);
+ graph = new AltosGraph(enable, stats, flight_series);
statsTable = new AltosFlightStatsTable(stats);
pane.add("Flight Statistics", statsTable);
has_gps = false;
- fill_map(states);
+ fill_map(flight_series);
if (has_gps)
pane.add("Map", map);
pack();
setVisible(true);
- if (state != null && has_gps)
- map.centre(state);
+ if (gps != null)
+ map.centre(gps);
}
}
import java.io.*;
import java.util.concurrent.*;
import java.util.Arrays;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener {
AltosDevice device;
AltosPad pad;
AltosInfoTable flightInfo;
AltosFlightStatus flightStatus;
- AltosIgnitor ignitor;
+ AltosIgnitor igniter;
AltosIdleMonitor thread;
AltosUIMap sitemap;
int serial;
boolean remote;
- boolean has_ignitor;
+ boolean has_igniter;
boolean has_map;
void stop_display() {
public void show(AltosState state, AltosListenerState listener_state) {
status_update.saved_state = state;
- if (ignitor.should_show(state)) {
- if (!has_ignitor) {
- pane.add("Ignitor", ignitor);
- has_ignitor = true;
+ if (igniter.should_show(state)) {
+ if (!has_igniter) {
+ pane.add("Ignitor", igniter);
+ has_igniter = true;
}
} else {
- if (has_ignitor) {
- pane.remove(ignitor);
- has_ignitor = false;
+ if (has_igniter) {
+ pane.remove(igniter);
+ has_igniter = false;
}
}
if (state.gps != null && state.gps.connected) {
pad.show(state, listener_state);
flightStatus.show(state, listener_state);
flightInfo.show(state, listener_state);
- if (has_ignitor)
- ignitor.show(state, listener_state);
+ if (has_igniter)
+ igniter.show(state, listener_state);
if (has_map)
sitemap.show(state, listener_state);
// } catch (Exception e) {
flightInfo = new AltosInfoTable();
pane.add("Table", new JScrollPane(flightInfo));
- ignitor = new AltosIgnitor();
+ igniter = new AltosIgnitor();
sitemap = new AltosUIMap();
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosIgniteUI
extends AltosUIDialog
fired();
} else if (reply.startsWith("npyro")) {
npyro = Integer.parseInt(reply.substring(6));
+ if (npyro == AltosLib.MISSING)
+ npyro = 0;
make_ui();
}
}
boolean getting_status = false;
- boolean visible = false;
-
void set_ignite_status() {
getting_status = false;
poll_remaining = 2;
- if (!visible) {
- visible = true;
+ if (!isVisible())
setVisible(true);
- }
}
void poll_ignite_status() {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosIgnitor extends AltosUIFlightTab {
public class Ignitor extends AltosUIUnitsIndicator {
- int ignitor;
+ int igniter;
public double value(AltosState state, int i) {
- if (state.ignitor_voltage == null ||
- state.ignitor_voltage.length < ignitor)
+ if (state.igniter_voltage == null ||
+ state.igniter_voltage.length < igniter)
return AltosLib.MISSING;
- return state.ignitor_voltage[ignitor];
+ return state.igniter_voltage[igniter];
}
public double good() { return AltosLib.ao_igniter_good; }
public Ignitor (AltosUIFlightTab container, int y) {
- super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.ignitor_name(y)), 1, true, 1);
- ignitor = y;
+ super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.igniter_name(y)), 1, true, 1);
+ igniter = y;
}
}
- Ignitor[] ignitors;
+ Ignitor[] igniters;
public void show(AltosState state, AltosListenerState listener_state) {
if (isShowing())
- make_ignitors(state);
+ make_igniters(state);
super.show(state, listener_state);
}
public boolean should_show(AltosState state) {
if (state == null)
return false;
- if (state.ignitor_voltage == null)
+ if (state.igniter_voltage == null)
return false;
- return state.ignitor_voltage.length > 0;
+ return state.igniter_voltage.length > 0;
}
- void make_ignitors(AltosState state) {
- int n = (state == null || state.ignitor_voltage == null) ? 0 : state.ignitor_voltage.length;
- int old_n = ignitors == null ? 0 : ignitors.length;
+ void make_igniters(AltosState state) {
+ int n = (state == null || state.igniter_voltage == null) ? 0 : state.igniter_voltage.length;
+ int old_n = igniters == null ? 0 : igniters.length;
if (n != old_n) {
- if (ignitors != null) {
- for (int i = 0; i < ignitors.length; i++) {
- remove(ignitors[i]);
- ignitors[i].remove(this);
- ignitors = null;
+ if (igniters != null) {
+ for (int i = 0; i < igniters.length; i++) {
+ remove(igniters[i]);
+ igniters[i].remove(this);
+ igniters = null;
}
}
if (n > 0) {
setVisible(true);
- ignitors = new Ignitor[n];
+ igniters = new Ignitor[n];
for (int i = 0; i < n; i++) {
- ignitors[i] = new Ignitor(this, i);
- add(ignitors[i]);
+ igniters[i] = new Ignitor(this, i);
+ add(igniters[i]);
}
} else
setVisible(false);
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosLanded extends AltosUIFlightTab implements ActionListener {
if (file != null) {
String filename = file.getName();
try {
- AltosStateIterable states = null;
+ AltosRecordSet record_set = null;
+ FileInputStream in = new FileInputStream(file);
if (filename.endsWith("eeprom")) {
- FileReader in = new FileReader(file);
- states = new AltosEepromFile(in);
+ record_set = new AltosEepromRecordSet(in);
} else if (filename.endsWith("telem")) {
- FileInputStream in = new FileInputStream(file);
- states = new AltosTelemetryFile(in);
+ record_set = new AltosTelemetryFile(in);
} else {
throw new FileNotFoundException(filename);
}
try {
- new AltosGraphUI(states, file);
+ new AltosGraphUI(record_set, file);
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
import java.io.*;
import java.util.concurrent.*;
import java.awt.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosLaunch {
AltosDevice device;
import java.io.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
class FireButton extends JButton {
protected void processMouseEvent(MouseEvent e) {
package altosui;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosPad extends AltosUIFlightTab {
class LoggingReady extends AltosUIIndicator {
public void show (AltosState state, AltosListenerState listener_state) {
- if (state == null || state.flight == AltosLib.MISSING) {
+ AltosCalData cal_data = state.cal_data();
+ if (state == null || cal_data.flight == AltosLib.MISSING) {
hide();
} else {
- if (state.flight != 0) {
+ if (cal_data.flight != 0) {
if (state.state() <= Altos.ao_flight_pad)
show("Ready to record");
else if (state.state() < Altos.ao_flight_landed ||
show("Recorded data");
} else
show("Storage full");
- set_lights(state.flight != 0);
+ set_lights(cal_data.flight != 0);
}
}
public LoggingReady (AltosUIFlightTab container, int y) {
}
boolean report_pad(AltosState state) {
- if ((state.state() == AltosLib.ao_flight_stateless ||
- state.state() < AltosLib.ao_flight_pad) &&
- state.gps != null &&
- state.gps.lat != AltosLib.MISSING)
+ if (state.state() == AltosLib.ao_flight_stateless ||
+ state.state() < AltosLib.ao_flight_pad)
{
return false;
}
if (report_pad(state)) {
lat = state.pad_lat;
label = "Pad Latitude";
- } else {
+ } else if (state.gps != null) {
lat = state.gps.lat;
label = "Latitude";
}
if (report_pad(state)) {
lon = state.pad_lon;
label = "Pad Longitude";
- } else {
+ } else if (state.gps != null) {
lon = state.gps.lon;
label = "Longitude";
}
public double value(AltosState state, int i) {
if (report_pad(state))
return state.pad_alt;
- else
+ else if (state.gps != null)
return state.gps.alt;
+ else
+ return state.altitude();
}
public void show (AltosState state, AltosListenerState listener_state) {
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class AltosUI extends AltosUIFrame {
public AltosVoice voice = new AltosVoice();
AltosDataChooser chooser = new AltosDataChooser(
AltosUI.this);
- Iterable<AltosState> states = chooser.runDialog();
- if (states != null) {
- AltosFlightReader reader = new AltosReplayReader(states.iterator(),
- chooser.file());
+ AltosRecordSet set = chooser.runDialog();
+ if (set != null) {
+ AltosReplayReader reader = new AltosReplayReader(set, chooser.file());
new AltosFlightUI(voice, reader);
}
}
new AltosEepromManage(AltosUI.this, AltosLib.product_any);
}
+ private static AltosFlightSeries make_series(AltosRecordSet set) {
+ AltosFlightSeries series = new AltosFlightSeries(set.cal_data());
+ set.capture_series(series);
+ series.finish();
+ return series;
+ }
+
/* Load a flight log file and write out a CSV file containing
* all of the data in standard units
*/
private void ExportData() {
AltosDataChooser chooser;
chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
- new AltosCSVUI(AltosUI.this, states, chooser.file());
+ AltosFlightSeries series = make_series(set);
+ new AltosCSVUI(AltosUI.this, series, chooser.file());
}
/* Load a flight log CSV file and display a pretty graph.
private void GraphData() {
AltosDataChooser chooser;
chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
try {
- new AltosGraphUI(states, chooser.file());
+ new AltosGraphUI(set, chooser.file());
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
}
}
- static AltosStateIterable open_logfile(File file) {
- try {
- if (file.getName().endsWith("telem"))
- return new AltosTelemetryFile(new FileInputStream(file));
- else
- return new AltosEepromFile(new FileReader(file));
- } catch (FileNotFoundException fe) {
- System.out.printf("%s\n", fe.getMessage());
- return null;
- } catch (IOException ie) {
- System.out.printf("%s\n", ie.getMessage());
- return null;
- }
- }
-
static AltosWriter open_csv(File file) {
try {
return new AltosCSV(file);
}
}
+ static AltosRecordSet record_set(File input) {
+ try {
+ return AltosLib.record_set(input);
+ } catch (IOException ie) {
+ String message = ie.getMessage();
+ if (message == null)
+ message = String.format("%s (I/O error)", input.toString());
+ System.err.printf("%s\n", message);
+ }
+ return null;
+ }
+
static final int process_none = 0;
static final int process_csv = 1;
static final int process_kml = 2;
static final int process_graph = 3;
static final int process_replay = 4;
static final int process_summary = 5;
- static final int process_cat = 6;
static boolean process_csv(File input) {
- AltosStateIterable states = open_logfile(input);
- if (states == null)
+ AltosRecordSet set = record_set(input);
+ if (set == null)
return false;
File output = Altos.replace_extension(input,".csv");
AltosWriter writer = open_csv(output);
if (writer == null)
return false;
- writer.write(states);
+ AltosFlightSeries series = make_series(set);
+ writer.write(series);
writer.close();
}
return true;
}
static boolean process_kml(File input) {
- AltosStateIterable states = open_logfile(input);
- if (states == null)
+ AltosRecordSet set = record_set(input);
+ if (set == null)
return false;
File output = Altos.replace_extension(input,".kml");
AltosWriter writer = open_kml(output);
if (writer == null)
return false;
- writer.write(states);
+ AltosFlightSeries series = make_series(set);
+ series.finish();
+ writer.write(series);
writer.close();
return true;
}
}
- static AltosStateIterable record_iterable(File file) {
- FileInputStream in;
- if (file.getName().endsWith("telem")) {
- try {
- in = new FileInputStream(file);
- return new AltosTelemetryFile(in);
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
- }
- } else {
-
- try {
- AltosEepromFile f = new AltosEepromFile(new FileReader(file));
- return f;
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
- }
- }
- return null;
- }
-
static AltosReplayReader replay_file(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return null;
- return new AltosReplayReader(states.iterator(), file);
+ return new AltosReplayReader(set, file);
}
static boolean process_replay(File file) {
}
static boolean process_graph(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return false;
try {
- new AltosGraphUI(states, file);
+ new AltosGraphUI(set, file);
return true;
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
static boolean process_summary(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
- return false;
- try {
- System.out.printf("%s:\n", file.toString());
- AltosFlightStats stats = new AltosFlightStats(states);
- if (stats.serial != AltosLib.MISSING)
- System.out.printf("Serial: %5d\n", stats.serial);
- if (stats.flight != AltosLib.MISSING)
- System.out.printf("Flight: %5d\n", stats.flight);
- if (stats.year != AltosLib.MISSING)
- System.out.printf("Date: %04d-%02d-%02d\n",
- stats.year, stats.month, stats.day);
- if (stats.hour != AltosLib.MISSING)
- System.out.printf("Time: %02d:%02d:%02d UTC\n",
- stats.hour, stats.minute, stats.second);
- if (stats.max_height != AltosLib.MISSING)
- System.out.printf("Max height: %6.0f m %6.0f ft\n",
- stats.max_height,
- AltosConvert.meters_to_feet(stats.max_height));
- if (stats.max_speed != AltosLib.MISSING)
- System.out.printf("Max speed: %6.0f m/s %6.0f ft/s %6.4f Mach\n",
- stats.max_speed,
- AltosConvert.meters_to_feet(stats.max_speed),
- AltosConvert.meters_to_mach(stats.max_speed));
- if (stats.max_acceleration != AltosLib.MISSING) {
- System.out.printf("Max accel: %6.0f m/s² %6.0f ft/s² %6.2f g\n",
- stats.max_acceleration,
- AltosConvert.meters_to_feet(stats.max_acceleration),
- AltosConvert.meters_to_g(stats.max_acceleration));
- }
- if (stats.state_speed[Altos.ao_flight_drogue] != AltosLib.MISSING)
- System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n",
- stats.state_speed[Altos.ao_flight_drogue],
- AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
- if (stats.state_speed[Altos.ao_flight_main] != AltosLib.MISSING)
- System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n",
- stats.state_speed[Altos.ao_flight_main],
- AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
- if (stats.state_end[Altos.ao_flight_main] != AltosLib.MISSING &&
- stats.state_start[Altos.ao_flight_boost] != AltosLib.MISSING)
- System.out.printf("Flight time: %6.0f s\n",
- stats.state_end[Altos.ao_flight_main] -
- stats.state_start[Altos.ao_flight_boost]);
- System.out.printf("\n");
- return true;
- } catch (InterruptedException ie) {
- } catch (IOException ie) {
- }
- return false;
- }
-
- static boolean process_cat(File file) {
- try {
- AltosStateIterable eef = record_iterable(file);
-
- for (AltosState state : eef) {
- if ((state.set & AltosState.set_gps) != 0) {
- System.out.printf ("time %d %d-%d-%d %d:%d:%d lat %g lon %g alt %g\n",
- state.gps.seconds(),
- state.gps.year,
- state.gps.month,
- state.gps.day,
- state.gps.hour,
- state.gps.minute,
- state.gps.second,
- state.gps.lat,
- state.gps.lon,
- state.gps.alt);
- } else {
- System.out.printf ("tick %d state %d height %g\n",
- state.tick, state.state(), state.height());
- }
- }
-
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return false;
+ System.out.printf("%s:\n", file.toString());
+ AltosFlightSeries series = make_series(set);
+ AltosFlightStats stats = new AltosFlightStats(series);
+ if (stats.serial != AltosLib.MISSING)
+ System.out.printf("Serial: %5d\n", stats.serial);
+ if (stats.flight != AltosLib.MISSING)
+ System.out.printf("Flight: %5d\n", stats.flight);
+ if (stats.year != AltosLib.MISSING)
+ System.out.printf("Date: %04d-%02d-%02d\n",
+ stats.year, stats.month, stats.day);
+ if (stats.hour != AltosLib.MISSING)
+ System.out.printf("Time: %02d:%02d:%02d UTC\n",
+ stats.hour, stats.minute, stats.second);
+ if (stats.max_height != AltosLib.MISSING)
+ System.out.printf("Max height: %6.0f m %6.0f ft\n",
+ stats.max_height,
+ AltosConvert.meters_to_feet(stats.max_height));
+ if (stats.max_speed != AltosLib.MISSING)
+ System.out.printf("Max speed: %6.0f m/s %6.0f ft/s %6.4f Mach\n",
+ stats.max_speed,
+ AltosConvert.meters_to_feet(stats.max_speed),
+ AltosConvert.meters_to_mach(stats.max_speed));
+ if (stats.max_acceleration != AltosLib.MISSING) {
+ System.out.printf("Max accel: %6.0f m/s² %6.0f ft/s² %6.2f g\n",
+ stats.max_acceleration,
+ AltosConvert.meters_to_feet(stats.max_acceleration),
+ AltosConvert.meters_to_g(stats.max_acceleration));
}
+ if (stats.state_speed[Altos.ao_flight_drogue] != AltosLib.MISSING)
+ System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n",
+ stats.state_speed[Altos.ao_flight_drogue],
+ AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
+ if (stats.state_speed[Altos.ao_flight_main] != AltosLib.MISSING)
+ System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n",
+ stats.state_speed[Altos.ao_flight_main],
+ AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
+ if (stats.state_end[Altos.ao_flight_main] != AltosLib.MISSING &&
+ stats.state_start[Altos.ao_flight_boost] != AltosLib.MISSING)
+ System.out.printf("Flight time: %6.0f s\n",
+ stats.state_end[Altos.ao_flight_main] -
+ stats.state_start[Altos.ao_flight_boost]);
+ System.out.printf("\n");
return true;
}
process = process_graph;
else if (args[i].equals("--summary"))
process = process_summary;
- else if (args[i].equals("--cat"))
- process = process_cat;
else if (args[i].startsWith("--"))
help(1);
else {
if (!process_summary(file))
++errors;
break;
- case process_cat:
- if (!process_cat(file))
- ++errors;
}
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosBTDevice extends altos_bt_device implements AltosDevice {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
AltosBTDevice current;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosBTKnown implements Iterable<AltosBTDevice> {
LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.basic.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {
LinkedBlockingQueue<AltosBTDevice> found_devices;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosCSVUI
extends AltosUIDialog
JFileChooser csv_chooser;
JPanel accessory;
JComboBox<String> combo_box;
- Iterable<AltosState> states;
+ AltosFlightSeries series;
+ AltosCalData cal_data;
AltosWriter writer;
static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" };
set_default_file();
}
- public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) {
- this.states = states;
+ public AltosCSVUI(JFrame frame, AltosFlightSeries series, File source_file) {
+ this.series = series;
+ this.cal_data = series.cal_data();
csv_chooser = new JFileChooser(source_file);
accessory = new JPanel();
writer = new AltosCSV(file);
else
writer = new AltosKML(file);
- writer.write(states);
+ writer.write(series);
writer.close();
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(frame,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class AltosEditFreqUI extends AltosUIDialog implements ActionListener {
Frame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosDataChooser extends JFileChooser {
JFrame frame;
return file;
}
- public AltosStateIterable runDialog() {
+ public AltosRecordSet runDialog() {
int ret;
ret = showOpenDialog(frame);
file = getSelectedFile();
if (file == null)
return null;
- filename = file.getName();
try {
- if (filename.endsWith("eeprom")) {
- FileReader in = new FileReader(file);
- return new AltosEepromFile(in);
- } else if (filename.endsWith("telem")) {
- FileInputStream in = new FileInputStream(file);
- return new AltosTelemetryFile(in);
- } else {
- throw new FileNotFoundException();
- }
- } catch (FileNotFoundException fe) {
- JOptionPane.showMessageDialog(frame,
- fe.getMessage(),
- "Cannot open file",
- JOptionPane.ERROR_MESSAGE);
+ return AltosLib.record_set(file);
} catch (IOException ie) {
JOptionPane.showMessageDialog(frame,
ie.getMessage(),
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import libaltosJNI.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosDisplayThread extends Thread {
IdleThread idle_thread;
AltosVoice voice;
AltosFlightReader reader;
- AltosState old_state, state;
+ AltosState state;
+ int old_state = AltosLib.ao_flight_invalid;
+ boolean old_gps_ready = false;
AltosListenerState listener_state;
AltosFlightDisplay display;
state.from_pad != null &&
state.range >= 0)
{
- voice.speak("Height %s, bearing %s %d, elevation %d, range %s.\n",
+ voice.speak("Height %s, bearing %s %d, elevation %d, distance %s.\n",
AltosConvert.height.say(state.height()),
state.from_pad.bearing_words(
AltosGreatCircle.BEARING_VOICE),
(int) (state.from_pad.bearing + 0.5),
(int) (state.elevation + 0.5),
- AltosConvert.distance.say(state.range));
+ AltosConvert.distance.say(state.distance));
} else if (state.state() > AltosLib.ao_flight_pad && state.height() != AltosLib.MISSING) {
voice.speak(AltosConvert.height.say_units(state.height()));
} else {
else
voice.speak("rocket may have crashed");
if (state.from_pad != null)
- voice.speak("Bearing %d degrees, range %s.",
+ voice.speak("Bearing %d degrees, distance %s.",
(int) (state.from_pad.bearing + 0.5),
AltosConvert.distance.say_units(state.from_pad.distance));
++reported_landing;
}
public synchronized void notice(boolean spoken) {
- if (old_state != null && old_state.state() != state.state()) {
+ if (old_state != state.state()) {
report_time = now();
this.notify();
} else if (spoken)
synchronized boolean tell() {
boolean ret = false;
- if (old_state == null || old_state.state() != state.state()) {
+ if (old_state != state.state()) {
if (state.state() != AltosLib.ao_flight_stateless)
voice.speak(state.state_name());
- if ((old_state == null || old_state.state() <= AltosLib.ao_flight_boost) &&
+ if ((old_state == AltosLib.ao_flight_invalid || old_state <= AltosLib.ao_flight_boost) &&
state.state() > AltosLib.ao_flight_boost) {
if (state.max_speed() != AltosLib.MISSING)
voice.speak("max speed: %s.",
AltosConvert.speed.say_units(state.max_speed() + 0.5));
ret = true;
- } else if ((old_state == null || old_state.state() < AltosLib.ao_flight_drogue) &&
+ } else if ((old_state == AltosLib.ao_flight_invalid || old_state < AltosLib.ao_flight_drogue) &&
state.state() >= AltosLib.ao_flight_drogue) {
if (state.max_height() != AltosLib.MISSING)
voice.speak("max height: %s.",
ret = true;
}
}
- if (old_state == null || old_state.gps_ready != state.gps_ready) {
+ if (old_gps_ready != state.gps_ready) {
if (state.gps_ready) {
voice.speak("GPS ready");
ret = true;
}
- else if (old_state != null) {
+ else if (old_gps_ready) {
voice.speak("GPS lost");
ret = true;
}
}
- old_state = state;
+ old_state = state.state();
+ old_gps_ready = state.gps_ready;
return ret;
}
try {
for (;;) {
try {
- AltosState new_state = reader.read();
- if (new_state == null) {
- state = null;
+ state = reader.read();
+ if (state == null) {
listener_state.running = false;
break;
}
- reader.update(new_state);
- state = new_state;
show_safely();
told = tell();
idle_thread.notice(told);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosEepromDelete implements Runnable {
AltosEepromList flights;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosEepromManage implements ActionListener {
+++ /dev/null
-/*
- * Copyright © 2010 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altosuilib_11;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-public class AltosEepromMonitor extends AltosUIDialog {
-
- Container pane;
- Box box;
- JLabel serial_label;
- JLabel flight_label;
- JLabel file_label;
- JLabel serial_value;
- JLabel flight_value;
- JLabel file_value;
- JButton cancel;
- JProgressBar pbar;
- int min_state, max_state;
-
- public AltosEepromMonitor(JFrame owner, int in_min_state, int in_max_state) {
- super (owner, "Download Flight Data", false);
-
- GridBagConstraints c;
- Insets il = new Insets(4,4,4,4);
- Insets ir = new Insets(4,4,4,4);
-
- pane = getContentPane();
- pane.setLayout(new GridBagLayout());
-
- c = new GridBagConstraints();
- c.gridx = 0; c.gridy = 0;
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = il;
- serial_label = new JLabel("Serial:");
- pane.add(serial_label, c);
-
- c = new GridBagConstraints();
- c.gridx = 1; c.gridy = 0;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = ir;
- serial_value = new JLabel("");
- pane.add(serial_value, c);
-
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.NONE;
- c.gridx = 0; c.gridy = 1;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = il;
- flight_label = new JLabel("Flight:");
- pane.add(flight_label, c);
-
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.gridx = 1; c.gridy = 1;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = ir;
- flight_value = new JLabel("");
- pane.add(flight_value, c);
-
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.NONE;
- c.gridx = 0; c.gridy = 2;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = il;
- file_label = new JLabel("File:");
- pane.add(file_label, c);
-
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.HORIZONTAL;
- c.weightx = 1;
- c.gridx = 1; c.gridy = 2;
- c.anchor = GridBagConstraints.LINE_START;
- c.insets = ir;
- file_value = new JLabel("");
- pane.add(file_value, c);
-
- min_state = in_min_state;
- max_state = in_max_state;
- pbar = new JProgressBar();
- pbar.setMinimum(0);
- pbar.setMaximum(1000);
- pbar.setValue(0);
- pbar.setString("startup");
- pbar.setStringPainted(true);
- pbar.setPreferredSize(new Dimension(600, 20));
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.gridx = 0; c.gridy = 3;
- c.gridwidth = GridBagConstraints.REMAINDER;
- Insets ib = new Insets(4,4,4,4);
- c.insets = ib;
- pane.add(pbar, c);
-
-
- cancel = new JButton("Cancel");
- c = new GridBagConstraints();
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.gridx = 0; c.gridy = 4;
- c.gridwidth = GridBagConstraints.REMAINDER;
- Insets ic = new Insets(4,4,4,4);
- c.insets = ic;
- pane.add(cancel, c);
-
- pack();
- setLocationRelativeTo(owner);
- setVisible(true);
- }
-
- public void addActionListener (ActionListener l) {
- cancel.addActionListener(l);
- }
-
- private void set_value_internal(String state_name, int state, int state_block, int block) {
- if (state_block > 100)
- state_block = 100;
- if (state < min_state) state = min_state;
- if (state >= max_state) state = max_state - 1;
- state -= min_state;
-
- int pos = state * 100 + state_block;
-
- pbar.setString(String.format("block %d state %s", block, state_name));
- pbar.setValue(pos);
- }
-
- public void set_value(String in_state_name, int in_state, int in_state_block, int in_block) {
- final String state_name = in_state_name;
- final int state = in_state;
- final int state_block = in_state_block;
- final int block = in_block;
- Runnable r = new Runnable() {
- public void run() {
- try {
- set_value_internal(state_name, state, state_block, block);
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
- private void set_serial_internal(int serial) {
- serial_value.setText(String.format("%d", serial));
- }
-
- public void set_serial(int in_serial) {
- final int serial = in_serial;
- Runnable r = new Runnable() {
- public void run() {
- try {
- set_serial_internal(serial);
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
- private void set_flight_internal(int flight) {
- flight_value.setText(String.format("%d", flight));
- }
-
- public void set_flight(int in_flight) {
- final int flight = in_flight;
- Runnable r = new Runnable() {
- public void run() {
- try {
- set_flight_internal(flight);
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
- private void set_file_internal(String file) {
- file_value.setText(String.format("%s", file));
- }
-
- public void set_file(String in_file) {
- final String file = in_file;
- Runnable r = new Runnable() {
- public void run() {
- try {
- set_file_internal(file);
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
- private void done_internal() {
- setVisible(false);
- dispose();
- }
-
- public void done() {
- Runnable r = new Runnable() {
- public void run() {
- try {
- done_internal();
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-
- private void reset_internal() {
- set_value_internal("startup",min_state,0, 0);
- set_flight_internal(0);
- set_file_internal("");
- }
-
- public void reset() {
- Runnable r = new Runnable() {
- public void run() {
- try {
- reset_internal();
- } catch (Exception ex) {
- }
- }
- };
- SwingUtilities.invokeLater(r);
- }
-}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor {
JFrame owner;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class AltosEepromItem implements ActionListener {
AltosEepromLog log;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosFlashUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.table.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosFlightStatsTable extends JComponent implements AltosFontListener {
GridBagLayout layout;
return String.format("%s %4d° %9.6f'", h, deg, min);
}
- public AltosFlightStatsTable(AltosFlightStats stats) {
- layout = new GridBagLayout();
-
- setLayout(layout);
+ public void set_stats(AltosFlightStats stats) {
int y = 0;
- new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial));
- new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight));
+ if (stats.serial != AltosLib.MISSING) {
+ if (stats.product != null && stats.firmware_version != null)
+ new FlightStat(layout, y++, "Device",
+ stats.product,
+ String.format("version %s", stats.firmware_version),
+ String.format("serial %d", stats.serial));
+ else
+ new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial));
+ }
+ if (stats.flight != AltosLib.MISSING)
+ new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight));
if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING)
new FlightStat(layout, y++, "Date/Time",
String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day),
}
if (stats.max_height != AltosLib.MISSING) {
new FlightStat(layout, y++, "Maximum height",
- String.format("%5.0f m", stats.max_height),
+ String.format("%6.1f m", stats.max_height),
String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_height)));
}
if (stats.max_gps_height != AltosLib.MISSING) {
new FlightStat(layout, y++, "Maximum GPS height",
- String.format("%5.0f m", stats.max_gps_height),
+ String.format("%6.1f m", stats.max_gps_height),
String.format("%5.0f ft", AltosConvert.meters_to_feet(stats.max_gps_height)));
}
- new FlightStat(layout, y++, "Maximum speed",
- String.format("%5.0f m/s", stats.max_speed),
- String.format("%5.0f fps", AltosConvert.mps_to_fps(stats.max_speed)),
- String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed)));
+ if (stats.max_speed != AltosLib.MISSING) {
+ new FlightStat(layout, y++, "Maximum speed",
+ String.format("%6.1f m/s", stats.max_speed),
+ String.format("%5.0f fps", AltosConvert.mps_to_fps(stats.max_speed)),
+ String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed)));
+ }
if (stats.max_acceleration != AltosLib.MISSING)
new FlightStat(layout, y++, "Maximum boost acceleration",
- String.format("%5.0f m/s²", stats.max_acceleration),
+ String.format("%6.1f m/s²", stats.max_acceleration),
String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)),
- String.format("%5.0f G", AltosConvert.meters_to_g(stats.max_acceleration)));
+ String.format("%6.2f G", AltosConvert.meters_to_g(stats.max_acceleration)));
if (stats.state_accel[AltosLib.ao_flight_boost] != AltosLib.MISSING)
new FlightStat(layout, y++, "Average boost acceleration",
- String.format("%5.0f m/s²", stats.state_accel[AltosLib.ao_flight_boost]),
+ String.format("%6.1f m/s²", stats.state_accel[AltosLib.ao_flight_boost]),
String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.state_accel[AltosLib.ao_flight_boost])),
- String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[AltosLib.ao_flight_boost])));
- if (stats.state_speed[AltosLib.ao_flight_drogue] != AltosLib.MISSING)
- new FlightStat(layout, y++, "Drogue descent rate",
- String.format("%5.0f m/s", stats.state_speed[AltosLib.ao_flight_drogue]),
- String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_drogue])));
+ String.format("%6.2f G", AltosConvert.meters_to_g(stats.state_accel[AltosLib.ao_flight_boost])));
+ if (stats.state_time[AltosLib.ao_flight_boost] != 0 || stats.state_time[AltosLib.ao_flight_fast] != 0 || stats.state_time[AltosLib.ao_flight_coast] != 0) {
+
+ double boost_time = stats.state_time[AltosLib.ao_flight_boost];
+ double fast_time = stats.state_time[AltosLib.ao_flight_fast];
+ double coast_time = stats.state_time[AltosLib.ao_flight_coast];
+
+ if (fast_time > 0) {
+ new FlightStat(layout, y++, "Ascent time",
+ String.format("%6.1f s %s", boost_time,
+ AltosLib.state_name(AltosLib.ao_flight_boost)),
+ String.format("%6.1f s %s", fast_time,
+ AltosLib.state_name(AltosLib.ao_flight_fast)),
+ String.format("%6.1f s %s", coast_time,
+ AltosLib.state_name(AltosLib.ao_flight_coast)));
+ } else {
+ new FlightStat(layout, y++, "Ascent time",
+ String.format("%6.1f s %s", boost_time,
+ AltosLib.state_name(AltosLib.ao_flight_boost)),
+ String.format("%6.1f s %s", coast_time,
+ AltosLib.state_name(AltosLib.ao_flight_coast)));
+ }
+ }
+ if (stats.state_speed[AltosLib.ao_flight_drogue] != AltosLib.MISSING) {
+ String label;
+
+ if (stats.state_speed[AltosLib.ao_flight_main] == AltosLib.MISSING)
+ label = "Descent rate";
+ else
+ label = "Drogue descent rate";
+ new FlightStat(layout, y++, label,
+ String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_drogue]),
+ String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_drogue])));
+ }
if (stats.state_speed[AltosLib.ao_flight_main] != AltosLib.MISSING)
new FlightStat(layout, y++, "Main descent rate",
- String.format("%5.0f m/s", stats.state_speed[AltosLib.ao_flight_main]),
- String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_main])));
- if (stats.state_start[AltosLib.ao_flight_boost] < stats.state_end[AltosLib.ao_flight_coast])
- new FlightStat(layout, y++, "Ascent time",
- String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost],
- AltosLib.state_name(AltosLib.ao_flight_boost)),
- String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_fast] - stats.state_start[AltosLib.ao_flight_fast],
- AltosLib.state_name(AltosLib.ao_flight_fast)),
- String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_coast] - stats.state_start[AltosLib.ao_flight_coast],
- AltosLib.state_name(AltosLib.ao_flight_coast)));
- if (stats.state_start[AltosLib.ao_flight_drogue] < stats.state_end[AltosLib.ao_flight_main])
- new FlightStat(layout, y++, "Descent time",
- String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_drogue] - stats.state_start[AltosLib.ao_flight_drogue],
- AltosLib.state_name(AltosLib.ao_flight_drogue)),
- String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_main] - stats.state_start[AltosLib.ao_flight_main],
- AltosLib.state_name(AltosLib.ao_flight_main)));
- if (stats.state_start[AltosLib.ao_flight_boost] < stats.state_end[AltosLib.ao_flight_main])
+ String.format("%6.1f m/s", -stats.state_speed[AltosLib.ao_flight_main]),
+ String.format("%5.0f ft/s", -AltosConvert.meters_to_feet(stats.state_speed[AltosLib.ao_flight_main])));
+ if (stats.state_time[AltosLib.ao_flight_drogue] != 0 || stats.state_time[AltosLib.ao_flight_main] != 0) {
+ double drogue_duration = stats.state_time[AltosLib.ao_flight_drogue];
+ double main_duration = stats.state_time[AltosLib.ao_flight_main];
+ double duration = drogue_duration + main_duration;
+
+ if (drogue_duration > 0 && main_duration > 0) {
+ new FlightStat(layout, y++, "Descent time",
+ String.format("%6.1f s %s", drogue_duration,
+ AltosLib.state_name(AltosLib.ao_flight_drogue)),
+ String.format("%6.1f s %s", main_duration,
+ AltosLib.state_name(AltosLib.ao_flight_main)));
+ } else if (duration > 0) {
+ new FlightStat(layout, y++, "Descent time",
+ String.format("%6.1f s", duration));
+ }
+ }
+ if (stats.landed_time > stats.boost_time)
new FlightStat(layout, y++, "Flight time",
- String.format("%6.1f s", stats.state_end[AltosLib.ao_flight_main] -
- stats.state_start[AltosLib.ao_flight_boost]));
- if (stats.has_gps) {
+ String.format("%6.1f s", stats.landed_time - stats.boost_time));
+ if (stats.has_gps && stats.pad_lat != AltosLib.MISSING) {
new FlightStat(layout, y++, "Pad location",
pos(stats.pad_lat,"N","S"),
pos(stats.pad_lon,"E","W"));
+ }
+ if (stats.has_gps && stats.lat != AltosLib.MISSING) {
new FlightStat(layout, y++, "Last reported location",
pos(stats.lat,"N","S"),
pos(stats.lon,"E","W"));
}
}
+
+ public void tell_closing() {
+ AltosUIPreferences.unregister_font_listener(this);
+ }
+
+ public AltosFlightStatsTable() {
+ layout = new GridBagLayout();
+
+ setLayout(layout);
+
+ AltosUIPreferences.register_font_listener(this);
+ }
+
+ public AltosFlightStatsTable(AltosFlightStats stats) {
+ this();
+ set_stats(stats);
+ }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
import org.jfree.data.xy.*;
import org.jfree.data.*;
-class AltosVoltage extends AltosUnits {
-
- public double value(double v, boolean imperial_units) {
- return v;
- }
-
- public double inverse(double v, boolean imperial_units) {
- return v;
- }
-
- public String show_units(boolean imperial_units) {
- return "V";
- }
-
- public String say_units(boolean imperial_units) {
- return "volts";
- }
-
- public int show_fraction(int width, boolean imperial_units) {
- return width / 2;
- }
-}
-
-class AltosNsat extends AltosUnits {
-
- public double value(double v, boolean imperial_units) {
- return v;
- }
-
- public double inverse(double v, boolean imperial_units) {
- return v;
- }
-
- public String show_units(boolean imperial_units) {
- return "Sats";
- }
-
- public String say_units(boolean imperial_units) {
- return "Satellites";
- }
-
- public int show_fraction(int width, boolean imperial_units) {
- return 0;
- }
-}
-
-class AltosDbm extends AltosUnits {
-
- public double value(double d, boolean imperial_units) {
- return d;
- }
-
- public double inverse(double d, boolean imperial_units) {
- return d;
- }
-
- public String show_units(boolean imperial_units) {
- return "dBm";
- }
-
- public String say_units(boolean imperial_units) {
- return "D B M";
- }
-
- public int show_fraction(int width, boolean imperial_units) {
- return 0;
- }
-}
-
-class AltosGyroUnits 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 "°/sec";
- }
-
- public String say_units(boolean imperial_units) {
- return "degrees per second";
- }
-
- public int show_fraction(int width, boolean imperial_units) {
- return 1;
- }
-}
-
-class AltosMagUnits 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 "Ga";
- }
-
- public String say_units(boolean imperial_units) {
- return "gauss";
- }
-
- public int show_fraction(int width, boolean imperial_units) {
- return 2;
- }
-}
-
-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);
+ static final private Color kalman_height_color = new Color(255,0,0);
static final private Color gps_height_color = new Color(150,31,31);
static final private Color pressure_color = new Color (225,31,31);
static final private Color range_color = new Color(100, 31, 31);
static final private Color distance_color = new Color(100, 31, 194);
static final private Color speed_color = new Color(31,194,31);
+ static final private Color kalman_speed_color = new Color(0,255,0);
+ static final private Color thrust_color = new Color(31,194,31);
static final private Color accel_color = new Color(31,31,194);
+ static final private Color vert_accel_color = new Color(64,164,164);
+ static final private Color kalman_accel_color = new Color(0,0,255);
static final private Color voltage_color = new Color(194, 194, 31);
static final private Color battery_voltage_color = new Color(194, 194, 31);
static final private Color drogue_voltage_color = new Color(150, 150, 31);
static final private Color main_voltage_color = new Color(100, 100, 31);
+ static final private Color igniter_voltage_color = new Color(80, 80, 31);
+ static final private Color igniter_marker_color = new Color(255, 0, 0);
static final private Color gps_nsat_color = new Color (194, 31, 194);
static final private Color gps_nsat_solution_color = new Color (194, 31, 194);
static final private Color gps_nsat_view_color = new Color (150, 31, 150);
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_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 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);
- static final private Color accel_x_color = new Color(255, 0, 0);
- static final private Color accel_y_color = new Color(0, 255, 0);
- static final private Color accel_z_color = new Color(0, 0, 255);
- static final private Color gyro_x_color = new Color(192, 0, 0);
- static final private Color gyro_y_color = new Color(0, 192, 0);
- static final private Color gyro_z_color = new Color(0, 0, 192);
- static final private Color mag_x_color = new Color(128, 0, 0);
- static final private Color mag_y_color = new Color(0, 128, 0);
- static final private Color mag_z_color = new Color(0, 0, 128);
+ static final private Color accel_along_color = new Color(255, 0, 0);
+ static final private Color accel_across_color = new Color(0, 255, 0);
+ static final private Color accel_through_color = new Color(0, 0, 255);
+ static final private Color gyro_roll_color = new Color(192, 0, 0);
+ static final private Color gyro_pitch_color = new Color(0, 192, 0);
+ static final private Color gyro_yaw_color = new Color(0, 0, 192);
+ static final private Color mag_along_color = new Color(128, 0, 0);
+ static final private Color mag_across_color = new Color(0, 128, 0);
+ static final private Color mag_through_color = new Color(0, 0, 128);
static final private Color orient_color = new Color(31, 31, 31);
- static AltosVoltage voltage_units = new AltosVoltage();
- static AltosPressure pressure_units = new AltosPressure();
- static AltosNsat nsat_units = new AltosNsat();
- static AltosDbm dbm_units = new AltosDbm();
- static AltosGyroUnits gyro_units = new AltosGyroUnits();
- static AltosOrient orient_units = new AltosOrient();
- static AltosMagUnits mag_units = new AltosMagUnits();
- static AltosDopUnits dop_units = new AltosDopUnits();
+ static AltosUnits dop_units = null;
+
+ AltosUIFlightSeries flight_series;
- 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, dop_axis;
+ AltosUITimeSeries[] setup(AltosFlightStats stats, AltosUIFlightSeries flight_series) {
+ AltosCalData cal_data = flight_series.cal_data();
- public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) {
- super(enable);
+ AltosUIAxis height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis;
+ AltosUIAxis distance_axis, pressure_axis, thrust_axis;
+ AltosUIAxis gyro_axis, orient_axis, mag_axis;
+ AltosUIAxis course_axis, dop_axis;
+
+ if (stats.serial != AltosLib.MISSING && stats.product != null && stats.flight != AltosLib.MISSING)
+ setName(String.format("%s %d flight %d\n", stats.product, stats.serial, stats.flight));
height_axis = newAxis("Height", AltosConvert.height, height_color);
- pressure_axis = newAxis("Pressure", pressure_units, pressure_color, 0);
+ pressure_axis = newAxis("Pressure", AltosConvert.pressure, pressure_color, 0);
speed_axis = newAxis("Speed", AltosConvert.speed, speed_color);
+ thrust_axis = newAxis("Thrust", AltosConvert.force, thrust_color);
accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color);
- voltage_axis = newAxis("Voltage", voltage_units, voltage_color);
+ voltage_axis = newAxis("Voltage", AltosConvert.voltage, voltage_color);
temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0);
- nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color,
+ nsat_axis = newAxis("Satellites", null, gps_nsat_color,
AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer);
- dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0);
+ dbm_axis = newAxis("Signal Strength", null, dbm_color, 0);
distance_axis = newAxis("Distance", AltosConvert.distance, range_color);
- gyro_axis = newAxis("Rotation Rate", gyro_units, gyro_z_color, 0);
- 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);
+ gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_roll_color, 0);
+ orient_axis = newAxis("Tilt Angle", AltosConvert.orient, orient_color, 0);
+ mag_axis = newAxis("Magnetic Field", AltosConvert.magnetic_field, mag_along_color, 0);
+ course_axis = newAxis("Course", AltosConvert.orient, gps_course_color, 0);
dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0);
- addMarker("State", AltosGraphDataPoint.data_state, state_color);
-
- if (stats.has_flight_data) {
- addSeries("Height",
- AltosGraphDataPoint.data_height,
- AltosConvert.height,
- height_color,
- true,
- height_axis);
- addSeries("Pressure",
- AltosGraphDataPoint.data_pressure,
- pressure_units,
- pressure_color,
- false,
- pressure_axis);
- addSeries("Speed",
- AltosGraphDataPoint.data_speed,
- AltosConvert.speed,
- speed_color,
- true,
- speed_axis);
- addSeries("Acceleration",
- AltosGraphDataPoint.data_accel,
- AltosConvert.accel,
- accel_color,
- true,
- accel_axis);
- }
- if (stats.has_gps) {
- boolean enable_gps = false;
-
- if (!stats.has_flight_data)
- enable_gps = true;
-
- addSeries("Range",
- AltosGraphDataPoint.data_range,
- AltosConvert.distance,
- range_color,
- false,
- distance_axis);
- addSeries("Distance",
- AltosGraphDataPoint.data_distance,
- AltosConvert.distance,
- distance_color,
- enable_gps,
- distance_axis);
- addSeries("GPS Height",
- AltosGraphDataPoint.data_gps_height,
- AltosConvert.height,
- gps_height_color,
- enable_gps,
- height_axis);
- addSeries("GPS Altitude",
- AltosGraphDataPoint.data_gps_altitude,
- AltosConvert.height,
- gps_height_color,
- false,
- height_axis);
- addSeries("GPS Satellites in Solution",
- AltosGraphDataPoint.data_gps_nsat_solution,
- nsat_units,
- gps_nsat_solution_color,
- false,
- nsat_axis);
- if (stats.has_gps_sats) {
- addSeries("GPS Satellites in View",
- AltosGraphDataPoint.data_gps_nsat_view,
- nsat_units,
- gps_nsat_view_color,
- false,
- nsat_axis);
- }
- if (stats.has_gps_detail) {
- addSeries("GPS Course",
- AltosGraphDataPoint.data_gps_course,
- orient_units,
- gps_course_color,
- false,
- course_axis);
- addSeries("GPS Ground Speed",
- AltosGraphDataPoint.data_gps_ground_speed,
- AltosConvert.speed,
- gps_ground_speed_color,
- enable_gps,
- speed_axis);
- addSeries("GPS Climb Rate",
- AltosGraphDataPoint.data_gps_climb_rate,
- AltosConvert.speed,
- gps_climb_rate_color,
- enable_gps,
- speed_axis);
- }
- addSeries("GPS Position DOP",
- AltosGraphDataPoint.data_gps_pdop,
- dop_units,
- gps_pdop_color,
- false,
- dop_axis);
- if (stats.has_gps_detail) {
- 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",
- AltosGraphDataPoint.data_rssi,
- dbm_units,
- dbm_color,
- false,
- dbm_axis);
-
- if (stats.has_battery)
- addSeries("Battery Voltage",
- AltosGraphDataPoint.data_battery_voltage,
- voltage_units,
- battery_voltage_color,
- false,
- voltage_axis);
-
- if (stats.has_flight_adc) {
- addSeries("Temperature",
- AltosGraphDataPoint.data_temperature,
- AltosConvert.temperature,
- temperature_color,
- false,
- temperature_axis);
- addSeries("Drogue Voltage",
- AltosGraphDataPoint.data_drogue_voltage,
- voltage_units,
- drogue_voltage_color,
- false,
- voltage_axis);
- addSeries("Main Voltage",
- AltosGraphDataPoint.data_main_voltage,
- voltage_units,
- main_voltage_color,
- false,
- voltage_axis);
+ flight_series.register_axis("default",
+ speed_color,
+ false,
+ speed_axis);
+
+ flight_series.register_marker(AltosUIFlightSeries.state_name,
+ state_color,
+ true,
+ plot,
+ true);
+
+ flight_series.register_marker(AltosUIFlightSeries.pyro_fired_name,
+ igniter_marker_color,
+ true,
+ plot,
+ false);
+
+ flight_series.register_axis(AltosUIFlightSeries.accel_name,
+ accel_color,
+ true,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.vert_accel_name,
+ vert_accel_color,
+ true,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.kalman_accel_name,
+ kalman_accel_color,
+ false,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.rssi_name,
+ dbm_color,
+ false,
+ dbm_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.speed_name,
+ speed_color,
+ true,
+ speed_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.kalman_speed_name,
+ kalman_speed_color,
+ true,
+ speed_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.pressure_name,
+ pressure_color,
+ false,
+ pressure_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.height_name,
+ height_color,
+ true,
+ height_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.altitude_name,
+ height_color,
+ false,
+ height_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.kalman_height_name,
+ kalman_height_color,
+ false,
+ height_axis);
+
+
+ flight_series.register_axis(AltosUIFlightSeries.temperature_name,
+ temperature_color,
+ false,
+ temperature_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.battery_voltage_name,
+ battery_voltage_color,
+ false,
+ voltage_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.apogee_voltage_name,
+ drogue_voltage_color,
+ false,
+ voltage_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.main_voltage_name,
+ main_voltage_color,
+ false,
+ voltage_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.sats_in_view_name,
+ gps_nsat_view_color,
+ false,
+ nsat_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.sats_in_soln_name,
+ gps_nsat_solution_color,
+ false,
+ nsat_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_pdop_name,
+ gps_pdop_color,
+ false,
+ dop_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_hdop_name,
+ gps_hdop_color,
+ false,
+ dop_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_vdop_name,
+ gps_vdop_color,
+ false,
+ dop_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_altitude_name,
+ gps_height_color,
+ false,
+ height_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_height_name,
+ gps_height_color,
+ false,
+ height_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_ground_speed_name,
+ gps_ground_speed_color,
+ false,
+ speed_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_ascent_rate_name,
+ gps_climb_rate_color,
+ false,
+ speed_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_course_name,
+ gps_course_color,
+ false,
+ course_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gps_speed_name,
+ gps_speed_color,
+ false,
+ speed_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.accel_along_name,
+ accel_along_color,
+ false,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.accel_across_name,
+ accel_across_color,
+ false,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.accel_through_name,
+ accel_through_color,
+ false,
+ accel_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gyro_roll_name,
+ gyro_roll_color,
+ false,
+ gyro_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gyro_pitch_name,
+ gyro_pitch_color,
+ false,
+ gyro_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.gyro_yaw_name,
+ gyro_yaw_color,
+ false,
+ gyro_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.mag_along_name,
+ mag_along_color,
+ false,
+ mag_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.mag_across_name,
+ mag_across_color,
+ false,
+ mag_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.mag_through_name,
+ mag_through_color,
+ false,
+ mag_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.orient_name,
+ orient_color,
+ false,
+ orient_axis);
+
+ for (int channel = 0; channel < 26; channel++) {
+ flight_series.register_axis(flight_series.igniter_voltage_name(channel),
+ igniter_voltage_color,
+ false,
+ voltage_axis);
}
- if (stats.has_imu) {
- addSeries("Acceleration Along",
- AltosGraphDataPoint.data_accel_along,
- AltosConvert.accel,
- accel_x_color,
- false,
- accel_axis);
- addSeries("Acceleration Across",
- AltosGraphDataPoint.data_accel_across,
- AltosConvert.accel,
- accel_y_color,
- false,
- accel_axis);
- addSeries("Acceleration Through",
- AltosGraphDataPoint.data_accel_through,
- AltosConvert.accel,
- accel_z_color,
- false,
- accel_axis);
- addSeries("Roll Rate",
- AltosGraphDataPoint.data_gyro_roll,
- gyro_units,
- gyro_x_color,
- false,
- gyro_axis);
- addSeries("Pitch Rate",
- AltosGraphDataPoint.data_gyro_pitch,
- gyro_units,
- gyro_y_color,
- false,
- gyro_axis);
- addSeries("Yaw Rate",
- AltosGraphDataPoint.data_gyro_yaw,
- gyro_units,
- gyro_z_color,
- false,
- gyro_axis);
- }
- if (stats.has_mag) {
- addSeries("Magnetometer Along",
- AltosGraphDataPoint.data_mag_along,
- mag_units,
- mag_x_color,
- false,
- mag_axis);
- addSeries("Magnetometer Across",
- AltosGraphDataPoint.data_mag_across,
- mag_units,
- mag_y_color,
- false,
- mag_axis);
- addSeries("Magnetometer Through",
- AltosGraphDataPoint.data_mag_through,
- mag_units,
- mag_z_color,
- false,
- mag_axis);
- }
- if (stats.has_orient)
- addSeries("Tilt Angle",
- AltosGraphDataPoint.data_orient,
- orient_units,
- orient_color,
- false,
- orient_axis);
- if (stats.num_ignitor > 0) {
- for (int i = 0; i < stats.num_ignitor; i++)
- addSeries(AltosLib.ignitor_name(i),
- AltosGraphDataPoint.data_ignitor_0 + i,
- voltage_units,
- main_voltage_color,
- false,
- voltage_axis);
- for (int i = 0; i < stats.num_ignitor; i++)
- addMarker(AltosLib.ignitor_name(i), AltosGraphDataPoint.data_ignitor_fired_0 + i, state_color);
- }
+ flight_series.register_axis(AltosUIFlightSeries.thrust_name,
+ thrust_color,
+ true,
+ thrust_axis);
+
+ return flight_series.series(cal_data);
+ }
+
+ public void set_data(AltosFlightStats stats, AltosUIFlightSeries flight_series) {
+ set_series(setup(stats, flight_series));
+ }
+
+ public AltosGraph(AltosUIEnable enable) {
+ super(enable, "Flight");
+ }
- setDataSet(dataSet);
+ public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosUIFlightSeries flight_series) {
+ this(enable);
+ set_series(setup(stats, flight_series));
}
}
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altosuilib_11;
-
-import org.altusmetrum.altoslib_11.*;
-
-public class AltosGraphDataPoint implements AltosUIDataPoint {
-
- AltosState state;
-
- public static final int data_height = 0;
- public static final int data_speed = 1;
- public static final int data_accel = 2;
- public static final int data_temp = 3;
- public static final int data_battery_voltage = 4;
- public static final int data_drogue_voltage = 5;
- public static final int data_main_voltage = 6;
- public static final int data_rssi = 7;
- public static final int data_state = 8;
- public static final int data_gps_height = 9;
- public static final int data_gps_nsat_solution = 10;
- public static final int data_gps_nsat_view = 11;
- public static final int data_gps_altitude = 12;
- public static final int data_temperature = 13;
- public static final int data_range = 14;
- public static final int data_distance = 15;
- public static final int data_pressure = 16;
- public static final int data_accel_along = 17;
- public static final int data_accel_across = 18;
- public static final int data_accel_through = 19;
- public static final int data_gyro_roll = 20;
- public static final int data_gyro_pitch = 21;
- public static final int data_gyro_yaw = 22;
- public static final int data_mag_along = 23;
- public static final int data_mag_across = 24;
- public static final int data_mag_through = 25;
- public static final int data_orient = 26;
- 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_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;
- public static final int data_ignitor_fired_max = data_ignitor_fired_0 + data_ignitor_num - 1;
-
- public double x() throws AltosUIDataMissing {
- double time = state.time_since_boost();
- if (time < -2)
- throw new AltosUIDataMissing(-1);
- return time;
- }
-
- public double y(int index) throws AltosUIDataMissing {
- double y = AltosLib.MISSING;
- switch (index) {
- case data_height:
- y = state.height();
- break;
- case data_speed:
- y = state.speed();
- break;
- case data_accel:
- y = state.acceleration();
- break;
- case data_temp:
- y = state.temperature;
- break;
- case data_battery_voltage:
- y = state.battery_voltage;
- break;
- case data_drogue_voltage:
- y = state.apogee_voltage;
- break;
- case data_main_voltage:
- y = state.main_voltage;
- break;
- case data_rssi:
- y = state.rssi;
- break;
- case data_gps_height:
- y = state.gps_height;
- break;
- case data_gps_nsat_solution:
- if (state.gps != null)
- y = state.gps.nsat;
- break;
- case data_gps_nsat_view:
- if (state.gps != null) {
- if (state.gps.cc_gps_sat != null)
- y = state.gps.cc_gps_sat.length;
- else
- y = 0;
- }
- break;
- case data_gps_altitude:
- y = state.gps_altitude();
- break;
- case data_temperature:
- y = state.temperature;
- break;
- case data_range:
- y = state.range;
- break;
- case data_distance:
- if (state.from_pad != null)
- y = state.from_pad.distance;
- break;
- case data_pressure:
- y = state.pressure();
- break;
-
- case data_accel_along:
- y = state.accel_along();
- break;
- case data_accel_across:
- y = state.accel_across();
- break;
- case data_accel_through:
- y = state.accel_through();
- break;
- case data_gyro_roll:
- y = state.gyro_roll();
- break;
- case data_gyro_pitch:
- y = state.gyro_pitch();
- break;
- case data_gyro_yaw:
- y = state.gyro_yaw();
- break;
- case data_mag_along:
- y = state.mag_along();
- break;
- case data_mag_across:
- y = state.mag_across();
- break;
- case data_mag_through:
- y = state.mag_through();
- break;
- case data_orient:
- y = state.orient();
- break;
- case data_gps_course:
- if (state.gps != null)
- y = state.gps.course;
- else
- y = AltosLib.MISSING;
- break;
- case data_gps_ground_speed:
- if (state.gps != null)
- y = state.gps.ground_speed;
- else
- y = AltosLib.MISSING;
- break;
- case data_gps_climb_rate:
- if (state.gps != null)
- y = state.gps.climb_rate;
- 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;
- if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length)
- y = state.ignitor_voltage[ignitor];
- } else if (data_ignitor_fired_0 <= index && index <= data_ignitor_fired_max) {
- int ignitor = index - data_ignitor_fired_0;
- if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length) {
- if ((state.pyro_fired & (1 << ignitor)) != 0)
- y = 1;
- else
- y = 0;
- }
- }
- break;
- }
- if (y == AltosLib.MISSING)
- throw new AltosUIDataMissing(index);
- return y;
- }
-
- public int id(int index) {
- if (index == data_state) {
- int s = state.state();
- if (AltosLib.ao_flight_boost <= s && s <= AltosLib.ao_flight_landed)
- return s;
- } else if (data_ignitor_fired_0 <= index && index <= data_ignitor_fired_max) {
- int ignitor = index - data_ignitor_fired_0;
- if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length) {
- if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length) {
- if ((state.pyro_fired & (1 << ignitor)) != 0)
- return 1;
- }
- }
- }
- return -1;
- }
-
- public String id_name(int index) {
- if (index == data_state) {
- return state.state_name();
- } else if (data_ignitor_fired_0 <= index && index <= data_ignitor_fired_max) {
- int ignitor = index - data_ignitor_fired_0;
- if (state.ignitor_voltage != null && ignitor < state.ignitor_voltage.length)
- return AltosLib.ignitor_name(ignitor);
- }
- return "";
- }
-
- public AltosGraphDataPoint (AltosState state) {
- this.state = state;
- }
-}
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altosuilib_11;
-
-import java.lang.*;
-import java.io.*;
-import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-
-class AltosGraphIterator implements Iterator<AltosUIDataPoint> {
- AltosGraphDataSet dataSet;
- Iterator<AltosState> iterator;
-
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- public AltosUIDataPoint next() {
- AltosState state = iterator.next();
-
- if (state.flight != AltosLib.MISSING) {
- if (dataSet.callsign == null && state.callsign != null)
- dataSet.callsign = state.callsign;
-
- if (dataSet.serial == 0 && state.serial != 0)
- dataSet.serial = state.serial;
-
- if (dataSet.flight == 0 && state.flight != 0)
- dataSet.flight = state.flight;
- }
-
- return new AltosGraphDataPoint(state);
- }
-
- public AltosGraphIterator (Iterator<AltosState> iterator, AltosGraphDataSet dataSet) {
- this.iterator = iterator;
- this.dataSet = dataSet;
- }
-
- public void remove() {
- }
-}
-
-class AltosGraphIterable implements Iterable<AltosUIDataPoint> {
- AltosGraphDataSet dataSet;
-
- public Iterator<AltosUIDataPoint> iterator() {
- return new AltosGraphIterator(dataSet.states.iterator(), dataSet);
- }
-
- public AltosGraphIterable(AltosGraphDataSet dataSet) {
- this.dataSet = dataSet;
- }
-}
-
-public class AltosGraphDataSet implements AltosUIDataSet {
- String callsign;
- int serial;
- int flight;
- AltosStateIterable states;
-
- public String name() {
- if (callsign != null)
- return String.format("%s - %d/%d", callsign, serial, flight);
- else
- return String.format("%d/%d", serial, flight);
- }
-
- public Iterable<AltosUIDataPoint> dataPoints() {
- return new AltosGraphIterable(this);
- }
-
- public AltosGraphDataSet (AltosStateIterable states) {
- this.states = states;
- this.callsign = null;
- this.serial = 0;
- this.flight = 0;
- }
-}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
private AltosFlightInfoTableModel model;
public void show(AltosState state, AltosListenerState listener_state) {
+ AltosCalData cal_data = state.cal_data();
+
if (!isShowing()) {
last_state = state;
last_listener_state = listener_state;
reset();
if (state != null) {
- if (state.device_type != AltosLib.MISSING)
- info_add_row(0, "Device", "%s", AltosLib.product_name(state.device_type));
- else if (state.product != null)
- info_add_row(0, "Device", "%s", state.product);
+ if (cal_data.device_type != AltosLib.MISSING)
+ info_add_row(0, "Device", "%s", AltosLib.product_name(cal_data.device_type));
+ else if (cal_data.product != null)
+ info_add_row(0, "Device", "%s", cal_data.product);
if (state.altitude() != AltosLib.MISSING)
info_add_row(0, "Altitude", "%6.0f m", state.altitude());
- if (state.ground_altitude() != AltosLib.MISSING)
- info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude());
+ if (cal_data.ground_altitude != AltosLib.MISSING)
+ info_add_row(0, "Pad altitude", "%6.0f m", cal_data.ground_altitude);
if (state.height() != AltosLib.MISSING)
info_add_row(0, "Height", "%6.0f m", state.height());
if (state.max_height() != AltosLib.MISSING)
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public interface AltosPositionListener {
public void position_changed(int position);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosRomconfigUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class AltosScanResult {
String callsign;
if (state == null)
continue;
packet_count++;
- if (state.flight != AltosLib.MISSING) {
- final AltosScanResult result = new AltosScanResult(state.callsign,
- state.serial,
- state.flight,
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.flight != AltosLib.MISSING) {
+ final AltosScanResult result = new AltosScanResult(cal_data.callsign,
+ cal_data.serial,
+ cal_data.flight,
frequencies[frequency_index],
telemetry,
rate);
* Deal with TeleDongle on a serial port
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import libaltosJNI.*;
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public class AltosSerialInUseException extends Exception {
public AltosDevice device;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
public final static int axis_default = axis_include_zero;
public void set_units() {
- String u = units.parse_units();
- if (u != null)
- setLabel(String.format("%s (%s)", label, u));
- else
- setLabel(label);
+ if (units != null) {
+ String u = units.parse_units();
+ if (u != null) {
+ setLabel(String.format("%s (%s)", label, u));
+ return;
+ }
+ }
+ setLabel(label);
}
public void set_enable(boolean enable) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class DelegatingRenderer implements ListCellRenderer<Object> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public class AltosUIDataMissing extends Exception {
public int id;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public interface AltosUIDataPoint {
public abstract double x() throws AltosUIDataMissing;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public interface AltosUIDataSet {
public abstract String name();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+package org.altusmetrum.altosuilib_12;
+
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_12.*;
+
+import org.jfree.ui.*;
+import org.jfree.chart.*;
+import org.jfree.chart.plot.*;
+import org.jfree.chart.axis.*;
+import org.jfree.chart.renderer.*;
+import org.jfree.chart.renderer.xy.*;
+import org.jfree.chart.labels.*;
+import org.jfree.data.xy.*;
+import org.jfree.data.*;
+
+class AltosUITimeSeriesAxis {
+ Color color;
+ boolean enabled;
+ boolean marker;
+ boolean marker_top;
+ AltosUIAxis axis;
+ XYPlot plot;
+
+ public AltosUITimeSeriesAxis(Color color, boolean enabled, AltosUIAxis axis, XYPlot plot, boolean marker, boolean marker_top) {
+ this.color = color;
+ this.enabled = enabled;
+ this.axis = axis;
+ this.plot = plot;
+ this.marker = marker;
+ this.marker_top = marker_top;
+ }
+}
+
+public class AltosUIFlightSeries extends AltosFlightSeries {
+
+ Hashtable<String,AltosUITimeSeriesAxis> axes;
+
+ AltosUIFlightSeries flight_series;
+
+ void fill_axes(String label, AltosUITimeSeriesAxis axis) {
+ for (AltosTimeSeries ts : series) {
+ AltosUITimeSeries uts = (AltosUITimeSeries) ts;
+
+ if (label.equals(ts.label) || (label.equals("default") && uts.color == null)) {
+ if (axis.marker)
+ uts.set_marker(axis.color, axis.enabled, axis.plot, axis.marker_top);
+ else
+ uts.set_axis(axis.color, axis.enabled, axis.axis);
+ }
+ }
+ }
+
+ public void register_axis(String label,
+ Color color,
+ boolean enabled,
+ AltosUIAxis axis) {
+ AltosUITimeSeriesAxis tsa = new AltosUITimeSeriesAxis(color,
+ enabled,
+ axis,
+ null,
+ false,
+ false);
+ axes.put(label, tsa);
+ fill_axes(label, tsa);
+ }
+
+ public void register_marker(String label,
+ Color color,
+ boolean enabled,
+ XYPlot plot,
+ boolean marker_top) {
+ AltosUITimeSeriesAxis tsa = new AltosUITimeSeriesAxis(color,
+ enabled,
+ null,
+ plot,
+ true,
+ marker_top);
+ axes.put(label, tsa);
+ fill_axes(label, tsa);
+ }
+
+ public AltosTimeSeries make_series(String label, AltosUnits units) {
+
+
+ AltosUITimeSeries time_series = new AltosUITimeSeries(label, units);
+
+ AltosUITimeSeriesAxis tsa = axes.get(label);
+ if (tsa == null)
+ tsa = axes.get("default");
+ if (tsa != null) {
+ if (tsa.marker)
+ time_series.set_marker(tsa.color, tsa.enabled, tsa.plot, tsa.marker_top);
+ else
+ time_series.set_axis(tsa.color, tsa.enabled, tsa.axis);
+ }
+ return time_series;
+ }
+
+ public AltosUITimeSeries[] series(AltosCalData cal_data) {
+ finish();
+ return series.toArray(new AltosUITimeSeries[0]);
+ }
+
+ public AltosUIFlightSeries (AltosCalData cal_data) {
+ super(cal_data);
+ axes = new Hashtable<String,AltosUITimeSeriesAxis>();
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public abstract class AltosUIFlightTab extends JComponent implements AltosFlightDisplay, HierarchyListener {
public GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUIFreqList extends JComboBox<AltosFrequency> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
+import java.util.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
public ChartPanel panel;
NumberAxis xAxis;
AltosUIEnable enable;
- ArrayList<AltosUIGrapher> graphers;
- AltosUIDataSet dataSet;
+ AltosUITimeSeries[] series;
int axis_index;
int series_index;
+ Hashtable<Integer,Boolean> axes_added;
static final private Color gridline_color = new Color(0, 0, 0);
static final private Color border_color = new Color(255, 255, 255);
return newAxis(label, units, color, AltosUIAxis.axis_default);
}
- public void addSeries(String label, int fetch, AltosUnits units, Color color,
- boolean enabled, AltosUIAxis axis) {
- AltosUISeries series = new AltosUISeries(label, fetch, units, color, enabled, axis);
- XYSeriesCollection dataset = new XYSeriesCollection(series);
+ void addAxis(AltosUIAxis axis) {
+ if (!axes_added.containsKey(axis.index)) {
+ axes_added.put(axis.index, true);
+ plot.setRangeAxis(axis.index, axis);
+ }
+ }
+
+ public void addSeries(AltosUITimeSeries series) {
+ XYSeriesCollection dataset = new XYSeriesCollection(series.xy_series());
+
+ addAxis(series.axis);
series.renderer.setPlot(plot);
plot.setDataset(series_index, dataset);
plot.setRenderer(series_index, series.renderer);
- plot.mapDatasetToRangeAxis(series_index, axis.index);
+ plot.mapDatasetToRangeAxis(series_index, series.axis.index);
if (enable != null)
- enable.add(label, series, enabled);
- this.graphers.add(series);
+ enable.add(series.label, series, series.enable);
series_index++;
}
- public void addSeries(String label, int fetch, AltosUnits units, Color color) {
- addSeries(label, fetch, units, color, true, newAxis(label, units, color));
- }
-
- public void addMarker(String label, int fetch, Color color) {
- AltosUIMarker marker = new AltosUIMarker(fetch, color, plot);
- this.graphers.add(marker);
- }
-
- public void resetData() {
- for (AltosUIGrapher g : graphers) {
- g.clear();
- g.setNotify(false);
- }
- if (dataSet != null) {
- for (AltosUIDataPoint dataPoint : dataSet.dataPoints())
- for (AltosUIGrapher g : graphers)
- g.add(dataPoint);
- }
- for (AltosUIGrapher g : graphers) {
- g.setNotify(true);
- g.fireSeriesChanged();
- }
+ public void addMarker(AltosUITimeSeries series) {
}
public void units_changed(boolean imperial_units) {
- for (AltosUIGrapher g : graphers)
- g.set_units();
- resetData();
+ for (AltosUITimeSeries s : series)
+ s.set_units();
}
public void setName (String name) {
chart.setTitle(name);
}
- public void setDataSet (AltosUIDataSet dataSet) {
- this.dataSet = dataSet;
- resetData();
- if (dataSet != null)
- setName(dataSet.name());
+ public void set_series(AltosUITimeSeries[] series) {
+ this.series = series;
+ boolean any_enabled = false;
+
+ for (AltosUITimeSeries s : series)
+ if (s.enable)
+ any_enabled = true;
+
+ if (!any_enabled)
+ for (AltosUITimeSeries s : series)
+ s.set_enable(true);
+
+ for (AltosUITimeSeries s : series)
+ addSeries(s);
+
+ units_changed(false);
}
- public AltosUIGraph(AltosUIEnable enable) {
+ public AltosUIGraph(AltosUIEnable enable, String title) {
this.enable = enable;
- this.graphers = new ArrayList<AltosUIGrapher>();
- this.series_index = 0;
+ this.series = null;
this.axis_index = 0;
+ axes_added = new Hashtable<Integer,Boolean>();
+
xAxis = new NumberAxis("Time (s)");
xAxis.setAutoRangeIncludesZero(true);
plot.setDomainPannable(true);
plot.setRangePannable(true);
- chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT,
+ chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
plot, true);
ChartUtilities.applyCurrentTheme(chart);
panel.setPreferredSize(new java.awt.Dimension(800, 500));
AltosPreferences.register_units_listener(this);
+
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
public abstract void set_units();
+ public abstract boolean need_reset();
+
public abstract void clear();
public abstract void add(AltosUIDataPoint dataPoint);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
import javax.swing.*;
import javax.imageio.ImageIO;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public abstract class AltosUIIndicator implements AltosFontListener, AltosUnitsListener {
JLabel label;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUILib extends AltosLib {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
public interface AltosUIListener {
public void ui_changed(String look_and_feel);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.concurrent.*;
import javax.imageio.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface {
map.show(state, listener_state);
}
+ public void show(AltosGPS gps, int state) {
+ map.show(gps, state);
+ }
+
public String getName() {
return "Map";
}
map.centre(state);
}
+ public void centre(AltosGPS gps) {
+ map.centre(gps);
+ }
+
/* internal layout bits */
private GridBagLayout layout = new GridBagLayout();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.net.URL;
import java.net.URLConnection;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
class AltosUIMapPos extends Box implements ActionListener {
AltosUIMapPreload preload;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
public void set_units() {
}
+ public boolean need_reset() { return true; }
+
public void set_enable(boolean enable) {
if (enabled == enable)
return;
public AltosUIMarker (int fetch, Color color, XYPlot plot) {
this(fetch, color, plot, true);
}
-}
\ No newline at end of file
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.*;
import java.util.*;
import java.awt.Component;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUIPreferences extends AltosPreferences {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.io.File;
import java.util.prefs.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
import javax.swing.filechooser.FileSystemView;
public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUIRateList extends JComboBox<String> {
int serial;
public void set_rate(int new_rate) {
- int i;
-
- setVisible(new_rate >= 0);
- setSelectedIndex(new_rate);
+ if (new_rate != AltosLib.MISSING)
+ setSelectedIndex(new_rate);
+ setVisible(new_rate != AltosLib.MISSING);
}
public void set_product(String new_product) {
+++ /dev/null
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.altosuilib_11;
-
-import java.io.*;
-import java.util.ArrayList;
-
-import java.awt.*;
-import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-
-import org.jfree.ui.*;
-import org.jfree.chart.*;
-import org.jfree.chart.plot.*;
-import org.jfree.chart.axis.*;
-import org.jfree.chart.renderer.*;
-import org.jfree.chart.renderer.xy.*;
-import org.jfree.chart.labels.*;
-import org.jfree.data.xy.*;
-import org.jfree.data.*;
-
-class AltosUITime extends AltosUnits {
- public double value(double v, boolean imperial_units) { return v; }
-
- public double inverse(double v, boolean imperial_unis) { return v; }
-
- public String show_units(boolean imperial_units) { return "s"; }
-
- public String say_units(boolean imperial_units) { return "seconds"; }
-
- public int show_fraction(int width, boolean imperial_units) {
- if (width < 5)
- return 0;
- return width - 5;
- }
-
- public int say_fraction(boolean imperial_units) { return 0; }
-}
-
-public class AltosUISeries extends XYSeries implements AltosUIGrapher {
- AltosUIAxis axis;
- String label;
- AltosUnits units;
- Color color;
- XYItemRenderer renderer;
- int fetch;
- boolean enable;
-
- public void set_units() {
- axis.set_units();
- StandardXYToolTipGenerator ttg;
-
- String time_example = (new AltosUITime()).graph_format(7);
- String example = units.graph_format(7);
-
- ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})",
- units.graph_units()),
- new java.text.DecimalFormat(time_example),
- new java.text.DecimalFormat(example));
- renderer.setBaseToolTipGenerator(ttg);
- }
-
- public void set_enable(boolean enable) {
- if (this.enable != enable) {
- this.enable = enable;
- renderer.setSeriesVisible(0, enable);
- axis.set_enable(enable);
- }
- }
-
- public void add(AltosUIDataPoint dataPoint) {
- try {
- super.add(dataPoint.x(), units.graph_value(dataPoint.y(fetch)));
- } catch (AltosUIDataMissing dm) {
- }
- }
-
- public AltosUISeries (String label, int fetch, AltosUnits units, Color color,
- boolean enable, AltosUIAxis axis) {
- super(label);
- this.label = label;
- this.fetch = fetch;
- this.units = units;
- this.color = color;
- this.enable = enable;
- this.axis = axis;
-
- axis.ref(this.enable);
-
- renderer = new XYLineAndShapeRenderer(true, false);
- renderer.setSeriesPaint(0, color);
- renderer.setSeriesStroke(0, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- renderer.setSeriesVisible(0, enable);
- set_units();
- }
-}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.util.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class AltosUITelemetryList extends JComboBox<String> {
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altosuilib_12;
+
+import java.io.*;
+import java.util.ArrayList;
+
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_12.*;
+
+import org.jfree.ui.*;
+import org.jfree.chart.*;
+import org.jfree.chart.plot.*;
+import org.jfree.chart.axis.*;
+import org.jfree.chart.renderer.*;
+import org.jfree.chart.renderer.xy.*;
+import org.jfree.chart.labels.*;
+import org.jfree.data.xy.*;
+import org.jfree.data.*;
+
+class AltosUITime extends AltosUnits {
+ public double value(double v, boolean imperial_units) { return v; }
+
+ public double inverse(double v, boolean imperial_unis) { return v; }
+
+ public String show_units(boolean imperial_units) { return "s"; }
+
+ public String say_units(boolean imperial_units) { return "seconds"; }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ if (width < 5)
+ return 0;
+ return width - 5;
+ }
+
+ public int say_fraction(boolean imperial_units) { return 0; }
+}
+
+class AltosXYSeries extends XYSeries {
+
+ public AltosXYSeries(String label) {
+ super(label);
+ }
+}
+
+public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher {
+ Color color;
+ boolean enable;
+ AltosUIAxis axis;
+ boolean marker;
+ boolean marker_top;
+ XYItemRenderer renderer;
+ XYPlot plot;
+ AltosXYSeries xy_series;
+ ArrayList<ValueMarker> markers;
+
+
+ /* AltosUIGrapher interface */
+ public boolean need_reset() {
+ return false;
+ }
+
+ public void clear() {
+ }
+
+ public void add(AltosUIDataPoint dataPoint) {
+ }
+
+ public void setNotify(boolean notify) {
+ }
+
+ public void fireSeriesChanged() {
+ }
+
+ void set_data() {
+ if (marker) {
+ if (markers != null) {
+ for (ValueMarker marker : markers)
+ plot.removeDomainMarker(marker);
+ }
+ markers = new ArrayList<ValueMarker>();
+ for (AltosTimeValue v : this) {
+ String s = units.string_value(v.value);
+ ValueMarker marker = new ValueMarker(v.time);
+ marker.setLabel(s);
+ if (marker_top) {
+ marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
+ marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
+ } else {
+ marker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT);
+ marker.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT);
+ }
+ marker.setPaint(color);
+ if (enable)
+ plot.addDomainMarker(marker);
+ markers.add(marker);
+ }
+ } else {
+ xy_series.clear();
+
+ xy_series.setNotify(false);
+ for (AltosTimeValue v : this) {
+ double value = v.value;
+ if (units != null)
+ value = units.graph_value(value);
+ xy_series.add(v.time, value);
+ }
+ xy_series.setNotify(true);
+ }
+ }
+
+ public void set_units() {
+ axis.set_units();
+ StandardXYToolTipGenerator ttg;
+
+ if (units != null) {
+ String time_example = (new AltosUITime()).graph_format(7);
+ String example = units.graph_format(7);
+
+ ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})",
+ units.graph_units()),
+ new java.text.DecimalFormat(time_example),
+ new java.text.DecimalFormat(example));
+ renderer.setBaseToolTipGenerator(ttg);
+ }
+ set_data();
+ }
+
+ public AltosXYSeries xy_series() {
+ return xy_series;
+ }
+
+ public void set_enable(boolean enable) {
+ if (this.enable != enable) {
+ this.enable = enable;
+ if (marker) {
+ for (ValueMarker marker : markers) {
+ if (enable)
+ plot.addDomainMarker(marker);
+ else
+ plot.removeDomainMarker(marker);
+ }
+ } else {
+ renderer.setSeriesVisible(0, enable);
+ axis.set_enable(enable);
+ }
+ }
+ }
+
+ public void set_axis(Color color, boolean enable, AltosUIAxis axis) {
+ this.color = color;
+ this.enable = enable;
+ this.axis = axis;
+ this.marker = false;
+
+ axis.ref(this.enable);
+
+ renderer = new XYLineAndShapeRenderer(true, false);
+ renderer.setSeriesPaint(0, color);
+ renderer.setSeriesStroke(0, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+ renderer.setSeriesVisible(0, enable);
+ xy_series = new AltosXYSeries(label);
+ }
+
+ public void set_marker(Color color, boolean enable, XYPlot plot, boolean marker_top) {
+ this.color = color;
+ this.enable = enable;
+ this.marker = true;
+ this.plot = plot;
+ this.marker_top = marker_top;
+ }
+
+ public AltosUITimeSeries(String label, AltosUnits units) {
+ super(label, units);
+ }
+
+ public AltosUITimeSeries(String label, AltosUnits units,
+ Color color, boolean enable,
+ AltosUIAxis axis) {
+ this(label, units);
+ set_axis(color, enable, axis);
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.util.*;
import libaltosJNI.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.awt.*;
import java.awt.event.*;
AltosUIDataMissing.java \
AltosUIDataPoint.java \
AltosUIDataSet.java \
- AltosUIGraph.java \
AltosUIGrapher.java \
AltosUIDialog.java \
AltosUIEnable.java \
AltosUIMarker.java \
AltosUIPreferencesBackend.java \
AltosUIPreferences.java \
- AltosUISeries.java \
+ AltosUIFlightSeries.java \
+ AltosUIGraph.java \
+ AltosGraph.java \
AltosUSBDevice.java \
AltosVoice.java \
AltosDisplayThread.java \
AltosInfoTable.java \
AltosFlightInfoTableModel.java \
AltosFlightStatsTable.java \
- AltosGraph.java \
- AltosGraphDataPoint.java \
- AltosGraphDataSet.java \
AltosBTDevice.java \
AltosBTDeviceIterator.java \
AltosBTManage.java \
AltosUITelemetryList.java \
AltosUIRateList.java \
AltosUIImage.java \
+ AltosUITimeSeries.java \
OSXAdapter.java
JAR=altosuilib_$(ALTOSUILIB_VERSION).jar
*/
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
import java.lang.reflect.*;
import java.util.HashMap;
exit 1
fi
-if [ -x /usr/bin/ao-usbload ]; then
- USBLOAD=/usr/bin/ao-usbload
+if [ -x `which ao-usbload` ]; then
+ USBLOAD=`which ao-usbload`
else
echo "Can't find ao-usbload! Aborting."
exit 1
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.7)
+AC_INIT([altos], 1.7.1)
ANDROID_VERSION=14
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2017-04-24
+RELEASE_DATE=2017-07-21
AC_SUBST(RELEASE_DATE)
VERSION_DASH=`echo $VERSION | sed 's/\./-/g'`
dnl ==========================================================================
dnl Java library versions
-ALTOSUILIB_VERSION=11
-ALTOSLIB_VERSION=11
+ALTOSUILIB_VERSION=12
+ALTOSLIB_VERSION=12
AC_SUBST(ALTOSLIB_VERSION)
AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package])
telemega-outline.txt \
telemetrum-outline.txt \
telemini-v1-outline.txt \
- telemini-v3-outline.txt
+ telemini-v3-outline.txt \
+ telegps-outline.txt
OUTLINE_RAW_FILES=$(OUTLINE_TXT_FILES:.txt=.raw)
--- /dev/null
+= TeleGPS Outline and Hole Pattern
+:doctype: article
+
+ This image, when printed, provides a precise template for the
+ mounting holes in TeleGPS. TeleGPS has overall dimensions
+ of 1.000 x 1.500 inches, and the mounting holes are sized for
+ use with 4-40 or M3 screws.
+
+ image::telegps.svg[align="center"]
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ width="1.75in"
+ height="1.25in"
+ viewBox="0 0 175 125"
+ preserveaspectratio="none"
+ id="svg2"
+ version="1.1">
+ <g transform="translate(12.5,12.5)"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;font-size:20">
+ <!-- outline -->
+ <rect width="150" height="100" x="0" y="0"/>
+ <!-- holes -->
+ <path d="M12.5,12.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/>
+ <path d="M137.5,12.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/>
+ <path d="M12.5,87.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/>
+ <path d="M137.5,87.5 m-6.25,0 a6.25,6.25,0,1,0,12.5,0 a6.25,6.25,0,1,0,-12.5,0 l12.5,0 m-6.25,-6.25 l0,12.5"/>
+ <!-- arrow -->
+ <path d="M25,50 l100,0"/>
+ <path style="fill:#000000;stroke:none" d="M125,45 l10,5 l-10,5 z"/>
+ <!-- label -->
+ <text x="75" y="35" style="fill:#000000;stroke:none" text-anchor="middle">TeleGPS</text>
+ <g transform="rotate(90)">
+ <text x="50" y="-133" style="fill:#000000;stroke:none" text-anchor="middle">UP</text>
+ </g>
+ </g>
+</svg>
WINDOWS_H=\
libaltos.h
-noinst_PROGRAMS=cjnitest
+noinst_PROGRAMS=cjnitest btletest
cjnitest_SOURCES=cjnitest.c
cjnitest_LDADD=libaltos.la
+btletest_SOURCES=btletest.c
+
+btletest_LDADD=-lbluetooth
+
if MULTI_ARCH
altoslib_LTLIBRARIES+=libaltos32.la libaltos64.la
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#include <bluetooth/l2cap.h>
+#include <poll.h>
+
+#define ATT_OP_MTU_REQ 0x02
+#define ATT_OP_MTU_RESP 0x03
+#define ATT_OP_WRITE_CMD 0x52
+#define ATT_OP_HANDLE_NOTIFY 0x1b
+#define CID_ATT 0x0004
+#define TX_ENDPOINT 0x003a
+#define RX_ENDPOINT 0x0037
+#define RX_NOTIFY 0x0038
+
+int
+main(int argc, char **argv)
+{
+ int sk;
+ int psm;
+ struct sockaddr_l2 src_addr = { 0 };
+ struct sockaddr_l2 dst_addr = { 0 };
+ char buf[1024];
+ struct pollfd fd[2];
+ int n, i;
+ char *btaddr;
+ int mtu;
+
+ btaddr = argc > 1 ? argv[1] : "D8:80:39:F3:4E:A5";
+
+ sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+ if (sk < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ src_addr.l2_family = AF_BLUETOOTH;
+ /* Leave src_addr.l2_bdaddr all zeros */
+ src_addr.l2_cid = htobs(CID_ATT);
+ src_addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
+ if (bind(sk, (struct sockaddr *) &src_addr, sizeof (src_addr)) < 0) {
+ perror("bind");
+ exit(1);
+ }
+
+ dst_addr.l2_family = AF_BLUETOOTH;
+ str2ba(btaddr, &dst_addr.l2_bdaddr);
+ dst_addr.l2_cid = htobs(CID_ATT);
+ dst_addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
+
+ if (connect(sk, (struct sockaddr *) &dst_addr, sizeof(dst_addr)) < 0) {
+ perror("connect");
+ exit(1);
+ }
+
+ buf[0] = ATT_OP_MTU_REQ;
+ buf[1] = sizeof(buf) & 0xff;
+ buf[2] = sizeof(buf) >> 8;
+ n = write(sk, buf, 3);
+ if (n != 3) {
+ perror("write mtu\n");
+ exit(1);
+ }
+
+ fd[0].fd = sk;
+ fd[0].events = POLLIN;
+ for (;;) {
+ n = poll(fd, 1, 3000);
+ if (n <= 0) {
+ printf("timeout waiting for MTU response\n");
+ exit(1);
+ }
+ if (fd[0].revents & POLLIN) {
+ n = read(sk, buf, sizeof(buf));
+ printf("read %d\n", n);
+ for (i = 0; i < n; i++)
+ printf("%02x\n", buf[i]);
+ if (buf[0] == ATT_OP_MTU_RESP) {
+ mtu = (buf[1] & 0xff) | ((buf[2] & 0xff) << 8);
+ break;
+ }
+ }
+ }
+ printf("mtu %d\n", mtu);
+
+ buf[0] = ATT_OP_WRITE_CMD;
+ buf[1] = RX_NOTIFY & 0xff;
+ buf[2] = RX_NOTIFY >> 8;
+ buf[3] = 1;
+ n = write(sk, buf, 4);
+ if (n != 4) {
+ perror("write notify");
+ exit(1);
+ }
+
+ fd[0].fd = 0;
+ fd[0].events = POLLIN;
+ fd[1].fd = sk;
+ fd[1].events = POLLIN;
+
+ for (;;) {
+ n = poll(fd, 2, -1);
+ if (n == 0)
+ continue;
+ if (fd[0].revents & POLLIN) {
+ char *b;
+ n = read(0, buf+3, sizeof(buf)-3);
+ if (n < 0) {
+ perror("read stdin");
+ exit(1);
+ }
+ if (n == 0)
+ break;
+
+ b = buf;
+ while (n > 0) {
+ int this = n;
+ if (this > mtu - 3)
+ this = mtu - 3;
+
+ b[0] = ATT_OP_WRITE_CMD;
+ b[1] = TX_ENDPOINT;
+ b[2] = TX_ENDPOINT >> 8;
+ if (write(sk, b, this + 3) != this + 3) {
+ perror("write sk");
+ exit(1);
+ }
+ b += this;
+ n -= this;
+ }
+ }
+ if (fd[1].revents & POLLIN) {
+ uint16_t ch;
+
+ n = read(sk, buf, sizeof(buf));
+ if (n < 0) {
+ perror("read sk");
+ exit(1);
+ }
+ if (n == 0)
+ continue;
+ ch = buf[1] | (buf[2] << 8);
+ switch (buf[0]) {
+ case ATT_OP_HANDLE_NOTIFY:
+ if (ch == RX_ENDPOINT)
+ write(1, buf+3, n-3);
+ break;
+ }
+ }
+ if (fd[1].revents & (POLLERR|POLLHUP))
+ break;
+ }
+ close(sk);
+
+ return 0;
+}
micropeak_JAVA= \
MicroPeak.java \
MicroData.java \
- MicroDataPoint.java \
MicroDownload.java \
MicroExport.java \
MicroFile.java \
MicroFrame.java \
- MicroGraph.java \
MicroRaw.java \
MicroSave.java \
MicroSerial.java \
MicroSerialLog.java \
- MicroStats.java \
- MicroStatsTable.java \
MicroFileChooser.java \
MicroDeviceDialog.java \
MicroUSB.java
import java.lang.*;
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
-class MicroIterator implements Iterator<MicroDataPoint> {
- int i;
- MicroData data;
-
- public boolean hasNext() {
- return i < data.pressures.length;
- }
-
- public MicroDataPoint next() {
- return new MicroDataPoint(data, i++);
- }
-
- public MicroIterator (MicroData data) {
- this.data = data;
- i = 0;
- }
-
- public void remove() {
- }
-}
-
-class MicroIterable implements Iterable<MicroDataPoint> {
-
- MicroData data;
-
- public Iterator<MicroDataPoint> iterator() {
- return new MicroIterator(data);
- }
-
- public MicroIterable(MicroData data) {
- this.data = data;
- }
-}
-
-class MicroUIIterator implements Iterator<AltosUIDataPoint> {
- int i;
- MicroData data;
-
- public boolean hasNext() {
- return i < data.pressures.length;
- }
-
- public AltosUIDataPoint next() {
- return new MicroDataPoint(data, i++);
- }
-
- public MicroUIIterator (MicroData data) {
- this.data = data;
- i = 0;
- }
-
- public void remove() {
- }
-}
-
-class MicroUIIterable implements Iterable<AltosUIDataPoint> {
- MicroData data;
-
- public Iterator<AltosUIDataPoint> iterator() {
- return new MicroUIIterator(data);
- }
-
- public MicroUIIterable(MicroData data) {
- this.data = data;
- }
-}
-
-public class MicroData implements AltosUIDataSet {
+public class MicroData {
public int ground_pressure;
public int min_pressure;
- public int[] pressures;
+
+ AltosUIFlightSeries flight_series;
+ AltosFlightStats flight_stats;
+ AltosCalData cal_data;
+
private double time_step;
- private double ground_altitude;
private ArrayList<Integer> bytes;
public int log_id;
String name;
- MicroStats stats;
public static final int LOG_ID_MICROPEAK = 0;
public static final int LOG_ID_MICROKITE = 1;
return Math.abs (target - a) < Math.abs(target - b);
}
+ public double altitude(double time) {
+ if (flight_series.altitude_series == null)
+ return 0.0;
+ return flight_series.altitude_series.value(time);
+ }
+
public double altitude(int i) {
- return AltosConvert.pressure_to_altitude(pressures[i]);
+ return altitude(time(i));
}
public String name() {
return name;
}
- public Iterable<AltosUIDataPoint> dataPoints() {
- return new MicroUIIterable(this);
- }
-
- public Iterable<MicroDataPoint> points() {
- return new MicroIterable(this);
- }
-
- int fact(int n) {
- if (n == 0)
- return 1;
- return n * fact(n-1);
- }
+ public double pressure(int i) {
+ if (flight_series.pressure_series == null)
+ return 0.0;
- int choose(int n, int k) {
- return fact(n) / (fact(k) * fact(n-k));
+ return flight_series.pressure_series.value(time(i));
}
+ public double height(double time) {
+ if (flight_series.height_series == null)
+ return 0.0;
- public double avg_altitude(int center, int dist) {
- int start = center - dist;
- int stop = center + dist;
-
- if (start < 0)
- start = 0;
- if (stop >= pressures.length)
- stop = pressures.length - 1;
-
- double sum = 0;
- double div = 0;
-
- int n = dist * 2;
-
- for (int i = start; i <= stop; i++) {
- int k = i - (center - dist);
- int c = choose (n, k);
-
- sum += c * pressures[i];
- div += c;
- }
-
- double pres = sum / div;
-
- double alt = AltosConvert.pressure_to_altitude(pres);
- return alt;
+ return flight_series.height_series.value(time);
}
- public double pressure(int i) {
- return pressures[i];
+ public double height(int i) {
+ return height(time(i));
}
- public double height(int i) {
- return altitude(i) - ground_altitude;
+ public int length() {
+ if (flight_series.pressure_series == null)
+ return 0;
+ return flight_series.pressure_series.size();
}
+ /* Use the recorded apogee pressure for stats so that it agrees with the device */
public double apogee_pressure() {
return min_pressure;
}
}
public double apogee_height() {
- return apogee_altitude() - ground_altitude;
+ return apogee_altitude() - cal_data.ground_altitude;
}
- static final int speed_avg = 3;
- static final int accel_avg = 5;
-
- private double avg_speed(int center, int dist) {
- if (center == 0)
- return 0;
-
- double ai = avg_altitude(center, dist);
- double aj = avg_altitude(center - 1, dist);
- double s = (ai - aj) / time_step;
-
- return s;
+ public double speed(double time) {
+ if (flight_series.speed_series == null)
+ return 0.0;
+ return flight_series.speed_series.value(time);
}
public double speed(int i) {
- return avg_speed(i, speed_avg);
+ return speed(time(i));
+ }
+
+ public double acceleration(double time) {
+ if (flight_series.accel_series == null)
+ return 0.0;
+ return flight_series.accel_series.value(time);
}
public double acceleration(int i) {
- if (i == 0)
- return 0;
- return (avg_speed(i, accel_avg) - avg_speed(i-1, accel_avg)) / time_step;
+ return acceleration(time(i));
}
public double time(int i) {
public void export (Writer f) throws IOException {
PrintWriter pw = new PrintWriter(f);
pw.printf(" Time, Press(Pa), Height(m), Height(f), Speed(m/s), Speed(mph), Speed(mach), Accel(m/s²), Accel(ft/s²), Accel(g)\n");
- for (MicroDataPoint point : points()) {
+
+ for (AltosTimeValue ptv : flight_series.pressure_series) {
+
+ double height = height(ptv.time);
+ double speed = speed(ptv.time);
+ double accel = acceleration(ptv.time);
+
pw.printf("%6.3f,%10.0f,%10.1f,%10.1f,%11.2f,%11.2f,%12.4f,%12.2f,%13.2f,%10.4f\n",
- point.time,
- point.pressure,
- point.height,
- AltosConvert.meters_to_feet(point.height),
- point.speed,
- AltosConvert.meters_to_mph(point.speed),
- AltosConvert.meters_to_mach(point.speed),
- point.accel,
- AltosConvert.meters_to_feet(point.accel),
- AltosConvert.meters_to_g(point.accel));
+ ptv.time,
+ ptv.value,
+ height,
+ AltosConvert.meters_to_feet(height),
+ speed,
+ AltosConvert.meters_to_mph(speed),
+ AltosConvert.meters_to_mach(speed),
+ accel,
+ AltosConvert.meters_to_feet(accel),
+ AltosConvert.meters_to_g(accel));
}
}
this.name = name;
}
+ public MicroData() {
+ ground_pressure = 101000;
+ min_pressure = 101000;
+ cal_data = new AltosCalData();
+ flight_series = new AltosUIFlightSeries(cal_data);
+ }
+
public MicroData (InputStream f, String name) throws IOException, InterruptedException, NonHexcharException, FileEndedException {
this.name = name;
bytes = new ArrayList<Integer>();
+
+ cal_data = new AltosCalData();
+ flight_series = new AltosUIFlightSeries(cal_data);
+
if (!find_header(f))
throw new IOException("No MicroPeak data header found");
try {
log_id = nsamples >> 12;
nsamples &= 0xfff;
- pressures = new int[nsamples + 1];
- ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
+ cal_data.set_ground_pressure(ground_pressure);
+
+ switch (log_id) {
+ case LOG_ID_MICROPEAK:
+ time_step = 2 * CLOCK_MP1;
+ break;
+ case LOG_ID_MICROKITE:
+ time_step = 200 * CLOCK_MP1;
+ break;
+ case LOG_ID_MICROPEAK2:
+ time_step = CLOCK_MP2;
+ break;
+ default:
+ throw new IOException(String.format("Unknown device type: %d", log_id));
+ }
+ cal_data.set_ticks_per_sec(1/time_step);
+ cal_data.set_tick(0);
+ cal_data.set_boost_tick();
+
int cur = ground_pressure;
- pressures[0] = cur;
+ cal_data.set_tick(0);
+ flight_series.set_time(cal_data.time());
+ flight_series.set_pressure(cur);
for (int i = 0; i < nsamples; i++) {
int k = get_16(f);
int same = mix_in(cur, k);
cur = down;
}
- pressures[i+1] = cur;
+ cal_data.set_tick(i+1);
+ flight_series.set_time(cal_data.time());
+ flight_series.set_pressure(cur);
}
+ flight_series.finish();
+
+ /* Build states */
+
+ flight_series.set_time(0);
+ flight_series.set_state(AltosLib.ao_flight_boost);
+
+ flight_series.set_time(flight_series.speed_series.max().time);
+ flight_series.set_state(AltosLib.ao_flight_coast);
+
+ flight_series.set_time(flight_series.height_series.max().time);
+ flight_series.set_state(AltosLib.ao_flight_drogue);
+
+ cal_data.set_tick(nsamples);
+ flight_series.set_time(cal_data.time());
+ flight_series.set_state(AltosLib.ao_flight_landed);
+
+ flight_series.finish();
+
+ flight_stats = new AltosFlightStats(flight_series);
+
int current_crc = swap16(~file_crc & 0xffff);
int crc = get_16(f);
crc_valid = crc == current_crc;
- switch (log_id) {
- case LOG_ID_MICROPEAK:
- time_step = 2 * CLOCK_MP1;
- break;
- case LOG_ID_MICROKITE:
- time_step = 200 * CLOCK_MP1;
- break;
- case LOG_ID_MICROPEAK2:
- time_step = CLOCK_MP2;
- break;
- default:
- throw new IOException(String.format("Unknown device type: %d", log_id));
- }
- stats = new MicroStats(this);
} catch (FileEndedException fe) {
throw new IOException("File Ended Unexpectedly");
}
}
- public MicroData() {
- ground_pressure = 101000;
- min_pressure = 101000;
- pressures = new int[1];
- pressures[0] = 101000;
- }
-
}
+++ /dev/null
-/*
- * Copyright © 2012 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.micropeak;
-
-import org.altusmetrum.altosuilib_11.*;
-
-public class MicroDataPoint implements AltosUIDataPoint {
- public double time;
- public double pressure;
- public double height;
- public double speed;
- public double accel;
- public MicroStats stats;
-
- public static final int data_height = 0;
- public static final int data_speed = 1;
- public static final int data_accel = 2;
- public static final int data_state = 3;
-
- public double x() {
- return time;
- }
-
- public double y(int index) {
- switch (index) {
- case data_height:
- return height;
- case data_speed:
- return speed;
- case data_accel:
- return accel;
- default:
- return 0;
- }
- }
-
- public int id(int index) {
- if (index == data_state) {
- return stats.state(time);
- }
- return 0;
- }
-
- public String id_name(int index) {
- if (index == data_state)
- return stats.state_name(time);
- return "";
- }
-
- public MicroDataPoint (double pressure, double height, double speed, double accel, double time, MicroStats stats) {
- this.pressure = pressure;
- this.height = height;
- this.speed = speed;
- this.accel = accel;
- this.time = time;
- this.stats = stats;
- }
-
- public MicroDataPoint(MicroData data, int i) {
- this(data.pressure(i),
- data.height(i),
- data.speed(i),
- data.acceleration(i),
- data.time(i),
- data.stats);
- }
-}
\ No newline at end of file
import java.awt.*;
import java.awt.event.*;
import java.util.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroDeviceDialog extends AltosDeviceDialog {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener {
MicroPeak owner;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroExport extends JFileChooser {
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroFile {
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroFileChooser extends JFileChooser {
JFrame frame;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroFrame extends AltosUIFrame {
static String[] micro_icon_names = {
+++ /dev/null
-/*
- * Copyright © 2012 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.micropeak;
-
-import java.io.*;
-import java.util.ArrayList;
-
-import java.awt.*;
-import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
-
-import org.jfree.ui.*;
-import org.jfree.chart.*;
-import org.jfree.chart.plot.*;
-import org.jfree.chart.axis.*;
-import org.jfree.chart.renderer.*;
-import org.jfree.chart.renderer.xy.*;
-import org.jfree.chart.labels.*;
-import org.jfree.data.xy.*;
-import org.jfree.data.*;
-
-public class MicroGraph extends AltosUIGraph {
-
- static final private Color height_color = new Color(194,31,31);
- static final private Color speed_color = new Color(31,194,31);
- static final private Color accel_color = new Color(31,31,194);
- static final private Color state_color = new Color(3,3,3);
-
- public MicroGraph(AltosUIEnable enable) {
- super(enable);
-
- addSeries("Height", MicroDataPoint.data_height, AltosConvert.height, height_color);
- addSeries("Speed", MicroDataPoint.data_speed, AltosConvert.speed, speed_color);
- addSeries("Acceleration", MicroDataPoint.data_accel, AltosConvert.accel, accel_color);
- addMarker("State", MicroDataPoint.data_state, state_color);
- }
-}
\ No newline at end of file
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {
File filename;
- MicroGraph graph;
+ AltosGraph graph;
AltosUIEnable enable;
- MicroStatsTable statsTable;
+ AltosFlightStatsTable statsTable;
MicroRaw raw;
MicroData data;
- MicroStats stats;
Container container;
JTabbedPane pane;
static int number_of_windows;
return mp.SetData(data);
}
this.data = data;
- stats = new MicroStats(data);
- graph.setDataSet(data);
- statsTable.setStats(stats);
+ if (data.flight_series == null)
+ System.out.printf("no data in flight\n");
+ if (data.flight_stats == null)
+ System.out.printf("no stats in flight\n");
+ graph.set_data(data.flight_stats, data.flight_series);
+ statsTable.set_stats(data.flight_stats);
raw.setData(data);
setTitle(data.name);
return this;
});
enable = new AltosUIEnable();
- graph = new MicroGraph(enable);
- statsTable = new MicroStatsTable();
+
+ graph = new AltosGraph(enable);
+ statsTable = new AltosFlightStatsTable();
raw = new MicroRaw();
pane.add(graph.panel, "Graph");
pane.add(enable, "Configure Graph");
CommandExport(file);
opened = true;
} catch (Exception e) {
- System.err.printf("Error processing \"%s\": %s\n",
- file.getName(), e.getMessage());
+ System.err.printf("Error processing \"%s\": %s %s\n",
+ file.getName(), e.toString(), e.getMessage());
+ e.printStackTrace();
}
}
}
import java.awt.*;
import java.io.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroRaw extends JTextArea {
StringWriter sw = new StringWriter();
try {
data.export(sw);
- setRows(data.pressures.length + 1);
+ setRows(data.length());
setText(sw.toString());
} catch (IOException ie) {
setText(String.format("Error writing data: %s", ie.getMessage()));
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroSave extends JFileChooser {
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroSerial extends InputStream {
SWIGTYPE_p_altos_file file;
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public interface MicroSerialLog {
+++ /dev/null
-/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.micropeak;
-
-import java.io.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
-
-public class MicroStats {
- double coast_height;
- double coast_time;
-
- double apogee_height;
- double apogee_time;
-
- double landed_height;
- double landed_time;
-
- double max_speed;
- double max_accel;
-
- MicroData data;
-
- void find_landing() {
- landed_height = 0;
-
- for (MicroDataPoint point : data.points()) {
- landed_height = point.height;
- landed_time = point.time;
- }
-
- boolean above = false;
- for (MicroDataPoint point : data.points()) {
- if (point.height > landed_height + 10) {
- above = true;
- } else {
- if (above && point.height < landed_height + 2) {
- above = false;
- landed_time = point.time;
- }
- }
- }
- }
-
- void find_apogee() {
- apogee_height = data.apogee_height();
- double searched_apogee = 0;
- apogee_time = 0;
-
- /* This just finds the apogee time -- we've recorded the
- * peak altitude separately in eeprom, and that could
- * have occurred after the eeprom was full.
- */
- for (MicroDataPoint point : data.points()) {
- if (point.height > searched_apogee) {
- searched_apogee = point.height;
- apogee_time = point.time;
- }
- }
- }
-
- void find_coast() {
- coast_height = 0;
- coast_time = 0;
-
- for (MicroDataPoint point : data.points()) {
- if (point.accel < -9.8)
- break;
- coast_time = point.time;
- coast_height = point.height;
- }
- }
-
- void find_max_speed() {
- max_speed = 0;
- for (MicroDataPoint point : data.points()) {
- if (point.time > apogee_time)
- break;
- if (point.speed > max_speed)
- max_speed = point.speed;
- }
- }
-
- void find_max_accel() {
- max_accel = 0;
- for (MicroDataPoint point : data.points()) {
- if (point.time > apogee_time)
- break;
- if (point.accel > max_accel)
- max_accel = point.accel;
- }
- }
-
- double boost_duration() {
- return coast_time;
- }
-
- double boost_height() {
- return coast_height;
- }
-
- double boost_speed() {
- return coast_height / coast_time;
- }
-
- double boost_accel() {
- return boost_speed() / boost_duration();
- }
-
- double coast_duration() {
- return apogee_time - coast_time;
- }
-
- double coast_height() {
- return apogee_height - coast_height;
- }
-
- double coast_speed() {
- return coast_height() / coast_duration();
- }
-
- double coast_accel() {
- return coast_speed() / coast_duration();
- }
-
- double descent_duration() {
- return landed_time - apogee_time;
- }
-
- double descent_height() {
- return apogee_height - landed_height;
- }
-
- double descent_speed() {
- return descent_height() / descent_duration();
- }
-
- public static final int state_startup = -1;
- public static final int state_pad = 0;
- public static final int state_boost = 1;
- public static final int state_coast = 2;
- public static final int state_descent = 3;
- public static final int state_landed = 4;
-
- static final String state_names[] = {
- "pad",
- "boost",
- "coast",
- "descent",
- "landed"
- };
-
- public int state(double t) {
- if (t >= landed_time)
- return state_landed;
- if (t >= apogee_time)
- return state_descent;
- if (t >= coast_time)
- return state_coast;
- if (t >= 0)
- return state_boost;
- return state_pad;
- }
-
- public static String state_name(int state) {
- if (state < 0 || state > state_landed)
- return "unknown";
- return state_names[state];
- }
-
- public String state_name(double t) {
- return state_name(state(t));
- }
-
- public MicroStats(MicroData data) {
-
- this.data = data;
-
- find_coast();
- find_apogee();
- find_landing();
- find_max_speed();
- find_max_accel();
- }
-
- public MicroStats() {
- this(new MicroData());
- }
-}
+++ /dev/null
-/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-package org.altusmetrum.micropeak;
-
-import java.awt.*;
-import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
-
-public class MicroStatsTable extends JComponent implements AltosFontListener {
- GridBagLayout layout;
-
- class MicroStat {
- JLabel label;
- JTextField[] texts;
-
- public void set_values(String ... values) {
- for (int j = 0; j < values.length; j++) {
- texts[j].setText(values[j]);
- }
- }
-
- public void set_font() {
- for (int j = 0; j < texts.length; j++)
- texts[j].setFont(AltosUILib.value_font);
- label.setFont(AltosUILib.label_font);
- }
-
- public MicroStat(GridBagLayout layout, int y, String label_text, String ... values) {
- GridBagConstraints c = new GridBagConstraints();
- c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
- c.weighty = 1;
-
- label = new JLabel(label_text);
- label.setFont(AltosUILib.label_font);
- label.setHorizontalAlignment(SwingConstants.LEFT);
- c.gridx = 0; c.gridy = y;
- c.anchor = GridBagConstraints.WEST;
- c.fill = GridBagConstraints.VERTICAL;
- c.weightx = 0;
- layout.setConstraints(label, c);
- add(label);
-
- texts = new JTextField[values.length];
- for (int j = 0; j < values.length; j++) {
- JTextField value = new JTextField(values[j]);
- value.setEditable(false);
- value.setFont(AltosUILib.value_font);
- value.setHorizontalAlignment(SwingConstants.RIGHT);
- texts[j] = value;
- c.gridx = j+1; c.gridy = y;
- c.anchor = GridBagConstraints.EAST;
- c.fill = GridBagConstraints.BOTH;
- c.weightx = 1;
- layout.setConstraints(value, c);
- add(value);
- }
- }
- }
-
- MicroStat max_height, max_speed;
- MicroStat max_accel, avg_accel;
- MicroStat boost_duration;
- MicroStat coast_duration;
- MicroStat descent_speed;
- MicroStat descent_duration;
- MicroStat flight_time;
-
- public void setStats(MicroStats stats) {
- max_height.set_values(String.format("%7.1f m", stats.apogee_height),
- String.format("%7.1f ft", AltosConvert.meters_to_feet(stats.apogee_height)));
- max_speed.set_values(String.format("%7.1f m/s", stats.max_speed),
- String.format("%7.1f mph", AltosConvert.meters_to_mph(stats.max_speed)),
- String.format("Mach %7.3f", AltosConvert.meters_to_mach(stats.max_speed)));
- max_accel.set_values(String.format("%7.1f m/s²", stats.max_accel),
- String.format("%7.1f ft/s²", AltosConvert.meters_to_feet(stats.max_accel)),
- String.format("%7.3f G", AltosConvert.meters_to_g(stats.max_accel)));
- avg_accel.set_values(String.format("%7.1f m/s²", stats.boost_accel(),
- String.format("%7.1f ft/s²", AltosConvert.meters_to_feet(stats.boost_accel())),
- String.format("%7.3f G", AltosConvert.meters_to_g(stats.boost_accel()))));
- boost_duration.set_values(String.format("%6.1f s", stats.boost_duration()));
- coast_duration.set_values(String.format("%6.1f s", stats.coast_duration()));
- descent_speed.set_values(String.format("%7.1f m/s", stats.descent_speed()),
- String.format("%7.1f ft/s", AltosConvert.meters_to_feet(stats.descent_speed())));
- descent_duration.set_values(String.format("%6.1f s", stats.descent_duration()));
- flight_time.set_values(String.format("%6.1f s", stats.landed_time));
- }
-
- public void set_font() {
- max_height.set_font();
- max_speed.set_font();
- max_accel.set_font();
- avg_accel.set_font();
- boost_duration.set_font();
- coast_duration.set_font();
- descent_speed.set_font();
- descent_duration.set_font();
- flight_time.set_font();
- }
-
- public void font_size_changed(int font_size) {
- set_font();
- }
-
- public MicroStatsTable(MicroStats stats) {
- layout = new GridBagLayout();
-
- setLayout(layout);
- int y = 0;
- max_height = new MicroStat(layout, y++, "Maximum height",
- String.format("%7.1f m", stats.apogee_height),
- String.format("%7.1f ft", AltosConvert.meters_to_feet(stats.apogee_height)));
- max_speed = new MicroStat(layout, y++, "Maximum speed",
- String.format("%7.1f m/s", stats.max_speed),
- String.format("%7.1f mph", AltosConvert.meters_to_mph(stats.max_speed)),
- String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed)));
- max_accel = new MicroStat(layout, y++, "Maximum boost acceleration",
- String.format("%7.1f m/s²", stats.max_accel),
- String.format("%7.1f ft/s²", AltosConvert.meters_to_feet(stats.max_accel)),
- String.format("%7.3f G", AltosConvert.meters_to_g(stats.max_accel)));
- avg_accel = new MicroStat(layout, y++, "Average boost acceleration",
- String.format("%7.1f m/s²", stats.boost_accel(),
- String.format("%7.1f ft/s²", AltosConvert.meters_to_feet(stats.boost_accel())),
- String.format("%7.3f G", AltosConvert.meters_to_g(stats.boost_accel()))));
- boost_duration = new MicroStat(layout, y++, "Boost duration",
- String.format("%6.1f s", stats.boost_duration()));
- coast_duration = new MicroStat(layout, y++, "Coast duration",
- String.format("%6.1f s", stats.coast_duration()));
- descent_speed = new MicroStat(layout, y++, "Descent rate",
- String.format("%7.1f m/s", stats.descent_speed()),
- String.format("%7.1f ft/s", AltosConvert.meters_to_feet(stats.descent_speed())));
- descent_duration = new MicroStat(layout, y++, "Descent duration",
- String.format("%6.1f s", stats.descent_duration()));
- flight_time = new MicroStat(layout, y++, "Flight Time",
- String.format("%6.1f s", stats.landed_time));
- set_font();
-
- AltosUIPreferences.register_font_listener(this);
- }
-
- public void tell_closing() {
- AltosUIPreferences.unregister_font_listener(this);
- }
-
- public MicroStatsTable() {
- this(new MicroStats());
- }
-
-}
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class MicroUSB extends altos_device implements AltosDevice {
static void
ao_hmc5883(void)
{
+ struct ao_hmc5883_sample sample;
ao_hmc5883_setup();
for (;;) {
- ao_hmc5883_sample(&ao_hmc5883_current);
- ao_arch_critical(
- AO_DATA_PRESENT(AO_DATA_HMC5883);
- AO_DATA_WAIT();
- );
+ ao_hmc5883_sample(&sample);
+ ao_arch_block_interrupts();
+ ao_hmc5883_current = sample;
+ AO_DATA_PRESENT(AO_DATA_HMC5883);
+ AO_DATA_WAIT();
+ ao_arch_release_interrupts();
}
}
static void
ao_hmc5883_show(void)
{
- struct ao_data sample;
- ao_data_get(&sample);
- printf ("X: %d Y: %d Z: %d missed irq: %lu\n",
- sample.hmc5883.x, sample.hmc5883.y, sample.hmc5883.z, ao_hmc5883_missed_irq);
+ printf ("X: %d Z: %d Y: %d missed irq: %lu\n",
+ ao_hmc5883_current.x, ao_hmc5883_current.z, ao_hmc5883_current.y, ao_hmc5883_missed_irq);
}
static const struct ao_cmds ao_hmc5883_cmds[] = {
#define HMC5883_ID_C 12
struct ao_hmc5883_sample {
- int16_t x, y, z;
+ int16_t x, z, y;
};
extern struct ao_hmc5883_sample ao_hmc5883_current;
_ao_mpu6000_wait_alive();
/* Reset the whole chip */
-
+
_ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1,
(1 << MPU6000_PWR_MGMT_1_DEVICE_RESET));
ao_delay(AO_MS_TO_TICKS(200));
_ao_mpu6000_sample(&normal_mode);
-
+
errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x);
errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y);
errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z);
/* Set sample rate divider to sample at 200Hz (v = gyro/rate - 1) */
_ao_mpu6000_reg_write(MPU6000_SMPRT_DIV,
1000 / 200 - 1);
-
+
ao_delay(AO_MS_TO_TICKS(100));
ao_mpu6000_configured = 1;
}
static void
ao_mpu6000(void)
{
+ struct ao_mpu6000_sample sample;
/* ao_mpu6000_init already grabbed the SPI bus and mutex */
_ao_mpu6000_setup();
#if AO_MPU6000_SPI
#if AO_MPU6000_SPI
ao_mpu6000_spi_get();
#endif
- _ao_mpu6000_sample(&ao_mpu6000_current);
+ _ao_mpu6000_sample(&sample);
#if AO_MPU6000_SPI
ao_mpu6000_spi_put();
-#endif
- ao_arch_critical(
- AO_DATA_PRESENT(AO_DATA_MPU6000);
- AO_DATA_WAIT();
- );
+#endif
+ ao_arch_block_interrupts();
+ ao_mpu6000_current = sample;
+ AO_DATA_PRESENT(AO_DATA_MPU6000);
+ AO_DATA_WAIT();
+ ao_arch_release_interrupts();
}
}
static void
ao_mpu6000_show(void)
{
- struct ao_data sample;
-
- ao_data_get(&sample);
printf ("Accel: %7d %7d %7d Gyro: %7d %7d %7d\n",
- sample.mpu6000.accel_x,
- sample.mpu6000.accel_y,
- sample.mpu6000.accel_z,
- sample.mpu6000.gyro_x,
- sample.mpu6000.gyro_y,
- sample.mpu6000.gyro_z);
+ ao_mpu6000_current.accel_x,
+ ao_mpu6000_current.accel_y,
+ ao_mpu6000_current.accel_z,
+ ao_mpu6000_current.gyro_x,
+ ao_mpu6000_current.gyro_y,
+ ao_mpu6000_current.gyro_z);
}
static const struct ao_cmds ao_mpu6000_cmds[] = {
ao_mpu6000_configured = 0;
ao_add_task(&ao_mpu6000_task, ao_mpu6000, "mpu6000");
-
+
#if AO_MPU6000_SPI
ao_spi_init_cs(AO_MPU6000_SPI_CS_PORT, (1 << AO_MPU6000_SPI_CS_PIN));
ao_cur_task = &ao_mpu6000_task;
ao_spi_get(AO_MPU6000_SPI_BUS, AO_SPI_SPEED_1MHz);
ao_cur_task = NULL;
-#endif
+#endif
ao_cmd_register(&ao_mpu6000_cmds[0]);
}
static void
ao_ms5607(void)
{
+ struct ao_ms5607_sample sample;
ao_ms5607_setup();
for (;;)
{
- ao_ms5607_sample(&ao_ms5607_current);
+ ao_ms5607_sample(&sample);
ao_arch_block_interrupts();
+ ao_ms5607_current = sample;
AO_DATA_PRESENT(AO_DATA_MS5607);
AO_DATA_WAIT();
ao_arch_release_interrupts();
ao_rn_log_char(char c, char dir)
{
if (dir != ao_rn_dir) {
- putchar(dir);
+ putchar(dir); putchar('\n');
ao_rn_dir = dir;
}
switch (c) {
"RFCOMM_CLOSE",
"RFCOMM_OPEN",
"CONNECT",
+ "LCONNECT",
"DISCONN",
"BONDED",
};
#define NUM_STATUS_STRING (sizeof status_strings/sizeof status_strings[0])
+static char ao_rn_buffer[64];
+static int ao_rn_buf_cnt, ao_rn_buf_ptr;
+static int ao_rn_draining;
+static AO_TICK_TYPE ao_rn_buf_time;
+
+/* Well, this is annoying. The status strings from the RN4678 can't be
+ * disabled due to a firmware bug. So, this code finds those in the
+ * input and strips them out.
+ */
int
_ao_wrap_rn_pollchar(void)
{
- static char buffer[64];
- static int buf_cnt, buf_ptr;
- static int draining;
int c = AO_READ_AGAIN;
unsigned i;
int done = 0;
- while (!done && !draining) {
+ while (!done && !ao_rn_draining) {
c = _ao_serial_rn_pollchar();
- if (c == AO_READ_AGAIN)
+ if (c == AO_READ_AGAIN) {
+ if (ao_rn_buf_cnt && (ao_time() - ao_rn_buf_time) > AO_MS_TO_TICKS(1000)) {
+ ao_rn_draining = 1;
+ continue;
+ }
return AO_READ_AGAIN;
+ }
- if (buf_cnt) {
+ if (ao_rn_buf_cnt) {
/* buffering chars */
if (c == STATUS_CHAR) {
/* End of status string, drop it and carry on */
- buffer[buf_cnt] = '\0';
- ao_rn_dbg("discard %s\n", buffer);
- buf_cnt = 0;
- } else if (buf_cnt == sizeof(buffer)) {
+ ao_rn_buffer[ao_rn_buf_cnt] = '\0';
+// ao_rn_dbg("discard %s\n", ao_rn_buffer);
+ ao_rn_buf_cnt = 0;
+ } else if (ao_rn_buf_cnt == sizeof(ao_rn_buffer)) {
/* If we filled the buffer, just give up */
- draining = 1;
+ ao_rn_draining = 1;
} else {
- buffer[buf_cnt++] = c;
+ ao_rn_buffer[ao_rn_buf_cnt++] = c;
for (i = 0; i < NUM_STATUS_STRING; i++) {
int cmp = strlen(status_strings[i]);
- if (cmp >= buf_cnt)
- cmp = buf_cnt-1;
- if (memcmp(buffer+1, status_strings[i], cmp) == 0)
+ if (cmp >= ao_rn_buf_cnt)
+ cmp = ao_rn_buf_cnt-1;
+ if (memcmp(ao_rn_buffer+1, status_strings[i], cmp) == 0)
break;
}
if (i == NUM_STATUS_STRING)
- draining = 1;
+ ao_rn_draining = 1;
}
} else if (c == STATUS_CHAR) {
- buffer[0] = c;
- buf_cnt = 1;
- buf_ptr = 0;
+ ao_rn_buffer[0] = c;
+ ao_rn_buf_cnt = 1;
+ ao_rn_buf_ptr = 0;
+ ao_rn_buf_time = ao_time();
} else
done = 1;
}
- if (draining) {
- c = buffer[buf_ptr++] & 0xff;
- if (buf_ptr == buf_cnt) {
- buf_ptr = buf_cnt = 0;
- draining = 0;
+ if (ao_rn_draining) {
+ c = ao_rn_buffer[ao_rn_buf_ptr++] & 0xff;
+ if (ao_rn_buf_ptr == ao_rn_buf_cnt) {
+ ao_rn_buf_ptr = ao_rn_buf_cnt = 0;
+ ao_rn_draining = 0;
}
}
-#if AO_RN_DEBUG
- ao_arch_release_interrupts();
- ao_usb_putchar(c); ao_usb_flush();
- ao_arch_block_interrupts();
-#endif
return c;
}
-#if AO_RN_DEBUG
-static void
-ao_wrap_rn_putchar(char c)
-{
- ao_usb_putchar(c); ao_usb_flush();
- ao_serial_rn_putchar(c);
-}
-#else
-#define ao_wrap_rn_putchar ao_serial_rn_putchar
-#endif
-
static void
ao_rn_puts(char *s)
{
{
int timeout = 0;
- ao_rn_dbg("drain...\n");
+// ao_rn_dbg("drain...\n");
ao_serial_rn_drain();
while (!timeout) {
ao_arch_block_interrupts();
}
ao_arch_release_interrupts();
}
- ao_rn_dbg("drain done\n");
+// ao_rn_dbg("drain done\n");
}
static void
ao_rn_send_cmd(char *cmd, char *param)
{
- ao_rn_dbg("send_cmd %s%s\n", cmd, param ? param : "");
+// ao_rn_dbg("send_cmd %s%s\n", cmd, param ? param : "");
ao_rn_drain();
ao_rn_puts(cmd);
if (param)
AO_TICK_TYPE giveup_time = ao_time() + timeout;
int c;
- ao_rn_dbg("wait for %d, \"%s\"\n", timeout, match);
+// ao_rn_dbg("wait for %d, \"%s\"\n", timeout, match);
memset(reply, ' ', sizeof(reply));
while (memcmp(reply, match, match_len) != 0) {
c = ao_rn_wait_char(giveup_time);
if (c == AO_READ_AGAIN) {
- ao_rn_dbg("\twait for timeout\n");
+// ao_rn_dbg("\twait for timeout\n");
return AO_RN_TIMEOUT;
}
reply[match_len] = (char) c;
memmove(reply, reply+1, match_len);
reply[match_len] = '\0';
- ao_rn_dbg("\tmatch now \"%s\"\n", reply);
+// ao_rn_dbg("\tmatch now \"%s\"\n", reply);
}
- ao_rn_dbg("\twait for ok\n");
+// ao_rn_dbg("\twait for ok\n");
return AO_RN_OK;
}
{
char *l = line;
- ao_rn_dbg("wait line\n");
+// ao_rn_dbg("wait line\n");
for (;;) {
int c = ao_rn_wait_char(giveup_time);
/* timeout */
if (c == AO_READ_AGAIN) {
- ao_rn_dbg("\twait line timeout\n");
+// ao_rn_dbg("\twait line timeout\n");
return AO_RN_TIMEOUT;
}
/* done */
if (c == '\r') {
*l = '\0';
- ao_rn_dbg("\twait line \"%s\"\n", line);
+// ao_rn_dbg("\twait line \"%s\"\n", line);
return AO_RN_OK;
}
AO_TICK_TYPE giveup_time = ao_time() + AO_RN_CMD_TIMEOUT;
int status;
- ao_rn_dbg("wait status\n");
+// ao_rn_dbg("wait status\n");
status = ao_rn_wait_line(giveup_time, message, sizeof (message));
if (status == AO_RN_OK)
if (strncmp(message, "AOK", 3) != 0)
char *s = sn + 8;
int n;
- ao_rn_dbg("set name...\n");
+// ao_rn_dbg("set name...\n");
*--s = '\0';
n = ao_serial_number;
do {
static int
ao_rn_get_name(char *name, int len)
{
- ao_rn_dbg("get name...\n");
+// ao_rn_dbg("get name...\n");
ao_rn_send_cmd(AO_RN_GET_NAME_CMD, NULL);
return ao_rn_wait_line(ao_time() + AO_RN_CMD_TIMEOUT, name, len);
}
continue;
}
- ao_rn_puts("$$$");
-
/* After it reboots, it can take a moment before it responds
* to commands
*/
- (void) ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> ");
+ status = ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> ");
+
+ if (status == AO_RN_TIMEOUT) {
+ ao_rn_puts("$$$");
+ (void) ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> ");
+ }
+
+ ao_rn_send_cmd(AO_RN_VERSION_CMD, NULL);
+ (void) ao_rn_wait_status();
/* Check to see if the name is already set and assume
* that the device is ready to go
status = ao_rn_get_name(name, sizeof (name));
if (status != AO_RN_OK) {
ao_rn_dbg("get name failed\n");
- continue;
+ status = ao_rn_get_name(name, sizeof (name));
+ if (status != AO_RN_OK)
+ continue;
}
if (strncmp(name, "TeleBT-", 7) == 0) {
continue;
}
+ ao_rn_send_cmd(AO_RN_SET_STATUS_STRING, AO_RN_STATUS_STRING_ENABLE);
+ if (ao_rn_wait_status() != AO_RN_OK) {
+ ao_rn_dbg("set status string\n");
+ continue;
+ }
+
/* Select 'fast' mode to ignore command sequence (more or less) */
ao_rn_send_cmd(AO_RN_SET_FAST_MODE, NULL);
if (ao_rn_wait_status() != AO_RN_OK) {
ao_exti_enable(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN);
-#if 1
+#if AO_RN_DEBUG
+
+ /*
+ * Separate debug code when things aren't working. Just dump
+ * inbound bluetooth characters to stdout
+ */
+ for (;;) {
+ int c;
+
+ ao_arch_block_interrupts();
+ while ((c = _ao_rn_pollchar()) == AO_READ_AGAIN)
+ ao_sleep(&ao_serial_rn_rx_fifo);
+ ao_arch_release_interrupts();
+ }
+#else
ao_rn_stdio = ao_add_stdio(_ao_wrap_rn_pollchar,
- ao_wrap_rn_putchar,
+ ao_serial_rn_putchar,
NULL);
ao_rn_echo(0);
-
ao_rn_check_link();
-
- ao_rn_dbg("RN running\n");
-
/*
* Now just hang around and flash the blue LED when we've got
* a connection
ao_arch_release_interrupts();
while (ao_rn_connected) {
ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(20));
+ if (ao_rn_buf_cnt != 0)
+ ao_wakeup(&ao_stdin_ready);
ao_delay(AO_SEC_TO_TICKS(3));
}
}
-#else
-
- /*
- * Separate debug code when things aren't working. Just dump
- * inbound bluetooth characters to stdout
- */
- for (;;) {
- int c;
-
- while (rn_cmd_running)
- ao_delay(AO_MS_TO_TICKS(1000));
-
- ao_arch_block_interrupts();
- while ((c = _ao_wrap_rn_pollchar()) == AO_READ_AGAIN)
- ao_sleep(&ao_serial_rn_rx_fifo);
- ao_arch_release_interrupts();
- putchar(c); flush();
- }
#endif
}
/* Right after power on, poke P3_1 five times to force a
* factory reset
*/
- for (i = 0; i < 10; i++) {
+ for (i = 0; i < 20; i++) {
v = 1-v;
- ao_delay(AO_MS_TO_TICKS(100));
+ ao_delay(AO_MS_TO_TICKS(50));
ao_gpio_set(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, foo, v);
ao_led_toggle(AO_BT_LED);
}
/* And let P3_1 float again */
ao_enable_input(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, AO_EXTI_MODE_PULL_NONE);
+
+ printf("Reboot BT\n"); flush();
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0);
+ ao_delay(AO_MS_TO_TICKS(100));
+ ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 1);
}
+#if AO_RN_DEBUG
+static void
+ao_rn_send(void)
+{
+ int c;
+
+ while ((c = getchar()) != '~')
+ ao_rn_putchar(c);
+}
+#endif
+
static const struct ao_cmds rn_cmds[] = {
{ ao_rn_factory, "F\0Factory reset rn4678" },
+#if AO_RN_DEBUG
+ { ao_rn_send, "B\0Send data to rn4678. End with ~" },
+#endif
{ 0 },
};
*/
-#define AO_RN_REBOOT_MSG "%REBOOT%"
+#define AO_RN_REBOOT_MSG "REBOOT"
#define AO_RN_CMD_TIMEOUT AO_MS_TO_TICKS(200)
#define AO_RN_SET_NAME_CMD "SN,"
#define AO_RN_GET_NAME_CMD "GN"
-#define AO_RN_SET_STATUS_STRING "SO,"
+#define AO_RN_SET_STATUS_STRING "so,"
#define AO_RN_STATUS_STRING_DISABLE " "
+#define AO_RN_STATUS_STRING_ENABLE "%,%"
#define AO_RN_REBOOT_CMD "R,1"
+#define AO_RN_VERSION_CMD "V"
+
#define AO_RN_TIMEOUT -1
#define AO_RN_ERROR 0
#define AO_RN_OK 1
#define PACKET_HAS_SLAVE 0
-#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI
+#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI1
/* USART */
#define AO_PA11_PA12_RMP 1
#define AO_USB_FORCE_IDLE 1
-#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI
+#define AO_LOG_FORMAT AO_LOG_FORMAT_EASYMINI2
#define HAS_BOOT_RADIO 0
#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_OLD 5 /* 32 byte typed telemega records */
-#define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */
+#define AO_LOG_FORMAT_EASYMINI1 6 /* 16-byte MS5607 baro only, 3.0V supply */
#define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */
#define AO_LOG_FORMAT_TELEMINI2 8 /* 16-byte MS5607 baro only, 3.3V supply, cc1111 SoC */
#define AO_LOG_FORMAT_TELEGPS 9 /* 32 byte telegps records */
#define AO_LOG_FORMAT_DETHERM 11 /* 16-byte MS5607 baro only, no ADC */
#define AO_LOG_FORMAT_TELEMINI3 12 /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
#define AO_LOG_FORMAT_TELEFIRETWO 13 /* 32-byte test stand data */
+#define AO_LOG_FORMAT_EASYMINI2 14 /* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
extern __code uint8_t ao_log_format;
int16_t gyro_y; /* 20 */
int16_t gyro_z; /* 22 */
int16_t mag_x; /* 24 */
- int16_t mag_y; /* 26 */
- int16_t mag_z; /* 28 */
+ int16_t mag_z; /* 26 */
+ int16_t mag_y; /* 28 */
int16_t accel; /* 30 */
} sensor; /* 32 */
/* AO_LOG_TEMP_VOLT */
#endif
#if HAS_HMC5883
log.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].hmc5883.x;
- log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
log.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].hmc5883.z;
+ log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;
#endif
log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
ao_log_mega(&log);
#if HAS_HMC5883
telemetry.mega_sensor.mag_x = packet->hmc5883.x;
- telemetry.mega_sensor.mag_y = packet->hmc5883.y;
telemetry.mega_sensor.mag_z = packet->hmc5883.z;
+ telemetry.mega_sensor.mag_y = packet->hmc5883.y;
#endif
ao_telemetry_send();
int16_t gyro_z; /* 24 */
int16_t mag_x; /* 26 */
- int16_t mag_y; /* 28 */
- int16_t mag_z; /* 30 */
+ int16_t mag_z; /* 28 */
+ int16_t mag_y; /* 30 */
/* 32 */
};
#define HAS_SERIAL_1 0
#define HAS_SERIAL_2 1
#define USE_SERIAL_2_STDIN 0
-#define HAS_SERIAL_SW_FLOW 0
+#define USE_SERIAL_2_FLOW 0
+#define USE_SERIAL_2_SW_FLOW 0
#define SERIAL_2_PA2_PA3 1
#define SERIAL_2_PA14_PA15 0
#define USE_SERIAL2_FLOW 0
}
static void
-ao_usart_init(struct ao_stm_usart *usart)
+ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
{
usart->reg->cr1 = ((0 << STM_USART_CR1_OVER8) |
(1 << STM_USART_CR1_UE) |
(0 << STM_USART_CR3_IREN) |
(0 << STM_USART_CR3_EIE));
+ if (hw_flow)
+ usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
+ (1 << STM_USART_CR3_RTSE));
+
/* Pick a 9600 baud rate */
ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);
}
static void
ao_usart_set_flow(struct ao_stm_usart *usart)
{
- usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
- (1 << STM_USART_CR3_RTSE));
}
#endif
stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);
ao_stm_usart1.reg = &stm_usart1;
- ao_usart_init(&ao_stm_usart1);
+ ao_usart_init(&ao_stm_usart1, 0);
stm_nvic_set_enable(STM_ISR_USART1_POS);
stm_nvic_set_priority(STM_ISR_USART1_POS, AO_STM_NVIC_MED_PRIORITY);
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);
ao_stm_usart2.reg = &stm_usart2;
- ao_usart_init(&ao_stm_usart2);
-#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
- ao_usart_set_flow(&ao_stm_usart2);
-#endif
+ ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, AO_STM_NVIC_MED_PRIORITY);
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART3EN);
ao_stm_usart3.reg = &stm_usart3;
- ao_usart_init(&ao_stm_usart3);
+ ao_usart_init(&ao_stm_usart3, 0);
stm_nvic_set_enable(STM_ISR_USART3_POS);
stm_nvic_set_priority(STM_ISR_USART3_POS, AO_STM_NVIC_MED_PRIORITY);
}
static void
-ao_usart_init(struct ao_stm_usart *usart)
+ao_usart_init(struct ao_stm_usart *usart, int hw_flow)
{
usart->reg->cr1 = ((0 << STM_USART_CR1_M1) |
(0 << STM_USART_CR1_EOBIE) |
(0 << STM_USART_CR2_LBDL) |
(0 << STM_USART_CR2_ADDM7));
- usart->reg->cr3 = ((0 << STM_USART_CR3_WUFIE) |
- (0 << STM_USART_CR3_WUS) |
- (0 << STM_USART_CR3_SCARCNT) |
- (0 << STM_USART_CR3_DEP) |
- (0 << STM_USART_CR3_DEM) |
- (0 << STM_USART_CR3_DDRE) |
- (0 << STM_USART_CR3_OVRDIS) |
- (0 << STM_USART_CR3_ONEBIT) |
- (0 << STM_USART_CR3_CTIIE) |
- (0 << STM_USART_CR3_CTSE) |
- (0 << STM_USART_CR3_RTSE) |
- (0 << STM_USART_CR3_DMAT) |
- (0 << STM_USART_CR3_DMAR) |
- (0 << STM_USART_CR3_SCEN) |
- (0 << STM_USART_CR3_NACK) |
- (0 << STM_USART_CR3_HDSEL) |
- (0 << STM_USART_CR3_IRLP) |
- (0 << STM_USART_CR3_IREN) |
- (0 << STM_USART_CR3_EIE));
-
+ uint32_t cr3 = ((0 << STM_USART_CR3_WUFIE) |
+ (0 << STM_USART_CR3_WUS) |
+ (0 << STM_USART_CR3_SCARCNT) |
+ (0 << STM_USART_CR3_DEP) |
+ (0 << STM_USART_CR3_DEM) |
+ (0 << STM_USART_CR3_DDRE) |
+ (0 << STM_USART_CR3_OVRDIS) |
+ (0 << STM_USART_CR3_ONEBIT) |
+ (0 << STM_USART_CR3_CTIIE) |
+ (0 << STM_USART_CR3_CTSE) |
+ (0 << STM_USART_CR3_RTSE) |
+ (0 << STM_USART_CR3_DMAT) |
+ (0 << STM_USART_CR3_DMAR) |
+ (0 << STM_USART_CR3_SCEN) |
+ (0 << STM_USART_CR3_NACK) |
+ (0 << STM_USART_CR3_HDSEL) |
+ (0 << STM_USART_CR3_IRLP) |
+ (0 << STM_USART_CR3_IREN) |
+ (0 << STM_USART_CR3_EIE));
+
+ if (hw_flow)
+ cr3 |= ((1 << STM_USART_CR3_CTSE) |
+ (1 << STM_USART_CR3_RTSE));
+
+ usart->reg->cr3 = cr3;
/* Pick a 9600 baud rate */
ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);
/* Enable the usart */
usart->reg->cr1 |= (1 << STM_USART_CR1_UE);
-
}
-#if HAS_SERIAL_HW_FLOW
-static void
-ao_usart_set_flow(struct ao_stm_usart *usart)
-{
- usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) |
- (1 << STM_USART_CR3_RTSE));
-}
-#endif
-
#if HAS_SERIAL_1
struct ao_stm_usart ao_stm_usart1;
*/
#if SERIAL_1_PA9_PA10
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 9, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 10, STM_AFR_AF1);
#else
#if SERIAL_1_PB6_PB7
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPBEN);
+ ao_enable_port(&stm_gpiob);
stm_afr_set(&stm_gpiob, 6, STM_AFR_AF0);
stm_afr_set(&stm_gpiob, 7, STM_AFR_AF0);
stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);
ao_stm_usart1.reg = &stm_usart1;
- ao_usart_init(&ao_stm_usart1);
+ ao_usart_init(&ao_stm_usart1, 0);
stm_nvic_set_enable(STM_ISR_USART1_POS);
stm_nvic_set_priority(STM_ISR_USART1_POS, 4);
*/
# if SERIAL_2_PA2_PA3
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
-
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 2, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 3, STM_AFR_AF1);
# if USE_SERIAL_2_FLOW
# endif
# else
# if SERIAL_2_PA14_PA15
- stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
-
+ ao_enable_port(&stm_gpioa);
stm_afr_set(&stm_gpioa, 14, STM_AFR_AF1);
stm_afr_set(&stm_gpioa, 15, STM_AFR_AF1);
# if USE_SERIAL_2_FLOW
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);
ao_stm_usart2.reg = &stm_usart2;
- ao_usart_init(&ao_stm_usart2);
-# if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
- ao_usart_set_flow(&ao_stm_usart2);
-# endif
+ ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);
stm_nvic_set_enable(STM_ISR_USART2_POS);
stm_nvic_set_priority(STM_ISR_USART2_POS, 4);
ao_convert_volt.c \
ao_packet_master.c \
ao_packet.c \
+ ao_send_packet.c \
ao_monitor.c \
$(PROFILE) \
$(SAMPLE_PROFILE) \
#include <ao_profile.h>
#include <ao_btm.h>
#include <ao_lco_cmd.h>
+#include <ao_send_packet.h>
#if HAS_SAMPLE_PROFILE
#include <ao_sample_profile.h>
#endif
ao_radio_init();
ao_packet_master_init();
ao_monitor_init();
+ ao_send_packet_init();
ao_config_init();
ao_product.h \
ao_cc1200_CC1200.h \
ao_task.h \
+ ao_rn4678.h \
stm32f0.h \
Makefile
#define USE_SERIAL_2_STDIN 1
#define DELAY_SERIAL_2_STDIN 1
#define USE_SERIAL_2_FLOW 1
-#define USE_SERIAL_2_SW_FLOW 1
+#define USE_SERIAL_2_SW_FLOW 0
#define SERIAL_2_PA2_PA3 1
#define SERIAL_2_PD5_PD6 0
#define SERIAL_2_PORT_RTS (&stm_gpioa)
#define HAS_APRS 0
#define HAS_ACCEL 0
#define HAS_AES 0
-#define HAS_POLLCHAR 1
#define HAS_SPI_1 1
#define SPI_1_PA5_PA6_PA7 1 /* CC1200 */
#define HAS_EEPROM 1
#define HAS_LOG 1
#define HAS_PAD 1
-#define USE_INTERNAL_FLASH 0
+#define USE_INTERNAL_FLASH 1
#define IGNITE_ON_P0 0
#define PACKET_HAS_MASTER 0
#define PACKET_HAS_SLAVE 0
vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product:../lisp
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_flight_test_metrum ao_flight_test_mini \
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 ao_lisp_test
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_flight_test_mini: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
+ cc -DEASYMINI=1 -DHAS_ACCEL=0 $(CFLAGS) -o $@ $< -lm
+
ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h
cc $(CFLAGS) -o $@ $<
int ao_gps_new;
-#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2)
+#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI)
#define TELEMETRUM_V1 1
#endif
};
#endif
+#if EASYMINI
+#define AO_ADC_NUM_SENSE 2
+#define HAS_MS5607 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;
+};
+#endif
#if TELEMETRUM_V1
/*
#define ao_xmemcmp(d,s,c) memcmp(d,s,c)
#define AO_NEED_ALTITUDE_TO_PRES 1
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
#include "ao_convert_pa.c"
#include <ao_ms5607.h>
struct ao_ms5607_prom ao_ms5607_prom;
#else
double accel = 0.0;
#endif
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
double height;
ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked);
return (int32_t) uint32(bytes, off);
}
+uint32_t
+uint24(uint8_t *bytes, int off)
+{
+ return (uint32_t) bytes[off] | (((uint32_t) bytes[off+1]) << 8) |
+ (((uint32_t) bytes[off+2]) << 16);
+}
+
+int32_t
+int24(uint8_t *bytes, int off)
+{
+ return (int32_t) uint24(bytes, off);
+}
+
static int log_format;
void
for (;;) {
if (ao_records_read > 2 && ao_flight_state == ao_flight_startup)
{
+
#if TELEMEGA
ao_data_static.mpu6000 = ao_ground_mpu6000;
#endif
#if TELEMETRUM_V1
ao_data_static.adc.accel = ao_flight_ground_accel;
#endif
+
ao_insert();
return;
}
}
}
#endif
+#if EASYMINI
+ if ((log_format == AO_LOG_FORMAT_EASYMINI1 || log_format == AO_LOG_FORMAT_EASYMINI2) && 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_started = 1;
+ ao_ground_pres = uint32(bytes, 4);
+ ao_ground_height = ao_pa_to_altitude(ao_ground_pres);
+#if 0
+ printf("ground pres %d height %d\n", ao_ground_pres, ao_ground_height);
+ printf("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d\n",
+ ao_ms5607_prom.sens,
+ ao_ms5607_prom.off,
+ ao_ms5607_prom.tcs,
+ ao_ms5607_prom.tco,
+ ao_ms5607_prom.tref,
+ ao_ms5607_prom.tempsens,
+ ao_ms5607_prom.crc);
+#endif
+ break;
+ case 'A':
+ ao_data_static.tick = tick;
+ ao_data_static.ms5607_raw.pres = int24(bytes, 0);
+ ao_data_static.ms5607_raw.temp = int24(bytes, 3);
+#if 0
+ printf("raw pres %d temp %d\n",
+ ao_data_static.ms5607_raw.pres,
+ ao_data_static.ms5607_raw.temp);
+#endif
+ ao_ms5607_convert(&ao_data_static.ms5607_raw, &value);
+// printf("pres %d height %d\n", value.pres, ao_pa_to_altitude(value.pres));
+ 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_V2
if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) {
int i;
if (type != 'F' && !ao_flight_started)
continue;
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
(void) a;
(void) b;
#else
import java.util.concurrent.*;
import java.util.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPS
extends AltosUIFrame
status_update.saved_listener_state = listener_state;
if (state == null)
- state = new AltosState();
+ state = new AltosState(new AltosCalData());
int i = 0;
for (AltosFlightDisplay display : displays) {
new TeleGPSConfig(this);
}
+ private static AltosFlightSeries make_series(AltosRecordSet set) {
+ AltosFlightSeries series = new AltosFlightSeries(set.cal_data());
+ set.capture_series(series);
+ series.finish();
+ return series;
+ }
+
void export() {
- AltosDataChooser chooser;
- chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosDataChooser chooser = new AltosDataChooser(this);
+
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
- new AltosCSVUI(this, states, chooser.file());
+ AltosFlightSeries series = make_series(set);
+ new AltosCSVUI(this, series, chooser.file());
}
void graph() {
- AltosDataChooser chooser;
- chooser = new AltosDataChooser(this);
- AltosStateIterable states = chooser.runDialog();
- if (states == null)
+ AltosDataChooser chooser = new AltosDataChooser(this);
+ AltosRecordSet set = chooser.runDialog();
+ if (set == null)
return;
try {
- new TeleGPSGraphUI(states, chooser.file());
+ new TeleGPSGraphUI(set, chooser.file());
} catch (InterruptedException ie) {
} catch (IOException ie) {
}
connect(device);
}
- static AltosStateIterable record_iterable(File file) {
- FileInputStream in;
- if (file.getName().endsWith("telem")) {
- try {
- in = new FileInputStream(file);
- return new AltosTelemetryFile(in);
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
- }
- } else {
-
- try {
- AltosEepromFile f = new AltosEepromFile(new FileReader(file));
- return f;
- } catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
- }
+ static AltosRecordSet record_set(File file) {
+ try {
+ return AltosLib.record_set(file);
+ } catch (IOException ie) {
+ System.out.printf("%s\n", ie.getMessage());
}
return null;
}
static AltosReplayReader replay_file(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return null;
- return new AltosReplayReader(states.iterator(), file);
+ return new AltosReplayReader(set, file);
}
static boolean process_graph(File file) {
- AltosStateIterable states = record_iterable(file);
- if (states == null)
+ AltosRecordSet set = record_set(file);
+ if (set == null)
return false;
try {
- new TeleGPSGraphUI(states, file);
+ new TeleGPSGraphUI(set, file);
} catch (Exception e) {
return false;
}
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSConfigUI
extends AltosUIDialog
}
public double pyro_firing_time() {
- return -1;
+ return AltosLib.MISSING;
}
boolean is_telemetrum() {
}
void set_radio_enable_tool_tip() {
- if (radio_enable_value.isEnabled())
+ if (radio_enable_value.isVisible())
radio_enable_value.setToolTipText("Enable/Disable telemetry and RDF transmissions");
else
radio_enable_value.setToolTipText("Firmware version does not support disabling radio");
}
void set_rate_tool_tip() {
- if (rate_value.isEnabled())
+ if (rate_value.isVisible())
rate_value.setToolTipText("Select telemetry baud rate");
else
rate_value.setToolTipText("Firmware version does not support variable telemetry rates");
}
void set_aprs_interval_tool_tip() {
- if (aprs_interval_value.isEnabled())
+ if (aprs_interval_value.isVisible())
aprs_interval_value.setToolTipText("Enable APRS and set the interval between APRS reports");
else
aprs_interval_value.setToolTipText("Hardware doesn't support APRS");
}
void set_aprs_ssid_tool_tip() {
- if (aprs_ssid_value.isEnabled())
+ if (aprs_ssid_value.isVisible())
aprs_ssid_value.setToolTipText("Set the APRS SSID (secondary station identifier)");
- else if (aprs_ssid_value.isEnabled())
+ else if (aprs_ssid_value.isVisible())
aprs_ssid_value.setToolTipText("Software version doesn't support setting the APRS SSID");
else
aprs_ssid_value.setToolTipText("Hardware doesn't support APRS");
}
void set_aprs_format_tool_tip() {
- if (aprs_format_value.isEnabled())
+ if (aprs_format_value.isVisible())
aprs_format_value.setToolTipText("Set the APRS format (compressed/uncompressed)");
- else if (aprs_format_value.isEnabled())
+ else if (aprs_format_value.isVisible())
aprs_format_value.setToolTipText("Software version doesn't support setting the APRS format");
else
aprs_format_value.setToolTipText("Hardware doesn't support APRS");
}
void set_flight_log_max_tool_tip() {
- if (flight_log_max_value.isEnabled())
+ if (flight_log_max_value.isVisible())
flight_log_max_value.setToolTipText("Size reserved for each flight log (in kB)");
else
flight_log_max_value.setToolTipText("Cannot set max value with flight logs in memory");
public void units_changed(boolean imperial_units) {
boolean was_dirty = dirty;
- if (tracker_motion_value.isEnabled()) {
+ if (tracker_motion_value.isVisible()) {
String motion = tracker_motion_value.getSelectedItem().toString();
tracker_motion_label.setText(get_tracker_motion_label());
set_tracker_motion_values();
}
public int main_deploy() {
- return -1;
+ return AltosLib.MISSING;
}
public void set_apogee_delay(int new_apogee_delay) { }
public int apogee_delay() {
- return -1;
+ return AltosLib.MISSING;
}
public void set_apogee_lockout(int new_apogee_lockout) { }
- public int apogee_lockout() { return -1; }
+ public int apogee_lockout() { return AltosLib.MISSING; }
public void set_radio_frequency(double new_radio_frequency) {
- radio_frequency_value.set_frequency(new_radio_frequency);
+ if (new_radio_frequency != AltosLib.MISSING)
+ radio_frequency_value.set_frequency(new_radio_frequency);
+ radio_frequency_label.setVisible(new_radio_frequency != AltosLib.MISSING);
+ radio_frequency_value.setVisible(new_radio_frequency != AltosLib.MISSING);
}
public double radio_frequency() {
}
public void set_radio_calibration(int new_radio_calibration) {
- radio_calibration_value.setVisible(new_radio_calibration >= 0);
- if (new_radio_calibration < 0)
- radio_calibration_value.setText("Disabled");
- else
+ if (new_radio_calibration != AltosLib.MISSING)
radio_calibration_value.setText(String.format("%d", new_radio_calibration));
- }
-
- private int parse_int(String name, String s, boolean split) throws AltosConfigDataException {
- String v = s;
- if (split)
- v = s.split("\\s+")[0];
- try {
- return Integer.parseInt(v);
- } catch (NumberFormatException ne) {
- throw new AltosConfigDataException("Invalid %s \"%s\"", name, s);
- }
+ radio_calibration_value.setVisible(new_radio_calibration == AltosLib.MISSING);
+ radio_calibration_label.setVisible(new_radio_calibration == AltosLib.MISSING);
}
public void set_radio_enable(int new_radio_enable) {
- if (new_radio_enable >= 0) {
- radio_enable_value.setSelected(new_radio_enable > 0);
- radio_enable_value.setEnabled(true);
- } else {
- radio_enable_value.setSelected(true);
- radio_enable_value.setVisible(radio_frequency() > 0);
- radio_enable_value.setEnabled(false);
- }
+ if (new_radio_enable != AltosLib.MISSING)
+ radio_enable_value.setSelected(new_radio_enable != 0);
+ radio_enable_label.setVisible(new_radio_enable != AltosLib.MISSING);
+ radio_enable_value.setVisible(new_radio_enable != AltosLib.MISSING);
set_radio_enable_tool_tip();
}
public int radio_enable() {
- if (radio_enable_value.isEnabled())
+ if (radio_enable_value.isVisible())
return radio_enable_value.isSelected() ? 1 : 0;
else
- return -1;
+ return AltosLib.MISSING;
}
public void set_telemetry_rate(int new_rate) {
- rate_value.set_rate(new_rate);
+ if (new_rate != AltosLib.MISSING)
+ rate_value.set_rate(new_rate);
+ rate_label.setVisible(new_rate != AltosLib.MISSING);
+ rate_value.setVisible(new_rate != AltosLib.MISSING);
}
public int telemetry_rate() {
}
public void set_callsign(String new_callsign) {
+ if (new_callsign != null)
+ callsign_value.setText(new_callsign);
callsign_value.setVisible(new_callsign != null);
- callsign_value.setText(new_callsign);
+ callsign_label.setVisible(new_callsign != null);
}
public String callsign() {
- return callsign_value.getText();
+ if (callsign_value.isVisible())
+ return callsign_value.getText();
+ return null;
+ }
+
+ private int parse_int(String name, String s, boolean split) throws AltosConfigDataException {
+ String v = s;
+ if (split)
+ v = s.split("\\s+")[0];
+ try {
+ return Integer.parseInt(v);
+ } catch (NumberFormatException ne) {
+ throw new AltosConfigDataException("Invalid %s \"%s\"", name, s);
+ }
}
int flight_log_max_limit;
}
public void set_ignite_mode(int new_ignite_mode) { }
- public int ignite_mode() { return -1; }
+ public int ignite_mode() { return AltosLib.MISSING; }
public void set_pad_orientation(int new_pad_orientation) { }
- public int pad_orientation() { return -1; }
+ public int pad_orientation() { return AltosLib.MISSING; }
public void set_beep(int new_beep) { }
- public int beep() { return -1; }
+ public int beep() { return AltosLib.MISSING; }
String[] tracker_motion_values() {
if (AltosConvert.imperial_units)
}
void set_tracker_tool_tip() {
- if (tracker_motion_value.isEnabled())
+ if (tracker_motion_value.isVisible())
tracker_motion_value.setToolTipText("How far the device must move before logging");
else
tracker_motion_value.setToolTipText("This device doesn't disable logging when stationary");
- if (tracker_interval_value.isEnabled())
+ if (tracker_interval_value.isVisible())
tracker_interval_value.setToolTipText("How often to report GPS position");
else
tracker_interval_value.setToolTipText("This device can't configure interval");
}
public void set_tracker_motion(int tracker_motion) {
- if (tracker_motion < 0) {
- tracker_motion_value.setEnabled(false);
- } else {
- tracker_motion_value.setEnabled(true);
+ if (tracker_motion != AltosLib.MISSING)
tracker_motion_value.setSelectedItem(AltosConvert.height.say(tracker_motion));
- }
+ tracker_motion_label.setVisible(tracker_motion != AltosLib.MISSING);
+ tracker_motion_value.setVisible(tracker_motion != AltosLib.MISSING);
}
public int tracker_motion() throws AltosConfigDataException {
- String str = tracker_motion_value.getSelectedItem().toString();
- try {
- return (int) (AltosConvert.height.parse_locale(str) + 0.5);
- } catch (ParseException pe) {
- throw new AltosConfigDataException("invalid tracker motion %s", str);
+ if (tracker_motion_value.isVisible()) {
+ String str = tracker_motion_value.getSelectedItem().toString();
+ try {
+ return (int) (AltosConvert.height.parse_locale(str) + 0.5);
+ } catch (ParseException pe) {
+ throw new AltosConfigDataException("invalid tracker motion %s", str);
+ }
}
+ return AltosLib.MISSING;
}
public void set_tracker_interval(int tracker_interval) {
- if (tracker_interval< 0) {
- tracker_interval_value.setEnabled(false);
- } else {
- tracker_interval_value.setEnabled(true);
+ if (tracker_interval != AltosLib.MISSING)
tracker_interval_value.setSelectedItem(String.format("%d", tracker_interval));
- }
+ tracker_interval_label.setVisible(tracker_interval != AltosLib.MISSING);
+ tracker_interval_value.setVisible(tracker_interval != AltosLib.MISSING);
}
public int tracker_interval() throws AltosConfigDataException {
- return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
+ if (tracker_interval_value.isVisible())
+ return parse_int ("tracker interval", tracker_interval_value.getSelectedItem().toString(), false);
+ return AltosLib.MISSING;
}
public void set_aprs_interval(int new_aprs_interval) {
- String s;
-
- if (new_aprs_interval <= 0)
- s = "Disabled";
- else
- s = Integer.toString(new_aprs_interval);
- aprs_interval_value.setSelectedItem(s);
- aprs_interval_value.setVisible(new_aprs_interval >= 0);
+ if (new_aprs_interval != AltosLib.MISSING)
+ aprs_interval_value.setSelectedItem(Integer.toString(new_aprs_interval));
+ aprs_interval_value.setVisible(new_aprs_interval != AltosLib.MISSING);
+ aprs_interval_label.setVisible(new_aprs_interval != AltosLib.MISSING);
set_aprs_interval_tool_tip();
}
public int aprs_interval() throws AltosConfigDataException {
- String s = aprs_interval_value.getSelectedItem().toString();
+ if (aprs_interval_value.isVisible()) {
+ String s = aprs_interval_value.getSelectedItem().toString();
- if (s.equals("Disabled"))
- return 0;
- return parse_int("aprs interval", s, false);
+ return parse_int("aprs interval", s, false);
+ }
+ return AltosLib.MISSING;
}
public void set_aprs_ssid(int new_aprs_ssid) {
- aprs_ssid_value.setSelectedItem(Math.max(0,new_aprs_ssid));
- aprs_ssid_value.setVisible(new_aprs_ssid >= 0);
+ if (new_aprs_ssid != AltosLib.MISSING)
+ aprs_ssid_value.setSelectedItem(new_aprs_ssid);
+ aprs_ssid_value.setVisible(new_aprs_ssid != AltosLib.MISSING);
+ aprs_ssid_label.setVisible(new_aprs_ssid != AltosLib.MISSING);
set_aprs_ssid_tool_tip();
}
public int aprs_ssid() throws AltosConfigDataException {
- Integer i = (Integer) aprs_ssid_value.getSelectedItem();
- return i;
+ if (aprs_ssid_value.isVisible()) {
+ Integer i = (Integer) aprs_ssid_value.getSelectedItem();
+ return i;
+ }
+ return AltosLib.MISSING;
}
public void set_aprs_format(int new_aprs_format) {
- aprs_format_value.setVisible(new_aprs_format >= 0);
- aprs_format_label.setVisible(new_aprs_format >= 0);
-
- aprs_format_value.setSelectedIndex(Math.max(0,new_aprs_format));
+ if (new_aprs_format != AltosLib.MISSING)
+ aprs_format_value.setSelectedIndex(new_aprs_format);
+ aprs_format_value.setVisible(new_aprs_format != AltosLib.MISSING);
+ aprs_format_label.setVisible(new_aprs_format != AltosLib.MISSING);
set_aprs_format_tool_tip();
}
public int aprs_format() throws AltosConfigDataException {
- return aprs_format_value.getSelectedIndex();
+ if (aprs_format_value.isVisible())
+ return aprs_format_value.getSelectedIndex();
+ return AltosLib.MISSING;
}
}
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSDisplayThread extends Thread {
IdleThread idle_thread;
AltosVoice voice;
AltosFlightReader reader;
- AltosState old_state, state;
+ AltosState state;
+ int old_state = AltosLib.ao_flight_invalid;
+ boolean old_gps_ready = false;
AltosListenerState listener_state;
AltosFlightDisplay display;
}
public synchronized void notice(boolean spoken) {
- if (old_state != null && old_state.state() != state.state()) {
+ if (old_state != state.state()) {
report_time = now();
this.notify();
} else if (spoken)
set_report_time();
+ old_state = state.state();
}
public IdleThread() {
synchronized boolean tell() {
boolean ret = false;
- if (old_state == null || old_state.gps_ready != state.gps_ready) {
+ if (old_gps_ready != state.gps_ready) {
if (state.gps_ready) {
voice.speak("GPS ready");
ret = true;
}
- else if (old_state != null) {
+ else if (old_gps_ready) {
voice.speak("GPS lost");
ret = true;
}
+ old_gps_ready = state.gps_ready;
}
- old_state = state;
return ret;
}
listener_state.running = false;
break;
}
- reader.update(state);
show_safely();
told = tell();
idle_thread.notice(told);
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.ui.RefineryUtilities;
-public class TeleGPSGraphUI extends AltosUIFrame
+public class TeleGPSGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener
{
JTabbedPane pane;
AltosGraph graph;
AltosUIMap map;
AltosState state;
AltosFlightStats stats;
- AltosGraphDataSet graphDataSet;
AltosFlightStatsTable statsTable;
-
- void fill_map(AltosStateIterable states) {
- for (AltosState state : states) {
- if (state.gps != null && state.gps.locked && state.gps.nsat >= 4)
- map.show(state, null);
+ AltosGPS gps;
+ boolean has_gps;
+
+ void fill_map(AltosFlightSeries flight_series) {
+ boolean any_gps = false;
+ AltosGPSTimeValue gtv_last = null;
+
+ if (flight_series.gps_series != null) {
+ for (AltosGPSTimeValue gtv : flight_series.gps_series) {
+ gtv_last = gtv;
+ AltosGPS gps = gtv.gps;
+ if (gps != null &&
+ gps.locked &&
+ gps.nsat >= 4) {
+ if (map == null)
+ map = new AltosUIMap();
+ map.show(gps, (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time));
+ this.gps = gps;
+ has_gps = true;
+ }
+ }
+ }
+ if (gtv_last != null) {
+ int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time);
+ if (state == AltosLib.ao_flight_landed)
+ map.show(gtv_last.gps, state);
}
}
TeleGPS.subtract_window();
}
- TeleGPSGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException {
+ public void font_size_changed(int font_size) {
+ if (map != null)
+ map.font_size_changed(font_size);
+ if (statsTable != null)
+ statsTable.font_size_changed(font_size);
+ }
+
+ public void units_changed(boolean imperial_units) {
+ if (map != null)
+ map.units_changed(imperial_units);
+ if (enable != null)
+ enable.units_changed(imperial_units);
+ }
+
+ TeleGPSGraphUI(AltosRecordSet set, File file) throws InterruptedException, IOException {
super(file.getName());
- state = null;
+ AltosCalData cal_data = set.cal_data();
+
+ AltosUIFlightSeries flight_series = new AltosUIFlightSeries(cal_data);
+ set.capture_series(flight_series);
+ flight_series.finish();
pane = new JTabbedPane();
enable = new AltosUIEnable();
- stats = new AltosFlightStats(states);
- graphDataSet = new AltosGraphDataSet(states);
- graph = new AltosGraph(enable, stats, graphDataSet);
+ stats = new AltosFlightStats(flight_series);
+
+ graph = new AltosGraph(enable, stats, flight_series);
+
statsTable = new AltosFlightStatsTable(stats);
map = new AltosUIMap();
pane.add("Graph", graph.panel);
pane.add("Configure Graph", enable);
pane.add("Statistics", statsTable);
- fill_map(states);
+ fill_map(flight_series);
pane.add("Map", map);
setContentPane (pane);
+ AltosUIPreferences.register_font_listener(this);
+ AltosPreferences.register_units_listener(this);
+
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSInfo extends AltosUIFlightTab {
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSPreferences
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSState extends AltosUIFlightTab {
class FirmwareVersion extends AltosUIIndicator {
public void show(AltosState state, AltosListenerState listener_state) {
- if (state.firmware_version == null)
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.firmware_version == null)
show("Missing");
else
- show(state.firmware_version);
+ show(cal_data.firmware_version);
}
public FirmwareVersion(Container container, int y) {
class FlightLogMax extends AltosUIIndicator {
public void show(AltosState state, AltosListenerState listener_state) {
- int storage = state.flight_log_max;
- if (storage == AltosLib.MISSING)
- storage = state.log_space >> 10;
+ AltosCalData cal_data = state.cal_data();
+ int storage = cal_data.flight_log_max;
if (storage == AltosLib.MISSING)
show("Missing");
else
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_11.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altoslib_12.*;
+import org.altusmetrum.altosuilib_12.*;
public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
String call;
void show(AltosState state, AltosListenerState listener_state) {
- if (state.callsign != call) {
- value.setText(state.callsign);
- call = state.callsign;
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data == null)
+ System.out.printf("null cal data?\n");
+ if (cal_data.callsign != call) {
+ value.setText(cal_data.callsign);
+ call = cal_data.callsign;
}
- if (state.callsign == null)
+ if (cal_data.callsign == null)
setVisible(false);
else
setVisible(true);
class Serial extends Value {
int serial = -1;
void show(AltosState state, AltosListenerState listener_state) {
- if (state.serial != serial) {
- if (state.serial == AltosLib.MISSING)
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.serial != serial) {
+ if (cal_data.serial == AltosLib.MISSING)
value.setText("none");
else
- value.setText(String.format("%d", state.serial));
- serial = state.serial;
+ value.setText(String.format("%d", cal_data.serial));
+ serial = cal_data.serial;
}
}
int last_flight = -1;
void show(AltosState state, AltosListenerState listener_state) {
- if (state.flight != last_flight) {
- if (state.flight == AltosLib.MISSING)
+ AltosCalData cal_data = state.cal_data();
+ if (cal_data.flight != last_flight) {
+ if (cal_data.flight == AltosLib.MISSING)
value.setText("none");
else
- value.setText(String.format("%d", state.flight));
- last_flight = state.flight;
+ value.setText(String.format("%d", cal_data.flight));
+ last_flight = cal_data.flight;
}
}
package org.altusmetrum.telegps;
import java.awt.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
public class TeleGPSStatusUpdate implements ActionListener {