Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
authorBdale Garbee <bdale@gag.com>
Fri, 21 Jul 2017 23:44:03 +0000 (17:44 -0600)
committerBdale Garbee <bdale@gag.com>
Fri, 21 Jul 2017 23:44:03 +0000 (17:44 -0600)
326 files changed:
altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDebug.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosUsb.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
altosdroid/src/org/altusmetrum/AltosDroid/IdleModeActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/ManageFrequenciesActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/MapTypeActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/PreloadMapActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/SetupActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/TabFlight.java
altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
altosdroid/src/org/altusmetrum/AltosDroid/TabRecover.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryState.java
altoslib/AltosAccel.java
altoslib/AltosCRCException.java
altoslib/AltosCSV.java
altoslib/AltosCalData.java [new file with mode: 0644]
altoslib/AltosCompanion.java
altoslib/AltosConfigData.java
altoslib/AltosConfigDataException.java
altoslib/AltosConfigValues.java
altoslib/AltosConvert.java
altoslib/AltosDataListener.java [new file with mode: 0644]
altoslib/AltosDataProvider.java [new file with mode: 0644]
altoslib/AltosDebug.java
altoslib/AltosDistance.java
altoslib/AltosEeprom.java
altoslib/AltosEepromChunk.java
altoslib/AltosEepromDownload.java
altoslib/AltosEepromFile.java
altoslib/AltosEepromList.java
altoslib/AltosEepromLog.java
altoslib/AltosEepromMonitor.java
altoslib/AltosEepromNew.java [deleted file]
altoslib/AltosEepromRecord.java
altoslib/AltosEepromRecordFireTwo.java
altoslib/AltosEepromRecordFull.java
altoslib/AltosEepromRecordGps.java
altoslib/AltosEepromRecordMega.java
altoslib/AltosEepromRecordMetrum.java
altoslib/AltosEepromRecordMini.java
altoslib/AltosEepromRecordSet.java
altoslib/AltosEepromRecordTiny.java
altoslib/AltosFile.java
altoslib/AltosFlash.java
altoslib/AltosFlashListener.java
altoslib/AltosFlightDisplay.java
altoslib/AltosFlightListener.java [new file with mode: 0644]
altoslib/AltosFlightReader.java
altoslib/AltosFlightSeries.java [new file with mode: 0644]
altoslib/AltosFlightStats.java
altoslib/AltosFontListener.java
altoslib/AltosForce.java
altoslib/AltosFrequency.java
altoslib/AltosGPS.java
altoslib/AltosGPSSat.java
altoslib/AltosGPSTimeValue.java [new file with mode: 0644]
altoslib/AltosGreatCircle.java
altoslib/AltosHeight.java
altoslib/AltosHexfile.java
altoslib/AltosHexsym.java
altoslib/AltosIMU.java
altoslib/AltosIdle.java
altoslib/AltosIdleFetch.java
altoslib/AltosIdleMonitor.java
altoslib/AltosIdleMonitorListener.java
altoslib/AltosIdleReader.java
altoslib/AltosIgnite.java
altoslib/AltosImage.java
altoslib/AltosJson.java
altoslib/AltosKML.java
altoslib/AltosLatLon.java
altoslib/AltosLatitude.java
altoslib/AltosLaunchSite.java
altoslib/AltosLaunchSiteListener.java
altoslib/AltosLaunchSites.java
altoslib/AltosLib.java
altoslib/AltosLine.java
altoslib/AltosLink.java
altoslib/AltosListenerState.java
altoslib/AltosLocation.java
altoslib/AltosLog.java
altoslib/AltosLongitude.java
altoslib/AltosMag.java
altoslib/AltosMap.java
altoslib/AltosMapCache.java
altoslib/AltosMapCacheListener.java
altoslib/AltosMapInterface.java
altoslib/AltosMapLine.java
altoslib/AltosMapLoader.java
altoslib/AltosMapLoaderListener.java
altoslib/AltosMapMark.java
altoslib/AltosMapPath.java
altoslib/AltosMapPathPoint.java
altoslib/AltosMapRectangle.java
altoslib/AltosMapStore.java
altoslib/AltosMapStoreListener.java
altoslib/AltosMapTile.java
altoslib/AltosMapTileListener.java
altoslib/AltosMapTransform.java
altoslib/AltosMapTypeListener.java
altoslib/AltosMapZoomListener.java
altoslib/AltosMma655x.java
altoslib/AltosMs5607.java
altoslib/AltosNoSymbol.java
altoslib/AltosOrient.java
altoslib/AltosParse.java
altoslib/AltosPointDouble.java
altoslib/AltosPointInt.java
altoslib/AltosPreferences.java
altoslib/AltosPreferencesBackend.java
altoslib/AltosPresTemp.java [new file with mode: 0644]
altoslib/AltosPressure.java
altoslib/AltosProgrammer.java
altoslib/AltosPyro.java
altoslib/AltosPyroName.java [new file with mode: 0644]
altoslib/AltosQuaternion.java
altoslib/AltosRecordSet.java [new file with mode: 0644]
altoslib/AltosRectangle.java
altoslib/AltosReplayReader.java
altoslib/AltosRomconfig.java
altoslib/AltosRotation.java
altoslib/AltosRotationRate.java [new file with mode: 0644]
altoslib/AltosSavedState.java
altoslib/AltosSelfFlash.java
altoslib/AltosSensorEMini.java
altoslib/AltosSensorMM.java
altoslib/AltosSensorMega.java
altoslib/AltosSensorMetrum.java
altoslib/AltosSensorTGPS.java
altoslib/AltosSensorTM.java
altoslib/AltosSensorTMini2.java
altoslib/AltosSensorTMini3.java
altoslib/AltosSpeed.java
altoslib/AltosState.java
altoslib/AltosStateIterable.java [deleted file]
altoslib/AltosStateName.java [new file with mode: 0644]
altoslib/AltosStateUpdate.java [deleted file]
altoslib/AltosStringInputStream.java [new file with mode: 0644]
altoslib/AltosTelemetry.java
altoslib/AltosTelemetryCompanion.java
altoslib/AltosTelemetryConfiguration.java
altoslib/AltosTelemetryFile.java
altoslib/AltosTelemetryIterable.java
altoslib/AltosTelemetryLegacy.java
altoslib/AltosTelemetryLocation.java
altoslib/AltosTelemetryMap.java
altoslib/AltosTelemetryMegaData.java
altoslib/AltosTelemetryMegaSensor.java
altoslib/AltosTelemetryMetrumData.java
altoslib/AltosTelemetryMetrumSensor.java
altoslib/AltosTelemetryMini2.java
altoslib/AltosTelemetryMini3.java
altoslib/AltosTelemetryRaw.java
altoslib/AltosTelemetryReader.java
altoslib/AltosTelemetrySatellite.java
altoslib/AltosTelemetrySensor.java
altoslib/AltosTelemetryStandard.java
altoslib/AltosTemperature.java
altoslib/AltosTime.java [new file with mode: 0644]
altoslib/AltosTimeSeries.java [new file with mode: 0644]
altoslib/AltosTimeValue.java [new file with mode: 0644]
altoslib/AltosUnits.java
altoslib/AltosUnitsListener.java
altoslib/AltosUnitsRange.java
altoslib/AltosUnknownProduct.java
altoslib/AltosVersion.java.in
altoslib/AltosVoltage.java
altoslib/AltosWriter.java
altoslib/Makefile.am
altosui/Altos.java
altosui/AltosAscent.java
altosui/AltosCompanionInfo.java
altosui/AltosConfig.java
altosui/AltosConfigPyroUI.java
altosui/AltosConfigTD.java
altosui/AltosConfigTDUI.java
altosui/AltosConfigUI.java
altosui/AltosConfigureUI.java
altosui/AltosDescent.java
altosui/AltosFlightStatus.java
altosui/AltosFlightStatusTableModel.java
altosui/AltosFlightStatusUpdate.java
altosui/AltosFlightUI.java
altosui/AltosGraphUI.java
altosui/AltosIdleMonitorUI.java
altosui/AltosIgniteUI.java
altosui/AltosIgnitor.java
altosui/AltosLanded.java
altosui/AltosLaunch.java
altosui/AltosLaunchUI.java
altosui/AltosPad.java
altosui/AltosUI.java
altosuilib/AltosBTDevice.java
altosuilib/AltosBTDeviceIterator.java
altosuilib/AltosBTKnown.java
altosuilib/AltosBTManage.java
altosuilib/AltosCSVUI.java
altosuilib/AltosConfigFreqUI.java
altosuilib/AltosDataChooser.java
altosuilib/AltosDevice.java
altosuilib/AltosDeviceDialog.java
altosuilib/AltosDeviceUIDialog.java
altosuilib/AltosDisplayThread.java
altosuilib/AltosEepromDelete.java
altosuilib/AltosEepromManage.java
altosuilib/AltosEepromMonitor.java [deleted file]
altosuilib/AltosEepromMonitorUI.java
altosuilib/AltosEepromSelect.java
altosuilib/AltosFlashUI.java
altosuilib/AltosFlightInfoTableModel.java
altosuilib/AltosFlightStatsTable.java
altosuilib/AltosGraph.java
altosuilib/AltosGraphDataPoint.java [deleted file]
altosuilib/AltosGraphDataSet.java [deleted file]
altosuilib/AltosInfoTable.java
altosuilib/AltosLed.java
altosuilib/AltosLights.java
altosuilib/AltosPositionListener.java
altosuilib/AltosRomconfigUI.java
altosuilib/AltosScanUI.java
altosuilib/AltosSerial.java
altosuilib/AltosSerialInUseException.java
altosuilib/AltosUIAxis.java
altosuilib/AltosUIConfigure.java
altosuilib/AltosUIDataMissing.java
altosuilib/AltosUIDataPoint.java
altosuilib/AltosUIDataSet.java
altosuilib/AltosUIDialog.java
altosuilib/AltosUIEnable.java
altosuilib/AltosUIFlightSeries.java [new file with mode: 0644]
altosuilib/AltosUIFlightTab.java
altosuilib/AltosUIFrame.java
altosuilib/AltosUIFreqList.java
altosuilib/AltosUIGraph.java
altosuilib/AltosUIGrapher.java
altosuilib/AltosUIImage.java
altosuilib/AltosUIIndicator.java
altosuilib/AltosUILib.java
altosuilib/AltosUIListener.java
altosuilib/AltosUIMap.java
altosuilib/AltosUIMapPreload.java
altosuilib/AltosUIMarker.java
altosuilib/AltosUIPreferences.java
altosuilib/AltosUIPreferencesBackend.java
altosuilib/AltosUIRateList.java
altosuilib/AltosUISeries.java [deleted file]
altosuilib/AltosUITelemetryList.java
altosuilib/AltosUITimeSeries.java [new file with mode: 0644]
altosuilib/AltosUIUnitsIndicator.java
altosuilib/AltosUIVoltageIndicator.java
altosuilib/AltosUSBDevice.java
altosuilib/AltosVoice.java
altosuilib/GrabNDrag.java
altosuilib/Makefile.am
altosuilib/OSXAdapter.java
ao-bringup/turnon_chaoskey
configure.ac
doc/Makefile
doc/telegps-outline.txt [new file with mode: 0644]
doc/telegps.svg [new file with mode: 0644]
libaltos/Makefile.am
libaltos/btletest.c [new file with mode: 0644]
micropeak/Makefile.am
micropeak/MicroData.java
micropeak/MicroDataPoint.java [deleted file]
micropeak/MicroDeviceDialog.java
micropeak/MicroDownload.java
micropeak/MicroExport.java
micropeak/MicroFile.java
micropeak/MicroFileChooser.java
micropeak/MicroFrame.java
micropeak/MicroGraph.java [deleted file]
micropeak/MicroPeak.java
micropeak/MicroRaw.java
micropeak/MicroSave.java
micropeak/MicroSerial.java
micropeak/MicroSerialLog.java
micropeak/MicroStats.java [deleted file]
micropeak/MicroStatsTable.java [deleted file]
micropeak/MicroUSB.java
src/drivers/ao_hmc5883.c
src/drivers/ao_hmc5883.h
src/drivers/ao_mpu6000.c
src/drivers/ao_ms5607.c
src/drivers/ao_rn4678.c
src/drivers/ao_rn4678.h
src/easymini-v1.0/ao_pins.h
src/easymini-v2.0/ao_pins.h
src/kernel/ao_log.h
src/kernel/ao_log_mega.c
src/kernel/ao_telemetry.c
src/kernel/ao_telemetry.h
src/micropeak-v2.0/ao_pins.h
src/stm/ao_serial_stm.c
src/stmf0/ao_serial_stm.c
src/telebt-v3.0/Makefile
src/telebt-v3.0/ao_telebt.c
src/telebt-v4.0/Makefile
src/telebt-v4.0/ao_pins.h
src/telefireone-v1.0/ao_pins.h
src/test/Makefile
src/test/ao_flight_test.c
telegps/TeleGPS.java
telegps/TeleGPSConfig.java
telegps/TeleGPSConfigUI.java
telegps/TeleGPSDisplayThread.java
telegps/TeleGPSGraphUI.java
telegps/TeleGPSInfo.java
telegps/TeleGPSPreferences.java
telegps/TeleGPSState.java
telegps/TeleGPSStatus.java
telegps/TeleGPSStatusUpdate.java

index 8e65e1d01cd2b724becfba5b670f3637520c3799..359b58321ed11995d805cc5a583aa539fd9d890c 100644 (file)
@@ -31,7 +31,7 @@ import android.bluetooth.BluetoothSocket;
 import android.os.Handler;
 //import android.os.Message;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class AltosBluetooth extends AltosDroidLink {
 
index b8c907739d9095b704641386ce91704662604dbf..5906ff985625f3e50477b8ad512c9ce2aaefe890 100644 (file)
@@ -21,7 +21,7 @@ import java.util.Arrays;
 import java.io.*;
 import java.lang.*;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.graphics.*;
index 30a949d57378cf8607c7a7a2e5a230e9c2dfb7c3..924ab4c9350a4564bdcb532b04e47777ead16bef 100644 (file)
@@ -52,7 +52,30 @@ import android.hardware.usb.*;
 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 {
 
@@ -114,6 +137,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        public Location location = null;
 
+       private AltosState      state;
+       private SavedState      saved_state;
+
        // Tabs
        TabHost         mTabHost;
        AltosViewPager  mViewPager;
@@ -123,7 +149,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        // Timer and Saved flight state for Age calculation
        private Timer timer;
-       AltosState saved_state;
+
        TelemetryState  telemetry_state;
        Integer[]       serials;
 
@@ -307,7 +333,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
                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)
@@ -322,7 +348,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
                        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;
@@ -334,7 +360,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                state = newest_state;
                }
 
-               update_ui(telemetry_state, state);
+               update_ui(telemetry_state, state, telemetry_state.quiet);
 
                start_timer();
        }
@@ -362,8 +388,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        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) {
@@ -375,7 +401,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        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;
 
@@ -399,17 +425,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
        }
 
-       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;
@@ -417,8 +445,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
                                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) {
@@ -456,22 +484,22 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                                                     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 {
@@ -485,15 +513,16 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                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() {
@@ -567,8 +596,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                // 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);
@@ -703,7 +733,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                         location.getLatitude(),
                                         location.getLongitude());
 
-               update_ui(telemetry_state, saved_state);
+               update_ui(telemetry_state, state, true);
        }
 
        @Override
@@ -1094,7 +1124,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                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) {
index 23105635621ca99ab67f2d66786c33472d987dba..05cb0f6b9ea9219a60154a4ddc3c549e4a52e780 100644 (file)
@@ -25,7 +25,7 @@ import java.util.UUID;
 
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public abstract class AltosDroidLink extends AltosLink {
 
index 2b78104d922d25964a0a948450682f7198590e16..8730e8adb3f356787436c378a711b9c427719bf4 100644 (file)
@@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid;
 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);
index c7cdc961729aad7e385633ac539f792e82cd9fb7..0670005a26efded41f5d69b259c01114ca2ceeb0 100644 (file)
@@ -22,7 +22,7 @@ import java.util.*;
 import java.text.*;
 
 import android.content.Context;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class AltosDroidPreferences extends AltosPreferences {
 
index 2e6ccb34e2227277910bbf1237392ff404980287..01ec0af941d5b93d49fdba9092b4b5be3a192c71 100644 (file)
@@ -25,7 +25,7 @@ import android.content.SharedPreferences;
 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";
@@ -77,7 +77,17 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        }
 
        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) {
@@ -103,6 +113,10 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        }
 
        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);
        }
 
index 11d8f6241fc885b1b140696c803a78753e3b4b77..71309897b6751b4bb71878f37e82be88ca759583 100644 (file)
@@ -18,7 +18,7 @@
 
 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;
index 76771adcfce6246ae3b57078be6ff2338f4f5a7e..2a728cf73bf4f2f735eb74f3aeb0d4d0b0760349 100644 (file)
@@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid;
 import java.util.*;
 import java.io.*;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.graphics.*;
@@ -164,6 +164,7 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                                                break;
                                        case AltosMapTile.forbidden:
                                                message = "Too many requests, try later";
+                                               AltosDebug.debug("Forbidden map response %d\n", AltosMapStore.forbidden_response);
                                                break;
                                        }
                                        if (message != null) {
@@ -476,11 +477,11 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                                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) {
index 9e5d6deea091acc9f9a8588956f9140adc28a149..b71cdd62eff6517d6a05786c45b859a079f5b997 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.AltosDroid;
 
 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.*;
index 8d0a725aef5347191e7da8868b89805d4d880c58..77947b4b3e6ed39d2b1670070b5fea4182596a3f 100644 (file)
@@ -29,7 +29,7 @@ import android.hardware.usb.*;
 import android.app.*;
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class AltosUsb extends AltosDroidLink {
 
index 811b03675d63640bb62d258ce46a6a249fa43d9d..fedfdb52ada23851db26f9c24d907256b628f7a2 100644 (file)
@@ -23,7 +23,7 @@ import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.OnInitListener;
 import android.location.Location;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class AltosVoice {
 
@@ -49,6 +49,7 @@ 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();
@@ -80,7 +81,8 @@ public class AltosVoice {
        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() {
@@ -121,6 +123,8 @@ public class AltosVoice {
                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,
@@ -239,12 +243,12 @@ public class AltosVoice {
                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;
                        }
                }
@@ -269,7 +273,7 @@ public class AltosVoice {
                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;
@@ -277,7 +281,9 @@ public class AltosVoice {
 
        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;
 
@@ -288,7 +294,7 @@ public class AltosVoice {
                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();
index 7b3bbb4e9644339c69e334e7da91cf4b024c9566..ace0a7d6465cd953057b681e5271d04d8ab58bf2 100644 (file)
@@ -35,7 +35,7 @@ import android.view.View.OnClickListener;
 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;
index 4b8dc3e8452c8ffa6afce09783ee9fb3b4d70050..eccf5c598a24fefc11495e26aaea7383b6c19f1b 100644 (file)
@@ -33,7 +33,7 @@ import android.view.View.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 class IgniterItem {
        public String name;
index 0eef129e38e20037fce7b656cf3de58995b3d333..ff599fdacec5ab9ee38355980ea6010a02b3ef63 100644 (file)
@@ -33,7 +33,7 @@ import android.view.inputmethod.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 class FrequencyItem {
        public AltosFrequency frequency;
index a0c7233f50b00b34a671f6f4f4752163e1fa05a5..b93eaa1962cb91329392c7ef2180395be57b714b 100644 (file)
@@ -35,7 +35,7 @@ import android.view.View.OnClickListener;
 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;
index a8e87bf265773e64c448af238feef8ff26dfcd40..9c43870f76c9838e55133da661ee0f3ffb896509 100644 (file)
@@ -42,7 +42,7 @@ import android.location.LocationManager;
 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
index 41c3eb8842830c203f48d0acefb9118a5e61dd58..d970fc4f2f3b65de920ac67c551ae4df47556b59 100644 (file)
@@ -31,7 +31,7 @@ import android.view.View.*;
 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;
index 3143679a3690036067a4af16307042b6646bb13e..5349612cc1ec823a602a619dfe07766bc4923b9f 100644 (file)
@@ -18,7 +18,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.os.Bundle;
index 5db5b85fd23e1fa9c3836f62295be050e0ac3a8d..d239d988ad488f36bebb9909e0c06d43aed6bc96 100644 (file)
@@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid;
 import java.util.*;
 import java.io.*;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.graphics.*;
index 492f7f5f4585c61dffb703c5189fd4802423bbd2..ba5afba5c8b1b81323fecc4705d4aa80d4efda66 100644 (file)
@@ -18,7 +18,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.os.Bundle;
@@ -178,10 +178,10 @@ public class TabPad extends AltosDroidTab {
                        }
                        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 {
@@ -191,7 +191,7 @@ public class TabPad extends AltosDroidTab {
                                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)
@@ -201,7 +201,7 @@ public class TabPad extends AltosDroidTab {
                        } 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;
index 97a35c9eb4a044ca9f1903f9394586725c48a409..ac211230446082324a81c241862e2c52ddd4379c 100644 (file)
@@ -18,7 +18,7 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.app.Activity;
 import android.os.Bundle;
index c379d3d84af153f77bd68f32eb5866d62eea4c52..56f235c1a8c4b17a6def2665906bc5faf403b4e8 100644 (file)
@@ -1,6 +1,6 @@
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
index bc0b3615476982bf16303306b89ea6e72137ecb4..d097a550953760958751d33b159161562af7eada 100644 (file)
@@ -26,7 +26,7 @@ import java.util.*;
 import java.util.concurrent.*;
 import android.os.Handler;
 
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 
 public class TelemetryReader extends Thread {
index 34c86ce5b56e31b5d7b5cc46409297811d2353f2..caf288a04b62864270650d3a6330270d78fae39a 100644 (file)
@@ -41,7 +41,7 @@ import android.os.Looper;
 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 {
 
@@ -259,14 +259,15 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
        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();
        }
@@ -615,6 +616,8 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
 
                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) {
@@ -625,7 +628,7 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
 
                                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,
@@ -699,7 +702,7 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
 
        /* 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();
        }
index 32ba12546d66c2ae9cbafbb766945f21299053ca..77cee787b56219fc27b4fab518c057389fa411d6 100644 (file)
@@ -19,7 +19,7 @@
 package org.altusmetrum.AltosDroid;
 
 import java.util.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 import android.location.Location;
 
 public class TelemetryState {
@@ -36,6 +36,8 @@ public class TelemetryState {
        double          frequency;
        int             telemetry_rate;
 
+       boolean         quiet;
+
        HashMap<Integer,AltosState>     states;
 
        int             latest_serial;
index 31aa7c1b9e9b2c940e4853bd8b1a9824689247a8..8fefefc5f0bf0be3166782bcec85a472f9f0e732 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 80dca140da3fa282b5a4322f1733640a4c685129..5c398d3cfb3bb42fd332f16b4807ef6bcc098feb 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index b51994563aec8b145a3b13ffd222dce9a692b245..f55b47852a47a895e8fa829346a9594b5a17a6a9 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -27,16 +27,17 @@ public class AltosCSV implements AltosWriter {
        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;
 
@@ -117,71 +118,116 @@ public class AltosCSV implements AltosWriter {
                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,
@@ -196,9 +242,9 @@ public class AltosCSV implements AltosWriter {
                           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);
@@ -212,8 +258,8 @@ public class AltosCSV implements AltosWriter {
                }
        }
 
-       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) {
@@ -230,12 +276,15 @@ public class AltosCSV implements AltosWriter {
        }
 
        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;
@@ -252,6 +301,7 @@ public class AltosCSV implements AltosWriter {
                }
                for (; channels_written < 12; channels_written++)
                        out.printf(",0");
+*/
        }
 
        void write_header() {
@@ -287,63 +337,47 @@ public class AltosCSV implements AltosWriter {
                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() {
@@ -351,15 +385,15 @@ public class AltosCSV implements AltosWriter {
        }
 
        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;
@@ -368,31 +402,37 @@ public class AltosCSV implements AltosWriter {
                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 {
diff --git a/altoslib/AltosCalData.java b/altoslib/AltosCalData.java
new file mode 100644 (file)
index 0000000..b49e379
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * 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);
+       }
+}
index 2c03c922ed5851865d72ce957ec736ccdf14aec6..5ce333f8a9782564e3c804a56addf31a6cf7292d 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 23ab1e113cd0264ac6b883f1761740a56a8023c3..97a80bcbadb20166cb2774491c7c291f304300be 100644 (file)
  * 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;
@@ -33,9 +33,7 @@ public class AltosConfigData implements Iterable<String> {
        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*/
@@ -96,14 +94,13 @@ public class AltosConfigData implements Iterable<String> {
        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)) {
@@ -142,21 +139,17 @@ public class AltosConfigData implements Iterable<String> {
                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;
@@ -214,6 +207,10 @@ public class AltosConfigData implements Iterable<String> {
                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);
@@ -233,8 +230,6 @@ public class AltosConfigData implements Iterable<String> {
        }
 
        public void reset() {
-               __lines = new LinkedList<String>();
-
                manufacturer = null;
                product = null;
                serial = AltosLib.MISSING;
@@ -242,6 +237,8 @@ public class AltosConfigData implements Iterable<String> {
                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;
@@ -265,8 +262,8 @@ public class AltosConfigData implements Iterable<String> {
 
                aes_key = null;
 
-               pyro = 0;
-               npyro = 0;
+               pyro = AltosLib.MISSING;
+               npyro = AltosLib.MISSING;
                pyros = null;
                pyro_firing_time = AltosLib.MISSING;
 
@@ -289,7 +286,7 @@ public class AltosConfigData implements Iterable<String> {
        }
 
        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) {}
@@ -302,17 +299,31 @@ public class AltosConfigData implements Iterable<String> {
 
                /* 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) {}
@@ -361,7 +372,7 @@ public class AltosConfigData implements Iterable<String> {
                        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)
@@ -425,24 +436,23 @@ public class AltosConfigData implements Iterable<String> {
        }
 
        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);
                }
@@ -452,12 +462,12 @@ public class AltosConfigData implements Iterable<String> {
                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,
@@ -492,56 +502,56 @@ public class AltosConfigData implements Iterable<String> {
        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();
        }
 
@@ -561,7 +571,7 @@ public class AltosConfigData implements Iterable<String> {
                if (log_space() == 0)
                        max_enabled = false;
 
-               if (log_fixed > 0)
+               if (log_fixed != AltosLib.MISSING)
                        max_enabled = false;
 
                switch (log_format) {
@@ -569,7 +579,7 @@ public class AltosConfigData implements Iterable<String> {
                        max_enabled = false;
                        break;
                default:
-                       if (stored_flight > 0)
+                       if (stored_flight != AltosLib.MISSING)
                                max_enabled = false;
                        break;
                }
@@ -581,7 +591,7 @@ public class AltosConfigData implements Iterable<String> {
                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);
@@ -605,17 +615,17 @@ public class AltosConfigData implements Iterable<String> {
        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,
@@ -631,7 +641,7 @@ public class AltosConfigData implements Iterable<String> {
                        }
                }
 
-               if (telemetry_rate >= 0) {
+               if (telemetry_rate != AltosLib.MISSING) {
                        link.printf("c T %d\n", telemetry_rate);
                        if (remote) {
                                link.flush_output();
@@ -653,12 +663,12 @@ public class AltosConfigData implements Iterable<String> {
                        }
                }
 
-               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 */
@@ -666,36 +676,36 @@ public class AltosConfigData implements Iterable<String> {
                        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 */
index 59a8e9c180851a8caea6c7adff9fd5ee8a1ab529..fe6336b6baba6aa7ceb2d4a909a66b672b42afae 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index bc20d21ddfee0fa9837d62ebf833021ad290d696..170b1112ea096048d06d61a893ad16444825973f 100644 (file)
@@ -16,7 +16,7 @@
  * 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 */
index 3489a609fc9eac2156b9c586ee23af0660a09512..ed16541a7d832a5a5424340470f8b053145f22bb 100644 (file)
 /*
  * 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
         *
@@ -44,20 +47,20 @@ public class AltosConvert {
         *   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
        };
 
@@ -181,6 +184,18 @@ public class AltosConvert {
                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)
        {
@@ -188,7 +203,7 @@ public class AltosConvert {
        }
 
        public static double
-       cc_ignitor_to_voltage(double ignite)
+       cc_igniter_to_voltage(double ignite)
        {
                return ignite / 32767 * 15.0;
        }
@@ -255,7 +270,15 @@ public class AltosConvert {
                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;
 
@@ -269,7 +292,13 @@ public class AltosConvert {
                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) {
@@ -307,6 +336,10 @@ public class AltosConvert {
                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];
@@ -384,6 +417,26 @@ public class AltosConvert {
                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();
@@ -408,6 +461,14 @@ public class AltosConvert {
 
        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");
diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java
new file mode 100644 (file)
index 0000000..5f89b3e
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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;
+       }
+}
diff --git a/altoslib/AltosDataProvider.java b/altoslib/AltosDataProvider.java
new file mode 100644 (file)
index 0000000..9589a8e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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;
+}
index aa1b298fca9209233e4a935a704aeffb153ff7f1..24a2593303c0f4bc16bbee37debaf73527208d83 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 0239c5cec2670c5b0476aa2e6e28f57f863c06e5..38efbf1abf004b06c9612312898e8687bf871cf9 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
@@ -96,7 +96,7 @@ 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);
index 6ed14d3abe576773100660fc29e0e67e72fd6742..ad7bf88104e8cb9ff106e02500b2737b8aa631a1 100644 (file)
 /*
- * 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() {
        }
 }
index 1deb0deda07b9e311d366b11abb85dc605f04a98..4f12c190f61936af2d9bd58e0fcac1c3364b900c 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 74912ed4bac7218b8d9a2462360e4e8c1acc32dc..33f0dd177997104e1bd1f8e8eabf0e2d8aff1fd2 100644 (file)
  * 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;
@@ -45,11 +92,11 @@ public class AltosEepromDownload implements Runnable {
                        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
@@ -134,24 +181,23 @@ public class AltosEepromDownload implements Runnable {
                }
 
                /* 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());
 
index 4606e78091946b84911fd0d0be7777c5b2800986..067f030218a3dd5ea140ff5b105e544f5d8ca4a3 100644 (file)
  * 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) {
        }
 
@@ -37,11 +33,19 @@ public class AltosEepromFile extends AltosStateIterable {
                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);
        }
 }
index fc72fd95a88c9d9c25e5313d0cb1ccdab99630e6..55d47e20d345d217631e5490776dbd3496f24780 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 63e4a1f8a238dd81b6efca8ef5fbebe5cd1c471b..8d1f3fc4e8cb603bd56bbda09aeebde9b38acf4e 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 250568ac659c882d3d3010cc70b7206291cc4a3f..a99ec687b2b7efbb24c5db250ec1db12ee5f90f4 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 public interface AltosEepromMonitor {
 
diff --git a/altoslib/AltosEepromNew.java b/altoslib/AltosEepromNew.java
deleted file mode 100644 (file)
index 4e3ee41..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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() {
-       }
-}
index c0edb9526bf235a80a2c7b557054aa97e5f29f77..094584fecf8176668b1f239daca1a1520d8ff3b2 100644 (file)
  * 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;
 
@@ -65,30 +64,44 @@ public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord>
                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;
@@ -102,7 +115,7 @@ public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord>
 
        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;
index 8c03cd5657e9eec3fd0da949c20f163c0640a216..d6b74d1b2c9946a11abcf8b919ff15694b81ba4e 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -68,21 +68,19 @@ public class AltosEepromRecordFireTwo extends AltosEepromRecord {
                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;
                }
        }
@@ -94,11 +92,11 @@ public class AltosEepromRecordFireTwo extends AltosEepromRecord {
                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);
        }
 }
index fbb8fbd9e7ff14cd528f27f564f5a6c0d8964797..85709f734de157ac9ff23b9f753c62651b4d131b 100644 (file)
@@ -12,7 +12,7 @@
  * 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;
@@ -21,53 +21,39 @@ public class AltosEepromRecordFull extends AltosEepromRecord {
 
        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);
@@ -81,29 +67,29 @@ public class AltosEepromRecordFull extends AltosEepromRecord {
                                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);
@@ -118,11 +104,11 @@ public class AltosEepromRecordFull extends AltosEepromRecord {
                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);
        }
 }
index 1312d3ecbd18fa6774f027cdae71528bfb11eae7..5cf5db3966c86faecfda5f996bc5d4246755936f 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -71,36 +71,19 @@ public class AltosEepromRecordGps extends AltosEepromRecord {
                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)
@@ -140,6 +123,7 @@ public class AltosEepromRecordGps extends AltosEepromRecord {
                                if (gps.vdop < 0.8)
                                        gps.vdop += 2.56;
                        }
+                       listener.set_gps(gps);
                        break;
                }
        }
@@ -151,11 +135,11 @@ public class AltosEepromRecordGps extends AltosEepromRecord {
                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);
        }
 }
index 1c6d1aee90a39747f976d3c73ca60da7e47b93d2..ad3e23fdfeeefcbc258354f5941dd6d5c35013b9 100644 (file)
@@ -12,7 +12,7 @@
  * 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;
@@ -73,8 +73,8 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
        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 */
@@ -109,84 +109,90 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
        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();
@@ -208,7 +214,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                        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;
@@ -225,7 +231,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                        }
                        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)
@@ -243,12 +249,12 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                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);
        }
 }
index c11b6aacf7e49a5084e0ff5f53f365111efee3e8..3da50544b2a56db660c619faf16cde1156e1c728 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
@@ -65,59 +65,42 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord {
        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();
@@ -136,7 +119,7 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord {
                        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++)
@@ -152,11 +135,11 @@ public class AltosEepromRecordMetrum extends AltosEepromRecord {
                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);
        }
 }
index f0fc61ad236147b9ece79f60a95dacac9b2b4ce5..5569669344f51ca3a8bc609b7aeaa91e60f6fe62 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
@@ -42,8 +42,10 @@ public class AltosEepromRecordMini extends AltosEepromRecord {
 
        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)
@@ -53,8 +55,10 @@ public class AltosEepromRecordMini extends AltosEepromRecord {
 
        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)
@@ -62,22 +66,24 @@ public class AltosEepromRecordMini extends AltosEepromRecord {
                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;
                }
        }
@@ -89,11 +95,11 @@ public class AltosEepromRecordMini extends AltosEepromRecord {
                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);
        }
 }
index 911b90b9f9f471f5c26167eeb8ad93a7cc347629..48e90c055e0269be6136385ac50935e411d4505e 100644 (file)
  * 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();
@@ -77,7 +75,8 @@ public class AltosEepromRecordSet implements Iterable<AltosState> {
                        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:
@@ -96,9 +95,6 @@ public class AltosEepromRecordSet implements Iterable<AltosState> {
                int     tick = 0;
                boolean first = true;
 
-               start_state = new AltosState();
-               start_state.set_config_data(record.eeprom.config_data());
-
                for (;;) {
                        int     t = record.tick();
 
@@ -118,7 +114,7 @@ public class AltosEepromRecordSet implements Iterable<AltosState> {
                }
        }
 
-       public AltosEepromRecordSet(Reader input) throws IOException {
-               this(new AltosEepromNew(input));
+       public AltosEepromRecordSet(InputStream input) throws IOException {
+               this(new AltosEeprom(input));
        }
 }
index fda6ddff8db063848dd54dc13980988b7b0217a5..06ee9d54508575d142dc66c8e3a07fb3a6e3c4ed 100644 (file)
@@ -12,9 +12,9 @@
  * 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() {
@@ -50,21 +50,21 @@ public class AltosEepromRecordTiny extends AltosEepromRecord {
                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;
                }
        }
@@ -76,11 +76,11 @@ public class AltosEepromRecordTiny extends AltosEepromRecord {
                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);
        }
 }
index ef75762a5a7c8dd0ccf4c8b4a95dff4805ba0b22..69f779c1d46f50e87e16c3617f17071109036ed7 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -66,7 +66,7 @@ public class AltosFile extends File {
                     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");
        }
 }
index ad5733051e00059cac753e02f3a64fc5adf4eeb2..c8db1f778ab32ff2421f68d7fbac0de9cf208705 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index e15d7ac3e4a72c72ee5d17e784499017d0a70856..60052133a09ceb999ff3122a4738aa8af9e16014 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index c395dc4584b573eccc2a2f2308e4188f91c0c255..8fe33c5e037b3f1c1a9a442a562ccbde41b88aec 100644 (file)
@@ -16,7 +16,7 @@
  * 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();
diff --git a/altoslib/AltosFlightListener.java b/altoslib/AltosFlightListener.java
new file mode 100644 (file)
index 0000000..d61831a
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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;
+       }
+}
index 250e2236b7a555a5fb2173f0bc6c925ae563e9bf..671bf63834bfaa5bd155a47ab33c785f8daf5eeb 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -31,6 +31,8 @@ public abstract class AltosFlightReader {
 
        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 { }
@@ -45,8 +47,6 @@ public abstract class AltosFlightReader {
 
        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; }
diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java
new file mode 100644 (file)
index 0000000..57f1a49
--- /dev/null
@@ -0,0 +1,697 @@
+/*
+ * 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);
+       }
+}
index 98f13dac50965e6fc43b5be336b1bb949b70b84a..6f8732cf5c25af479793e670fb256b6dc3312cfe 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
@@ -25,15 +25,17 @@ public class AltosFlightStats {
        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;
@@ -46,65 +48,133 @@ public class AltosFlightStats {
        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;
@@ -120,96 +190,75 @@ public class AltosFlightStats {
                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;
                }
        }
 }
index c7f339a02b09eb9fb744d99e57a031925c209868..97947d0b48f4fa501b03d2206f5462edfc1e3282 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 229d04f38dd2baa3a4b4ee903b0c808247ac7c8d..47fb900cd080b3b56e4abfd5977dee5f4d345b47 100644 (file)
@@ -15,7 +15,7 @@
  * 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 {
 
index 3b2a445a084e1560cc4477f7623d4216baa26468..6838be8aec47f01cd6ce7db62128025a93a9a2ab 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 0b30ed456593f75587ca57b2ff6a7954810f82db..b6ca3576b4096e061d2d59090c0ae9a93e544db2 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -383,17 +383,13 @@ public class AltosGPS implements Cloneable {
                }
        }
 
-       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 {
index e2f0f38038ab286216f172925b96540a840a9a6c..8d3b316af45d3dfc4cecf50c925ac7712d125c89 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
diff --git a/altoslib/AltosGPSTimeValue.java b/altoslib/AltosGPSTimeValue.java
new file mode 100644 (file)
index 0000000..e15c60e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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;
+       }
+}
index 6e5bd362372f4c633b423594b94cb37e296bb420..f1cb1940f1f9010ef799f8cdfa1d606aeb7969d6 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 0cd495fb19a38e5c03d2f00087a9c60750ee0925..668080f1216158a73909c10b85e0c224741c4f3a 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index e746b6494a422d7860399831524dee59d8b6a0e8..7ab121ad7a7e2f9b9a287a29ccc654930c70a51a 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 2eb08f75ab1d821cb7300c6111fcf1e8312be4b8..4f56af9a37630096f4210cc3c45077707c23a624 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index f6cadf1d13a0f4276a15156e9f99dc9535c7cfa4..dee28a92319eb8532d5d2556180ae51fa827509d 100644 (file)
  * 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) {
@@ -49,12 +51,12 @@ public class AltosIMU implements Cloneable {
                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;
        }
@@ -62,46 +64,41 @@ public class AltosIMU implements Cloneable {
        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 {
index d37af9664b166eac8fc964a9bd5226ae738fe3ef..b5ee20d00910eb756ea56c18c1b282d1eef32df0 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 73717e178c38569fbe2e426cae50f04ce809fccf..058df0a1a246db3455e4f4877b05df0f8ff241fa 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -30,61 +30,62 @@ class AltosIdler {
        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);
                }
        }
 
@@ -99,13 +100,17 @@ class AltosIdler {
 }
 
 
-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),
@@ -124,16 +129,19 @@ public class AltosIdleFetch implements AltosStateUpdate {
 
                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",
@@ -143,29 +151,22 @@ public class AltosIdleFetch implements AltosStateUpdate {
 
        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) {
                }
 
index c374b6015d5563350844c035136949eaa78facef..fc5d4cc889ef51bbe52227bb93d53b2409a9723e 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -52,20 +52,20 @@ public class AltosIdleMonitor extends Thread {
                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();
                        }
                }
@@ -92,12 +92,14 @@ public class AltosIdleMonitor extends Thread {
        }
 
        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) {
index 3349e9c4a98e3102374a8879a8f979d3de14b2da..1ddec09a13240feb0c26d57c036f92594574ddb4 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 5903c96815f03feb12adbbb1667085a8bb2eed38..d15e217487f482815e29281a8fece2c3016e7b98 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -25,6 +25,7 @@ import java.util.concurrent.*;
 public class AltosIdleReader extends AltosFlightReader {
        AltosLink       link;
        boolean         remote;
+       AltosCalData    cal_data = null;
        AltosState      state = null;
        AltosIdleFetch  fetch;
        long            next_millis;
@@ -44,15 +45,23 @@ public class AltosIdleReader extends AltosFlightReader {
                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)
@@ -61,7 +70,9 @@ public class AltosIdleReader extends AltosFlightReader {
                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) {
index cdc5c614c08d425cd15c72ee74dd2d0826521de4..767c00fbaf1689d4f8c5399518656c6594496995 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -102,7 +102,7 @@ public class AltosIgnite {
        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;
@@ -174,6 +174,7 @@ public class AltosIgnite {
                try {
                        start_link();
                        link.printf("i DoIt %s\n", igniter);
+                       link.flush_output();
                } catch (TimeoutException te) {
                } finally {
                        stop_link();
index 2e32b7200872063b7343ac7f33ce76c17b6e8d0f..abe9d56f9c0fe052b4b533467080bf211703d574 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 9191be68004d6297d4fea25ae61747669478816c..52c9b41e6d7d81f8dcd5d804eacad421568d3098 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -255,7 +255,7 @@ class JsonToken {
  * Lexer for json
  */
 class JsonLexer extends JsonUtil {
-       Reader                  f;
+       InputStream             f;
        int                     line;
        int                     ungot = -2;
        StringBuffer            pending_token;
@@ -445,12 +445,12 @@ class JsonLexer extends JsonUtil {
        }
 
        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;
@@ -570,7 +570,7 @@ class JsonParse {
                lexer = new JsonLexer(s);
        }
 
-       JsonParse(Reader f) {
+       JsonParse(InputStream f) {
                lexer = new JsonLexer(f);
        }
 }
@@ -670,7 +670,7 @@ public class AltosJson extends JsonUtil {
                }
        }
 
-       public static AltosJson fromReader(Reader f) {
+       public static AltosJson fromInputStream(InputStream f) {
                JsonParse       parse = new JsonParse(f);
                try {
                        return parse.parse();
index 25108bf97c67ad27660f8d1e3915b561c1724b8e..1c025ef41cc09b5049181f61dfbcd6e56259d83d 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -36,8 +36,9 @@ public class AltosKML implements AltosWriter {
        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
@@ -101,42 +102,47 @@ public class AltosKML implements AltosWriter {
                "</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() {
@@ -145,7 +151,7 @@ public class AltosKML implements AltosWriter {
 
        public void close() {
                if (prev != null) {
-                       state_end(prev);
+                       state_end();
                        end();
                        prev = null;
                }
@@ -155,40 +161,37 @@ public class AltosKML implements AltosWriter {
                }
        }
 
-       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 {
index 5865d3ccf32730bb9ae8a97c06918195f63232f2..6fcc43feabd591513a466c260be4a9fe040c7f44 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 4663cd0943fb5c371652836accd7a78f29e0155d..f43397d0f086f225fe369cbdb622bd9ebb707af5 100644 (file)
@@ -16,7 +16,7 @@
  * 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"; }
index 8a06cdb205d815b3603df86b5f38cddc737de6b9..19fb48589e26b367ab6019bb9385e6a9b4a046d0 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index d2ee601ee36c7318d1dd52abda8165c7c19bd228..0d9263530ae48ef8d71293b81ecbd9f243cd4765 100644 (file)
@@ -15,7 +15,7 @@
  * 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.*;
index d5c41c82d7f930e9d3399969d58cde3330b55c82..365f19e325e4825932633a50d08bb3a59c4c3b3f 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index a3f164d48827ecee6d5278c86863d063582edf07..d1063509b2d4e1efda7ebfce2a1eca76032d6200 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -38,6 +38,20 @@ public class AltosLib {
        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;
@@ -162,6 +176,16 @@ public class AltosLib {
                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";
 
@@ -330,7 +354,7 @@ public class AltosLib {
        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;
@@ -338,6 +362,7 @@ public class AltosLib {
        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) {
@@ -561,7 +586,31 @@ public class AltosLib {
                }
        }
 
-       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));
+                       }
+               }
+       }
+
 }
index 952a21e3e6bb35eaa6d60f4a5df45a3947f7ef02..b3833f6402327e233cb4872ffc8c5432f79357a3 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index d75c9aa0c6e8f8d9a924e23842634f87cf0b0cb5..5a802ef180230bdfb969d01212a0197781bb366d 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 80bc0df2708794f5db62dbb238675be004d95069..949d2271ce52914ec6d3805600fc81b886c63cc0 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index c612caaa10c530a65fa45ad27af72882a48e160f..45831004aa22ea708a6ce384a299007ba50dde08 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index 6d873d7811576171aa29b63b4daf725c2c4f956b..44bea6465859e7ff2a91e8c3c65bd173fdafc508 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -61,8 +61,8 @@ public class AltosLog implements Runnable {
                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) {
@@ -80,24 +80,31 @@ public class AltosLog implements Runnable {
 
        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) {
index 4c6d185738838e354e095a3453bd1ef730806289..b2134cbb3b3b3f87eeec0ccbfe782145bac9a862 100644 (file)
@@ -16,7 +16,7 @@
  * 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"; }
index e89ec0debf5742abff50960451dd0006b02b3493..0d8ec69fec6ecf85bd448d988b4de25577169673 100644 (file)
  * 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;
 
@@ -33,10 +33,6 @@ public class AltosMag implements Cloneable {
        }
 
        public boolean parse_string(String line) {
-//             if (line.startsWith("Syntax error")) {
-//                     along = across = through = 0;
-//                     return true;
-//             }
 
                if (!line.startsWith("X:"))
                        return false;
@@ -44,9 +40,9 @@ public class AltosMag implements Cloneable {
                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;
        }
@@ -54,30 +50,27 @@ public class AltosMag implements Cloneable {
        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) {
                }
        }
index e3c4a6a79ec54db6223c62fd4690899a74855d14..286cf1bb696de34e2992728af6e0328810ecf45a 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -220,11 +220,11 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                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;
@@ -232,23 +232,23 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                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);
@@ -259,6 +259,10 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                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();
@@ -268,10 +272,14 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                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) {
index 4e529177984a77c4787be9a1e149108cf4cfa344..54d2dbddbc927c1d5576d19004245871147a8ef2 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 057d1c43ceca03ac077716881fbabd65d344cca2..8c07e3c1dd056501b52b898b5ee397fd520bca9c 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index a2ea81dbc2eb9ae19dc6deafd9f460ff83543080..5089db646c6d70081ad3f638804e798bdd50fc2c 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index c475f52d1cbd561c963c38930d6d67a685578ba4..f2174935f84a632c81d3fc2bc0b8ebb5ba09200a 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
@@ -44,39 +44,9 @@ public abstract class AltosMapLine {
        }
 
        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);
        }
 }
index 17e88bf414757411222f4021dde18336421f246f..b57591df175da770eb8feb98344530f5050132cc 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 07624f80fb331c3e700d8e2b60f8ed03fbe8da6f..7f36c0028f83c0f1b8a45b2dcbbc5f7c2aea623f 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index cbe7bebe46b4f5328cfcc67fa603a86f04502148..4ef179ef538b71a833e96c95bfca65911d071704 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index c2335169383393430acf907e39e65d37f5172930..1542a4e9bea71ed0afdcd84260b2a8e81294f191 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 5182ecfd6b21da1233bd337049a29c5212932ced..409a6a5cf65b635b1b356fbb11ff309bb602cb7a 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index a2321e19456e8e59e1a4236199da8d94de5a0b29..0751aa336d9c77f31cdd9b4c95cc42381783d200 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 7cce05a594c7eccb8008aaaca85c68357d97f76b..4eba3a044296987c5f1ebaa3b0a3cff548a8e3de 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -91,6 +91,7 @@ public class AltosMapStore {
        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;
@@ -116,6 +117,7 @@ public class AltosMapStore {
                                        synchronized (forbidden_lock) {
                                                forbidden_time = System.nanoTime();
                                                forbidden_set = true;
+                                               forbidden_response = response;
                                                return AltosMapTile.forbidden;
                                        }
                                }
index e393520102bd0c450020960c9ef0f661a4f6a38f..1fb7194a932ecf632263c2dcd71f5fda18a0be68 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 4d6dc8d124d7933c95118cc1ae881c8154c06323..4b01e437b898c3c8dfb46445bf99c61ebd9202e7 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 219dcd07e4aacee219245cbf32d82f1e013c0d31..3c6275a076451fd1afa2633bb720283c9a26cfae 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 266557b60b94ad96aaa43fe67529ac6f2b4a40e5..b6d4f4356af8166b4dd3322092aaa2ce9682dd39 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 1d5e2b47b91bb4d65ae51049589c27e6df0af814..94401a0031045496e7bae9bdc5e5a701e24206bf 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 93c26cbbabdf288875b99f097b288b276c103a7c..c4a0acd64175e625db023ea8292606d47c290713 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 503eb5fd0808e597424ac2df60769d060f4866af..0f6022ac4d89c34ac077e9eb8a477bb6caeb6e0f 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.util.concurrent.*;
 
@@ -46,17 +46,18 @@ public class AltosMma655x implements Cloneable {
                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) {
index c598d01e4a6021c5b8d15e8ddf3565c37fa3735f..5b3ba65d2040a1df3331312e899e09c8042e6266 100644 (file)
  * 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);
 
@@ -75,111 +83,75 @@ public class AltosMs5607 {
                        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();
        }
 }
index 37542cf08208aee688dcfbf6ea10722474665967..8372d39675303b6367786902e006dd5e01ba8b11 100644 (file)
@@ -16,7 +16,7 @@
  * 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) {
index 8b3a35414ce0baa2dc2f8e45acf72f46cf28232b..4546a798cde8d30d8e653d0c4f7ad212bdebfcc4 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index b4b6f87547955c22dac9af0c2cc7577c631363eb..77cf969df33fa357390bc7c011ac0d8806f6d556 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 31b03b1fe7c132b2f9fbd8a55e2ab1cd62af15ef..301d07b058004567df2ea4e08b129d2b02ad076c 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 233a8d316489740dcc99b50113c937de62e44c3b..25f5dd2a9693df3bc9177d7ccf639ac590902656 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 35d44631ed22918acab2f4c5bada4959e36c33dc..0c388f1b813cee13133006b4e26fe4534500d122 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -363,11 +363,11 @@ public class AltosPreferences {
                }
        }
 
-       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();
                }
        }
index 327b534c05fa0155cf4099a805d2bb9023f74ea1..00fd2c6d75d7a7e4f2d093083eb8331e8a405381 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
diff --git a/altoslib/AltosPresTemp.java b/altoslib/AltosPresTemp.java
new file mode 100644 (file)
index 0000000..4cd382c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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;
+       }
+}
index 2de2682059424ae421b6d10a078b9278601fe8cf..507a4ceeb7d152d44bb542e1e4386f9bb1c5d687 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index ba04107bff7fd01b439173bd4817bcb1194c28a0..0a828a32917535c8a913037483a9af99a08d7765 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 80884b9f01888005b67ce87be48c5b63ac6d3483..0ea3bfc13ccacdf950b204b452e98ef84d5f248c 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
diff --git a/altoslib/AltosPyroName.java b/altoslib/AltosPyroName.java
new file mode 100644 (file)
index 0000000..0152e47
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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; }
+}
index 40786e3293d586838af319d8849ac265df1e65cf..6d6bc12c1cf434c01357d4ea3e011addb998c1af 100644 (file)
  * 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,
@@ -31,35 +32,36 @@ public class AltosQuaternion {
        }
 
        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 +
@@ -67,10 +69,14 @@ public class AltosQuaternion {
                        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
@@ -145,7 +151,13 @@ public class AltosQuaternion {
                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);;
diff --git a/altoslib/AltosRecordSet.java b/altoslib/AltosRecordSet.java
new file mode 100644 (file)
index 0000000..91cce62
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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);
+}
index 50b3caa6141a8b82049b36be6c769e715eb87bd4..810388ed458283f909a9286300edfebd498651e7 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 59ade8719c8e33f4d133ddf04f4aaabc19aa95b6..24b425b78a2bc797f93cf77bdd6b405d1d318f58 100644 (file)
  * 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);
        }
 }
index dcfbda32dd139a16ead731a8098a5dcf84c98581..46ee2b6e66bc225ce8deddd488d5a3eb34a4852b 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 1235d86b90e57a1c0da9d3923b2c16db0cd09d0f..eec8c5296fd8956ba4f89f35b382c8bdc832cd2f 100644 (file)
  * 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;
 
@@ -28,8 +50,11 @@ public class AltosRotation extends AltosQuaternion {
                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();
        }
 
diff --git a/altoslib/AltosRotationRate.java b/altoslib/AltosRotationRate.java
new file mode 100644 (file)
index 0000000..492f121
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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;
+       }
+}
index 76d12faf0932f7f39a2263ae4a5235ed7a9ba194..6687686468b283e62c805197a25f249f075b6335 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index ae7cd69a95e37f73993ca0f7c485f09175f08287..537821729fc9a03adb4885d4d38337f2cede870b 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 
index 2581685f93b85b8a7073f93361ec720538d22e3a..1bdbb60c4a33624ed2a6c95e2c36f33a181f5eac 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -26,15 +26,25 @@ public class AltosSensorEMini {
        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) {
                }
index d79c08056688d63e560d8da3a51793b443ac9f8e..00873afe5fd343ab86ee8a6cfaa5b1cff4cc0c17 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
index 63c7a0ce960ddf0ef25e7487af3acb8b4d569f46..e58b03a1342e329be3741d93fb5049328ee511ff 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -89,18 +89,18 @@ class AltosSensorMega {
                }
        }
 
-       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) {
                }
index cb1639113b3879baa85cfdc28fd1a26ec97450a2..e01d57cc6bacaf9085f9c55d5fc59a6ed6cf38be 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -53,12 +53,12 @@ class AltosSensorMetrum {
                }
        }
 
-       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) {
                }
        }
index 9c2bcb10ca7f11b464bd0d759b578f505361f597..14514413de9aceadb57ef6aa0b05251e6a331996 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -24,13 +24,13 @@ public class AltosSensorTGPS {
        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) {
                }
index 5d1b1b7f6c50f24ca023dbbbe83c9516d46e12bb..bdedaa9c88b1218cb64e8a1a91dfbbd0c1163145 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -29,18 +29,19 @@ public class AltosSensorTM {
        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) {
                }
index 7e00abd017222360f641a457a28569414116137a..9b5a18545070e7e331886a8e62f33af712aaa179 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -26,15 +26,15 @@ public class AltosSensorTMini2 {
        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) {
                }
index 19d514d7cc8a029cac3bc13d63b733b03c84795d..b92def03475357ca1b563615501f292ae6392004 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
@@ -26,15 +26,15 @@ public class AltosSensorTMini3 {
        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) {
                }
index 465c190c43883770b1dc2cdb466e65c6f6c901d8..2a8ccedcd47a89523ad844bbfc975c5464102da1 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index 8c3f93f0c0e9481930dcbf195be0a2e02c118c74..9ee3d57ddf814fe340ef53df61fa2e31758d5cae 100644 (file)
  * 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;
@@ -40,12 +38,8 @@ public class AltosState implements Cloneable {
 
        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;
@@ -290,22 +284,9 @@ public class AltosState implements Cloneable {
                }
        }
 
-       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)
@@ -448,6 +429,11 @@ public class AltosState implements Cloneable {
        }
 
        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);
        }
 
@@ -515,6 +501,9 @@ public class AltosState implements Cloneable {
                pressure.set(p, time);
        }
 
+       public void set_thrust(double N) {
+       }
+
        public double baro_height() {
                double a = altitude();
                double g = ground_altitude();
@@ -667,6 +656,11 @@ public class AltosState implements Cloneable {
        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);
@@ -678,16 +672,10 @@ public class AltosState implements Cloneable {
        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;
 
@@ -699,6 +687,7 @@ public class AltosState implements Cloneable {
 
        public AltosGreatCircle from_pad;
        public double   elevation;      /* from pad */
+       public double   distance;       /* distance along ground */
        public double   range;          /* total distance */
 
        public double   gps_height;
@@ -708,20 +697,7 @@ public class AltosState implements Cloneable {
        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;
 
@@ -740,23 +716,11 @@ public class AltosState implements Cloneable {
 
                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();
@@ -771,43 +735,40 @@ public class AltosState implements Cloneable {
                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;
 
@@ -825,32 +786,14 @@ public class AltosState implements Cloneable {
                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();
@@ -863,156 +806,12 @@ public class AltosState implements Cloneable {
                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)
@@ -1054,36 +853,15 @@ public class AltosState implements Cloneable {
                                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;
@@ -1097,96 +875,8 @@ public class AltosState implements Cloneable {
                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() {
@@ -1206,42 +896,24 @@ public class AltosState implements Cloneable {
                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);
                }
        }
@@ -1253,197 +925,95 @@ public class AltosState implements Cloneable {
                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) {
@@ -1481,95 +1051,21 @@ public class AltosState implements Cloneable {
                }
        }
 
-       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();
        }
 }
diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java
deleted file mode 100644 (file)
index ec3d944..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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;
-               }
-       }
-}
diff --git a/altoslib/AltosStateName.java b/altoslib/AltosStateName.java
new file mode 100644 (file)
index 0000000..5ba21f2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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; }
+}
diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java
deleted file mode 100644 (file)
index e9698cb..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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;
-}
diff --git a/altoslib/AltosStringInputStream.java b/altoslib/AltosStringInputStream.java
new file mode 100644 (file)
index 0000000..48fff3e
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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;
+       }
+}
index f830bf3582a0a452f24facbda8671e45019d642b..7d576942c22f6348cd2b804c9855d751f1745f69 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.text.*;
 
@@ -24,13 +24,16 @@ 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;
@@ -43,13 +46,13 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
                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);
@@ -88,12 +91,6 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
                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:
@@ -108,35 +105,18 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
                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 {
@@ -149,7 +129,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
                        throw new AltosCRCException(AltosParse.parse_int(word[i++]));
                }
 
-               AltosTelemetry telem;
+               AltosTelemetry telem = null;
 
                if (word[i].equals("TELEM")) {
                        telem = parse_hex(word[i+1]);
index a97fda2d0cbb5135601cafddba6aafe431cb21c7..c6dfe3eb90a54d2a1579bc7610a12d75260d1439 100644 (file)
  * 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);
 
@@ -45,11 +40,17 @@ public class AltosTelemetryCompanion extends AltosTelemetryStandard {
                        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());
        }
 }
index 6ded5461c93c80926e9494a32965c625d3abc609..ea3074429c2cf4989e6e60e1668e90c255664a3a 100644 (file)
  * 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());
        }
 }
index 9c5f8dae92bc529266e1ca002a4e0d970397a5a9..135b028447bb6ac49bf85ccbce1b6ea33cf27be4 100644 (file)
  * 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);
        }
 }
index 0cba86a31c5712e28e96cdc0ffdbf7f8ae363806..d3e4ce67b83bcd5342557eaa066877c57cbb05fe 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -67,7 +67,7 @@ public class AltosTelemetryIterable implements Iterable<AltosTelemetry> {
        int index;
 
        public void add (AltosTelemetry telem) {
-               int     t = telem.tick;
+               int     t = telem.tick();
                if (!telems.isEmpty()) {
                        while (t < tick - 1000)
                                t += 65536;
@@ -80,29 +80,25 @@ public class AltosTelemetryIterable implements Iterable<AltosTelemetry> {
                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");
                }
        }
 }
index 08c529860bd6da4f4985b903a3420a5c3ec1e55d..027f601e1aa553fa022ae12636e55ee9ac8d7f58 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.text.*;
 
@@ -233,6 +233,17 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
        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;
@@ -271,7 +282,6 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
                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);
@@ -420,7 +430,6 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
         * Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that
         */
 
-       int[]   bytes;
        int     adjust;
 
        /*
@@ -452,8 +461,9 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
        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;
 
@@ -463,6 +473,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
                } else
                        serial = uint16(0);
 
+               rssi = super.rssi();
                callsign = string(62, 8);
                flight = uint16(2);
                state = uint8(4);
@@ -537,23 +548,26 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
                }
        }
 
-       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);
        }
 }
index 1199564020bbf57173443dad3e3d340a4d1712ba..f4366e33a3116ada1f71104dc4854dce701e1cad 100644 (file)
  * 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();
        }
 }
index c81854347de7d17e62171a0e56d1d990ef9e74bd..a7ddc684ee1a25b7bd2b72d5ba269d10937f17cc 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
 
index 6ea5ec89897ab541bf1a2c7ca85328f806f65163..7ef9c63759fd0e00ff70823903837c9e162973f0 100644 (file)
  * 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);
        }
 }
 
index 2dfc455aa5ca0d09adf7859d1581e6344ddfc405..4c64b55456b9ef8731593aafc2c2177ff0132aa2 100644 (file)
  * 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));
        }
 }
index 53a10cc41ea6ed9a91b09083693a300d8ccd4442..8cd09b41c3b697a60a7350a00952d2cdbfc2cb2d 100644 (file)
  * 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());
        }
 }
index e15043b4add4862724d6d7a8b184c5625864046b..79d3a499dcad7edde7443852bac42c4028484dce 100644 (file)
  * 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()));
        }
 }
index 50ec504d6934b89a08cfa187e3ae074ad85734fc..3ea287ac23de4206022c2a67c3aee38ce043d5b0 100644 (file)
  * 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);
        }
 }
index 21f8c485d6d1781367563555a40e1482cdb6d88e..c66f8e6114316da6e6e1538b6b96066505b5ff5e 100644 (file)
  * 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);
        }
 }
index 339043a66c3a3c0228471fb6a180ad46af5892db..f2108d6861bbcf886987555f5d1bc34023b1f859 100644 (file)
  * 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);
        }
 }
index 6a93c2c3f262ad5bce24b5fe0dde0f028be0fff4..26fe4f26c38823584307d1b861637b7b0b105431 100644 (file)
  * 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;
 
@@ -40,14 +41,22 @@ public class AltosTelemetryReader extends AltosFlightReader {
                                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();
        }
@@ -55,6 +64,7 @@ public class AltosTelemetryReader extends AltosFlightReader {
        public void reset() {
                flush();
                state = null;
+               cal_data = null;
        }
 
        public void close(boolean interrupted) {
index 6897f0e6d4273e740a51ad98e2773d0c0072197b..60bc4a51db41ba15cbb4ddcc1a1333094b6239bc 100644 (file)
  * 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)
@@ -38,14 +37,22 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard {
                                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();
        }
 }
index 3c3e6a0104b6b24b5de437e0cc00f2b9a30c24e2..dc8efa9b1d7c3a269b9b1c4371d870f1547e6e3b 100644 (file)
  * 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);
        }
 }
index 35d315c7972963b4b3ea1b9bfa447704c70e5d2a..2a1c93652f08d8f42379deb693c587fdda1eb3e5 100644 (file)
  * 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);
        }
@@ -50,10 +47,16 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
                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:
@@ -97,15 +100,11 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
                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);
        }
 }
index d63e81d1c835983b0f05c945d2853606cc12b665..efc6d5e122902801ea686e6b78b58ceec8180982 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
diff --git a/altoslib/AltosTime.java b/altoslib/AltosTime.java
new file mode 100644 (file)
index 0000000..5c6ab03
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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; }
+}
diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java
new file mode 100644 (file)
index 0000000..b3c432f
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * 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>();
+       }
+}
diff --git a/altoslib/AltosTimeValue.java b/altoslib/AltosTimeValue.java
new file mode 100644 (file)
index 0000000..298ac7f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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;
+       }
+}
index 717a106a41e3793abcf65b2d2308c35ebd25323f..e119448767d024a07a962b73a2afff61bbf4cf66 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.text.*;
 
@@ -41,6 +41,10 @@ public abstract class AltosUnits {
 
        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);
@@ -113,6 +117,10 @@ public abstract class AltosUnits {
                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;
index e094810c38b806686cf0c5c788d3aecaabdbb7da..1f06afbf1d1fce81daad204727d9dd7fccd48294 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 9f56001d2a48a761124e830e909809e4af1d04fb..6bf0d91fc8baf470f8cf2500791a0381caf73693 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.text.*;
 
index 114abc76679343714191b09316ea607f806331f3..e4bebcd44a0297d4fb3ef70e4038f05e4de18497 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index a48c532b99fa9cd25eff3c31eb9a3395e46d60a1..c8399f2ec8419db637a2c2d183ab7a59747ab887 100644 (file)
@@ -16,7 +16,7 @@
  * 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@";
index 8031c8057ad71a4372d0662b8898dfc25240784c..ef53ac11cd3072e277b0224a7c81e53e619bb957 100644 (file)
@@ -16,7 +16,7 @@
  * 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 {
 
index 691dc4de9812063df62aca4ef6171feb86cc44c2..c77e48b0d7d17fb762538f4e88d2c5eca22adacd 100644 (file)
  * 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();
 }
index b93d1f88925612480137429f1d6cc1d84b3a6d57..11b5d562ee643ae1f7e061bc9a885702c6d22a86 100644 (file)
@@ -26,6 +26,7 @@ record_files = \
 
 altoslib_JAVA = \
        AltosLib.java \
+       AltosCalData.java \
        AltosCompanion.java \
        AltosConfigData.java \
        AltosConfigDataException.java \
@@ -34,7 +35,8 @@ altoslib_JAVA = \
        AltosCRCException.java \
        AltosCSV.java \
        AltosDebug.java \
-       AltosEepromNew.java \
+       AltosEeprom.java \
+       AltosRecordSet.java \
        AltosEepromRecord.java \
        AltosEepromRecordFull.java \
        AltosEepromRecordTiny.java \
@@ -44,7 +46,6 @@ altoslib_JAVA = \
        AltosEepromRecordGps.java \
        AltosEepromRecordFireTwo.java \
        AltosEepromRecordSet.java \
-       AltosEeprom.java \
        AltosEepromChunk.java \
        AltosEepromDownload.java \
        AltosEepromMonitor.java \
@@ -54,11 +55,15 @@ altoslib_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 \
@@ -82,9 +87,11 @@ altoslib_JAVA = \
        AltosOrient.java \
        AltosParse.java \
        AltosPressure.java \
+       AltosPresTemp.java \
        AltosPreferences.java \
        AltosPreferencesBackend.java \
        AltosProgrammer.java \
+       AltosPyroName.java \
        AltosReplayReader.java \
        AltosRomconfig.java \
        AltosSavedState.java \
@@ -98,8 +105,8 @@ altoslib_JAVA = \
        AltosSensorMetrum.java \
        AltosSensorTGPS.java \
        AltosState.java \
-       AltosStateIterable.java \
-       AltosStateUpdate.java \
+       AltosStateName.java \
+       AltosStringInputStream.java \
        AltosTelemetry.java \
        AltosTelemetryConfiguration.java \
        AltosTelemetryCompanion.java \
@@ -119,6 +126,9 @@ altoslib_JAVA = \
        AltosTelemetrySensor.java \
        AltosTelemetrySatellite.java \
        AltosTelemetryStandard.java \
+       AltosTime.java \
+       AltosTimeSeries.java \
+       AltosTimeValue.java \
        AltosUnitsListener.java \
        AltosUnknownProduct.java \
        AltosMs5607.java \
@@ -135,6 +145,7 @@ altoslib_JAVA = \
        AltosLocation.java \
        AltosLatitude.java \
        AltosLongitude.java \
+       AltosRotationRate.java \
        AltosPyro.java \
        AltosWriter.java \
        AltosQuaternion.java \
index c2cf409084e1ec5b44448830d0cfaf9a10369902..9f176c4bef2a236f8a581a806446a297966a2192 100644 (file)
@@ -21,8 +21,8 @@ package altosui;
 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 {
 
index a4f475cb321e355eaf2a5eb77b0940791e7efd9a..ab052e5f6c0831d06df71f1f2aaa75328346cbb0 100644 (file)
@@ -22,8 +22,8 @@ import java.util.*;
 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;
index 52815d6f79205da123ff7591c1677b8b993f6c1b..95e1d2d90a7469054f745cf585ffb01488f00cd2 100644 (file)
@@ -20,8 +20,8 @@ package altosui;
 
 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;
index 07802247c9e0d824d020f5b1e83b8eaa8ee0eb66..bf2b81665fe856a81a11bbffc117f22ae9817afe 100644 (file)
@@ -23,8 +23,8 @@ import javax.swing.*;
 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 {
 
index 2d4b216c12aa155de21897f8fcee912f9e0afdab..5016ea63be2d35ccae942b4eff4ad0ca960146a5 100644 (file)
@@ -23,8 +23,8 @@ import java.awt.*;
 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
index 621db3c01203e43e39d2bce55c4790f2f77c83ea..9fedc56db94ac4d42e8bd5b776ad29fe13f679b4 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.event.*;
 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 {
 
index 529c2fa20ac1e74619145dcd2ae0ca33e03efd09..3ff5621843d4166a4e47e213124274b19c37630c 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.*;
 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
index e5f1949a4d2ac78c33160637c4a78275aee8cd69..270131b819188e206d7b720bb13fe0cb742b0f08 100644 (file)
@@ -23,8 +23,8 @@ import java.awt.event.*;
 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
@@ -193,46 +193,46 @@ public class AltosConfigUI
        }
 
        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())
@@ -243,14 +243,14 @@ public class AltosConfigUI
        }
 
        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())
@@ -263,7 +263,7 @@ public class AltosConfigUI
        }
 
        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");
@@ -959,12 +959,10 @@ public class AltosConfigUI
        }
 
        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 {
@@ -1008,7 +1006,7 @@ public class AltosConfigUI
                } 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();
@@ -1024,11 +1022,10 @@ public class AltosConfigUI
        }
 
        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 {
@@ -1047,11 +1044,11 @@ public class AltosConfigUI
        }
 
        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 {
@@ -1059,8 +1056,10 @@ public class AltosConfigUI
        }
 
        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() {
@@ -1068,40 +1067,33 @@ public class AltosConfigUI
        }
 
        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() {
@@ -1109,14 +1101,16 @@ public class AltosConfigUI
        }
 
        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;
@@ -1133,11 +1127,12 @@ public class AltosConfigUI
        }
 
        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();
        }
 
@@ -1147,84 +1142,92 @@ public class AltosConfigUI
        }
 
        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() {
@@ -1248,58 +1251,53 @@ public class AltosConfigUI
        }
 
        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 {
@@ -1310,9 +1308,9 @@ public class AltosConfigUI
 
        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 {
@@ -1322,49 +1320,49 @@ public class AltosConfigUI
        }
 
        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;
        }
 }
index 6aefb3a62f6a1f1faa2d69eda0dc08b6465afa2a..acafc65996f3e22b6c5359ffd809d63789b7e9e2 100644 (file)
@@ -23,7 +23,7 @@ import java.awt.event.*;
 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
index 0c3a8e9eea4cb3ac95dd411cc2ca4d7d5695151e..2cc65b088b5ea9d208422dd572eec7ec6efb7eaf 100644 (file)
@@ -22,8 +22,8 @@ import java.util.*;
 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 {
 
index 4288fc9feea97c9d647285b82a4e687356f7b7d9..a5e5a4efec4fea8fae1f2dd3f78c9539145e492d 100644 (file)
@@ -20,8 +20,8 @@ package altosui;
 
 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;
@@ -93,14 +93,14 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
                }
 
                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;
                        }
                }
 
@@ -120,13 +120,14 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
 
                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;
                        }
                }
 
@@ -147,13 +148,14 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
                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;
                        }
                }
 
index 7b872df9a599d93115ac851ba0218a0caafcb201..9c4e1beed300ab3330cd84e575cb0affcffbfa87 100644 (file)
@@ -28,7 +28,7 @@ import java.util.*;
 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 = {
index 82ef43c2c8428052d30a987ce4ea47a6907b1e7b..b8b0d38a9d56bf7f2a62a623d896727c4bf13eae 100644 (file)
@@ -19,7 +19,7 @@
 package altosui;
 
 import java.awt.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class AltosFlightStatusUpdate implements ActionListener {
 
index cf03d2dc3732562185f8c4ca4c33bbd2c4b18acd..44e995be300e8be012a3ce01fcd3d55c279a5af4 100644 (file)
@@ -23,8 +23,8 @@ import java.awt.event.*;
 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;
@@ -36,7 +36,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
        JTabbedPane     pane;
 
        AltosPad        pad;
-       AltosIgnitor    ignitor;
+       AltosIgnitor    igniter;
        AltosAscent     ascent;
        AltosDescent    descent;
        AltosLanded     landed;
@@ -45,7 +45,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
        boolean         has_map;
        boolean         has_companion;
        boolean         has_state;
-       boolean         has_ignitor;
+       boolean         has_igniter;
 
        private AltosFlightStatus flightStatus;
        private AltosInfoTable flightInfo;
@@ -101,7 +101,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
                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) {
@@ -115,21 +115,20 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
 
                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;
                        }
                }
 
@@ -145,7 +144,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
                        }
                }
 
-               if (state.gps != null && state.gps.connected) {
+               if (state.gps != null) {
                        if (!has_map) {
                                pane.add("Site Map", sitemap);
                                has_map = true;
@@ -272,8 +271,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
                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();
index 4ca2b77c3781856898654d72cdb828493c5ea764..f6c906c64fa78a1a14802b20d47914efcbbe7dab 100644 (file)
@@ -24,8 +24,8 @@ import java.util.ArrayList;
 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;
@@ -37,22 +37,35 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
        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) {
@@ -69,18 +82,24 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                        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);
 
@@ -89,7 +108,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                pane.add("Flight Statistics", statsTable);
 
                has_gps = false;
-               fill_map(states);
+               fill_map(flight_series);
                if (has_gps)
                        pane.add("Map", map);
 
@@ -108,7 +127,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                pack();
 
                setVisible(true);
-               if (state != null && has_gps)
-                       map.centre(state);
+               if (gps != null)
+                       map.centre(gps);
        }
 }
index 4d5c3b2df7661f96c6f91b67a8e7120bcd7d830a..a2696f1518433f57cb541620be94b8f52a3d1a40 100644 (file)
@@ -25,8 +25,8 @@ import javax.swing.event.*;
 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;
@@ -34,12 +34,12 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
        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() {
@@ -75,15 +75,15 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
 
        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) {
@@ -102,8 +102,8 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
                        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) {
@@ -274,7 +274,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
                flightInfo = new AltosInfoTable();
                pane.add("Table", new JScrollPane(flightInfo));
 
-               ignitor = new AltosIgnitor();
+               igniter = new AltosIgnitor();
 
                sitemap = new AltosUIMap();
 
index 15493b8a373c08c15cbbe0febf3c2234692a0776..debbf763481136e781ff274d165da27c2d0abb54 100644 (file)
@@ -25,8 +25,8 @@ import java.io.*;
 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
@@ -213,6 +213,8 @@ public class AltosIgniteUI
                        fired();
                } else if (reply.startsWith("npyro")) {
                        npyro = Integer.parseInt(reply.substring(6));
+                       if (npyro == AltosLib.MISSING)
+                               npyro = 0;
                        make_ui();
                }
        }
@@ -255,15 +257,11 @@ public class AltosIgniteUI
 
        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() {
index fabf43202eb3bbf26332ce750e54e4ff68b6a94c..7c7d1fba2cac14c925f018494f7d3bd638f74b9a 100644 (file)
@@ -21,65 +21,65 @@ package altosui;
 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);
index 25d4fcc80ea796ae88c63fabfdd426f90fef3e7d..c2e149232cbfed35871e0a96680d74d8a54b29d8 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.*;
 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 {
 
@@ -123,18 +123,17 @@ 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) {
                                        }
index d4e73b3e994e78a2caf254b5da79255a78f2f434..f1893cf505a3cf5a92625e6e3137e9a63efaf28a 100644 (file)
@@ -21,7 +21,7 @@ package altosui;
 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;
index 835858e23230e17f4d4ab72bf64ed422cc147e26..8a24ed3e1f2a54beefac6eef78077cf3b5e1e541 100644 (file)
@@ -24,7 +24,7 @@ import javax.swing.*;
 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) {
index d411c969a71eb2c2d348d7e43c0b292ad9dc165f..0aeef8e159cd92bf79c3826f5f445c162deca8e7 100644 (file)
@@ -19,8 +19,8 @@
 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 {
 
@@ -46,10 +46,11 @@ 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 ||
@@ -59,7 +60,7 @@ public class AltosPad extends AltosUIFlightTab {
                                                show("Recorded data");
                                } else
                                        show("Storage full");
-                               set_lights(state.flight != 0);
+                               set_lights(cal_data.flight != 0);
                        }
                }
                public LoggingReady (AltosUIFlightTab container, int y) {
@@ -128,10 +129,8 @@ public class AltosPad extends AltosUIFlightTab {
        }
 
        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;
                }
@@ -150,7 +149,7 @@ public class AltosPad extends AltosUIFlightTab {
                                if (report_pad(state)) {
                                        lat = state.pad_lat;
                                        label = "Pad Latitude";
-                               } else {
+                               } else if (state.gps != null) {
                                        lat = state.gps.lat;
                                        label = "Latitude";
                                }
@@ -187,7 +186,7 @@ public class AltosPad extends AltosUIFlightTab {
                                if (report_pad(state)) {
                                        lon = state.pad_lon;
                                        label = "Pad Longitude";
-                               } else {
+                               } else if (state.gps != null) {
                                        lon = state.gps.lon;
                                        label = "Longitude";
                                }
@@ -217,8 +216,10 @@ public class AltosPad extends AltosUIFlightTab {
                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) {
index 72c3c161b4809042423330098ed5307ea1cf4e93..26591738440a197dbde1d60cb1241644b06296bc 100644 (file)
@@ -23,8 +23,8 @@ import java.awt.event.*;
 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();
@@ -310,10 +310,9 @@ public class AltosUI extends AltosUIFrame {
                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);
                }
        }
@@ -325,6 +324,13 @@ public class AltosUI extends AltosUIFrame {
                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
         */
@@ -332,10 +338,11 @@ public class AltosUI extends AltosUIFrame {
        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.
@@ -344,11 +351,11 @@ public class AltosUI extends AltosUIFrame {
        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) {
                }
@@ -365,21 +372,6 @@ public class AltosUI extends AltosUIFrame {
                }
        }
 
-       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);
@@ -398,17 +390,28 @@ public class AltosUI extends AltosUIFrame {
                }
        }
 
+       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");
@@ -420,15 +423,16 @@ public class AltosUI extends AltosUIFrame {
                        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");
@@ -440,38 +444,19 @@ public class AltosUI extends AltosUIFrame {
                        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) {
@@ -483,11 +468,11 @@ public class AltosUI extends AltosUIFrame {
        }
 
        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) {
@@ -496,85 +481,51 @@ public class AltosUI extends AltosUIFrame {
        }
 
        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;
        }
 
@@ -620,8 +571,6 @@ public class AltosUI extends AltosUIFrame {
                                        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 {
@@ -650,9 +599,6 @@ public class AltosUI extends AltosUIFrame {
                                                if (!process_summary(file))
                                                        ++errors;
                                                break;
-                                       case process_cat:
-                                               if (!process_cat(file))
-                                                       ++errors;
                                        }
                                }
                        }
index 313cf0a0fa626d303360e879df8624145003315b..5b9ab06ade76dceacee37ddd7e8c72a2baedf032 100644 (file)
  * 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 {
 
index 1ea31950bf970822b077e3125009a5a5c5bff708..ac9068d08f004c1b2661f6dbe474a4edf28d461a 100644 (file)
  * 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;
index 32cc05d70064e30b9853fda6547e07fc2707f508..56f1991f19d9f5f30c25f60c8343b3b27f567bca 100644 (file)
  * 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>();
index 14e0a056f19d7abf44ec4b4f92e0b46da0bd3208..aec4c34d2351eb47bc001bde58c2cb78df5c810b 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -24,7 +24,7 @@ import javax.swing.*;
 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;
index 1b769740cbadb6343fb9a307fe104055e7161cc0..442e3de3520483cf092c1555e482249d01449fb5 100644 (file)
  * 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
@@ -31,7 +31,8 @@ public class AltosCSVUI
        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)" };
@@ -55,8 +56,9 @@ public class AltosCSVUI
                        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();
@@ -91,7 +93,7 @@ public class AltosCSVUI
                                        writer = new AltosCSV(file);
                                else
                                        writer = new AltosKML(file);
-                               writer.write(states);
+                               writer.write(series);
                                writer.close();
                        } catch (FileNotFoundException ee) {
                                JOptionPane.showMessageDialog(frame,
index c4d2abba26c81fa153a204104de27b9675708cfb..055d34f919456a237bedf08311c1d7ea945af88a 100644 (file)
  * 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;
index a8c74926381482d0b108575377253c1e5994484c..b417c732239a9292bef679688cb5ea08b6755f18 100644 (file)
  * 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;
@@ -36,7 +36,7 @@ public class AltosDataChooser extends JFileChooser {
                return file;
        }
 
-       public AltosStateIterable runDialog() {
+       public AltosRecordSet runDialog() {
                int     ret;
 
                ret = showOpenDialog(frame);
@@ -44,22 +44,8 @@ public class AltosDataChooser extends JFileChooser {
                        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(),
index f9878fe94739130b237d1e6e71430b50a216d314..44f71f7a96e08d6a208124b01e64eb2545b79956 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
 
 import libaltosJNI.*;
 
index 5d8ff570f747f772598538e0dd594e0df16a42ea..77249bfcca014a6cd7b6cb3acc86f1aac6fb690f 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index c2d6f4f38b63b00abb4f594fde05d074353dd780..f3409cced157500951119fdb2853c1639c093d8d 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 52414c62038e155b2305a66559cff2cf84f3954f..3fcc02dac353bba782fb15b85218c69d7b20fcd3 100644 (file)
  * 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 {
 
@@ -30,7 +30,9 @@ 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;
 
@@ -93,13 +95,13 @@ public class AltosDisplayThread extends Thread {
                            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 {
@@ -121,7 +123,7 @@ public class AltosDisplayThread extends Thread {
                                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;
@@ -164,7 +166,7 @@ public class AltosDisplayThread extends Thread {
                }
 
                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)
@@ -179,16 +181,16 @@ public class AltosDisplayThread extends Thread {
 
        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.",
@@ -196,17 +198,18 @@ public class AltosDisplayThread extends Thread {
                                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;
        }
 
@@ -220,14 +223,11 @@ public class AltosDisplayThread extends Thread {
                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);
index 24337be4a784b9f5e0f192c5add24b6a18275cfa..87e80a51a75001a90d4d137075d5b0a4a522c04e 100644 (file)
  * 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;
index a6636c4f5acde715c448f935a367ecae07b15468..93827139d0af83507e23644cb20f266eaa0101f3 100644 (file)
  * 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 {
 
diff --git a/altosuilib/AltosEepromMonitor.java b/altosuilib/AltosEepromMonitor.java
deleted file mode 100644 (file)
index d61169f..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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);
-       }
-}
index 036616626bf6ad46f3604500a359fd5d0d445d87..3427fe0fac5f5a8e675f056a2c5c6e3df3295ffb 100644 (file)
  * 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;
index 2c6ee6d7aaeca45a0daff82bb7f04cb8eb59af7e..0c890c8b445846178b1a51af4e3013eb1cd0995d 100644 (file)
  * 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;
index da36397abc7f7bda1c46ab3e81482d1a8cba2f0c..ca089ca845a6a4dd1bd068df1cee8bf67cc18a99 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -24,7 +24,7 @@ import javax.swing.*;
 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
index 2d371101388029f56fbdc056de681045d5e9fab2..943c9207d3ed866e96aacba5ee3a7bf18d6494c8 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
 
 import javax.swing.table.*;
 
index 2f46f231cbc0221dc9ffb1a3520f854eeb23bbb5..415c024484fac4895695c21e2c055034853c23c0 100644 (file)
  * 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;
@@ -87,13 +87,19 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen
                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),
@@ -108,61 +114,112 @@ public class AltosFlightStatsTable extends JComponent implements AltosFontListen
                }
                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);
+       }
 }
index 2dbd1612cad13ffd10959720605a6107e6be996a..31042abb51e34ca1da41c1f0ff4df5809243280d 100644 (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.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.*;
@@ -35,162 +35,32 @@ import org.jfree.chart.labels.*;
 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);
@@ -198,278 +68,268 @@ public class AltosGraph extends AltosUIGraph {
        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));
        }
 }
diff --git a/altosuilib/AltosGraphDataPoint.java b/altosuilib/AltosGraphDataPoint.java
deleted file mode 100644 (file)
index 0012d96..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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;
-       }
-}
diff --git a/altosuilib/AltosGraphDataSet.java b/altosuilib/AltosGraphDataSet.java
deleted file mode 100644 (file)
index 065a781..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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;
-       }
-}
index 7ede28244e5f8748e0ba3b800b8a0c313883fb0f..9e528b1fd27f6ae4295bb7bdc013a53c3a74ab0c 100644 (file)
  * 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;
@@ -128,6 +128,8 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar
 
        public void show(AltosState state, AltosListenerState listener_state) {
 
+               AltosCalData    cal_data = state.cal_data();
+
                if (!isShowing()) {
                        last_state = state;
                        last_listener_state = listener_state;
@@ -136,14 +138,14 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar
 
                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)
index c06e45e5e9b15028f496acebae1a6feafc33c6b4..b53e760439058a75ebf954b534239e9033c89636 100644 (file)
@@ -16,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
 
 import javax.swing.*;
 
index 394cfc67912728b758e95c54d17a6ebd9377ff49..7b02d770cc97d608ef355b81cd9cf31b4a24916c 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 8c4d25166b98f9cb154543037977dc6948532157..f44735e2d9796d23a5a6457ad4625a772a8fa91e 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index c1b8ac26100ca645d498886c0297a2640523d1ff..743232180bb3dea9ccb1d21d9f0f36a0d6022324 100644 (file)
  * 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
index 8843429a6113b6be45d2cc8f1a974f11fec82561..c63f027c12d7c0de1e12a95475937feae6d2ae77 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -26,7 +26,7 @@ import java.io.*;
 import java.util.*;
 import java.text.*;
 import java.util.concurrent.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 class AltosScanResult {
        String          callsign;
@@ -213,10 +213,11 @@ public class AltosScanUI
                                                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);
index 5c32a7d8448512e3bed8e394bd9e62fbb05f777f..d7c6129cdf1e21e4b595e9436fe30b75e305b62d 100644 (file)
  * 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.*;
 
 /*
index e0de8ad79c13d58db0dd3293cfcb29af23518fb3..c8ca4d569c84e4485e0cc9c6b2eb68ef489b56e2 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index e41667ef906f4f038b9325623ca050ba0638f318..fe94f161f5543beb81494080757e0af0bc4be76e 100644 (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.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.*;
@@ -49,11 +49,14 @@ public class AltosUIAxis extends NumberAxis {
        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) {
index 19512f49b3ce07d1e75f121b5be62868a433aa4d..e3d867243ac2980390a9cae5d919807949aa0e80 100644 (file)
  * 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> {
 
index a59cc0a042e0b1f18e6a3cba8b02207706b1ca7a..05227e1da069e0a99db41797ce5b584af2df8e97 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 4107feae6945148df7aac3be686710f640ddfc6f..36fadeaf52d5a3fbf73f9670b15b5a1da372dbff 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index ffab46c1a186330ab05ae008c01ebbab035d1b44..ddda3d3d91908d089fa3362e336d7b6c36ceccf5 100644 (file)
@@ -16,7 +16,7 @@
  * 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();
index 85b402293edbd73c151fd353877927293afd3401..5eafa45782377da6c9b3dc0e38fa2215b32eaa5f 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 4c733b9601496f5d1b54b5d2c6ac021253a147ac..0c23fa8d3279bd23f26e9b8249a98ccd4953b045 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -24,7 +24,7 @@ import javax.swing.*;
 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.*;
diff --git a/altosuilib/AltosUIFlightSeries.java b/altosuilib/AltosUIFlightSeries.java
new file mode 100644 (file)
index 0000000..19bed60
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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>();
+       }
+}
index 3adbdb336b703e707816d4d8eb3b2dd9a4062bcd..cf6a0c746ac4114d4b56f2ed605ebd7efdd42614 100644 (file)
  * 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;
index e5007fff78bd5aacb4ac73af9055b847ae4c3bb3..b7eee66453bdd8000390cb9b31a8641353493b1a 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index 4dd9fece0e1b483477c40ba467fbc6229e909537..7a5c3543a8e05324d9ca985f3d881d095d9fd33a 100644 (file)
  * 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> {
 
index d37603846595d0bd4fca46e9d9c7967a9377444d..0caabcfa4a009829b59a5ae55ddf0ae1d597307e 100644 (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.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.*;
@@ -42,10 +43,10 @@ public class AltosUIGraph implements AltosUnitsListener {
        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);
@@ -65,70 +66,65 @@ public class AltosUIGraph implements AltosUnitsListener {
                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);
@@ -139,7 +135,7 @@ public class AltosUIGraph implements AltosUnitsListener {
                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);
@@ -156,5 +152,6 @@ public class AltosUIGraph implements AltosUnitsListener {
                panel.setPreferredSize(new java.awt.Dimension(800, 500));
 
                AltosPreferences.register_units_listener(this);
+
        }
 }
index 0735814448075aa6b5c7761cfc34ee99b13e9ba6..916d0b3fca236c83167548d3901ede1e167e2ca3 100644 (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.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.*;
@@ -39,6 +39,8 @@ interface AltosUIGrapher {
 
        public abstract void set_units();
 
+       public abstract boolean need_reset();
+
        public abstract void clear();
 
        public abstract void add(AltosUIDataPoint dataPoint);
index b157a2ce8dd4e2f8b3b2255db8875a5ca03c295e..f23b50bc0f369fbd2f414780a68ec2d38a7ed359 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index f47a2f29797041aa6698ed4cd786c1e501ea998d..ac2e6f0663df2c38d79f905bab67754f0eb7e173 100644 (file)
  * 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;
index 0c5fa1c7df3992a732230fe83992482826d29d0f..ef706e364c2dabd5af947c53af40e4335ca16211 100644 (file)
  * 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 {
 
index 55ce584ae3d90a7bb0d2ea6d4f064447d4eff507..54a0066196b5121bc25afd4d1039ff8cb1b78ffc 100644 (file)
@@ -16,7 +16,7 @@
  * 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);
index 3e4cbe9b8a3e657860c308a52e7a5210313904b0..2e1e8f160bf8f5a2899c1993c1a534a9bdb224d6 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -28,7 +28,7 @@ import java.awt.geom.*;
 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 {
 
@@ -413,6 +413,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                map.show(state, listener_state);
        }
 
+       public void show(AltosGPS gps, int state) {
+               map.show(gps, state);
+       }
+
        public String getName() {
                return "Map";
        }
@@ -422,6 +426,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                map.centre(state);
        }
 
+       public void centre(AltosGPS gps) {
+               map.centre(gps);
+       }
+
        /* internal layout bits */
        private GridBagLayout layout = new GridBagLayout();
 
index 06c4c59bcf406590f3edf18b5d59d0a230144565..81cda0d2952c100cdac7fcb39a5c21ee392366b9 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
@@ -27,7 +27,7 @@ import java.text.*;
 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;
index 9d8dde6062d135678c04eaf021a1f9f84e312180..90cdb291728e1e7cb4ab43011a5a9de02f439f0d 100644 (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.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.*;
@@ -56,6 +56,8 @@ public class AltosUIMarker implements AltosUIGrapher {
        public void set_units() {
        }
 
+       public boolean need_reset() { return true; }
+
        public void set_enable(boolean enable) {
                if (enabled == enable)
                        return;
@@ -110,4 +112,4 @@ public class AltosUIMarker implements AltosUIGrapher {
        public AltosUIMarker (int fetch, Color color, XYPlot plot) {
                this(fetch, color, plot, true);
        }
-}
\ No newline at end of file
+}
index c8ae9a7d5cc8884b52d19a8af080f3db40fc5041..a2014065d731d4f519110c982417aedaeb8f4b8e 100644 (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 {
 
index 6dd2baaf15f55b383010df122e20fd641fd3be28..163ba173f2076f1fac0386ea7ceb8ddaf023b5f1 100644 (file)
  * 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 {
index 187977d39562e6ba31ff11401ac962e0b93ce4f5..d1c15ce0d44fa2994ace90cc532d2097915bcb5e 100644 (file)
  * 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> {
 
@@ -27,10 +27,9 @@ 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) {
diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java
deleted file mode 100644 (file)
index 66cc7d6..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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();
-       }
-}
index f02d2f7f069607e8e1033e7d573e06ff9b839803..f884cd412312ca9d2ff1b82c2943da313d1e799c 100644 (file)
  * 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> {
diff --git a/altosuilib/AltosUITimeSeries.java b/altosuilib/AltosUITimeSeries.java
new file mode 100644 (file)
index 0000000..08f95ca
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * 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);
+       }
+}
index d4dd18db0b2fead58625919270fdfc067de7ee6b..bbfebef6c1c4652e812c9eae2f25e8b6f0c50e4a 100644 (file)
  * 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 {
 
index 299c6114b18877a4b2bac2d7dae04431ac711d84..297a65312d086f1234118045e2262c0ed6eae427 100644 (file)
  * 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 {
 
index 221ac829727715c08d02b10d4f47c48fb9ecddb2..49f966f330b56e9f7c3f7fc53bc3dd9c0a161c2c 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index c651aa35b114207b417fb78ae1c6bd8266888fde..1d579a166deaedd2a1772176405e981c71e9c879 100644 (file)
@@ -16,7 +16,7 @@
  * 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;
index 0e57fe4d1cf1097b75eee8084913e8095b56fd65..665ef89eadb0d1a2c93540a3aa7cd5521aa13c7f 100644 (file)
@@ -16,7 +16,7 @@
  * 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.*;
index d18006b584bc0a6797c1d9603848f61a243b1470..4b5eb524c09824995393bb4a25d856f0f682dd6e 100644 (file)
@@ -18,7 +18,6 @@ altosuilib_JAVA = \
        AltosUIDataMissing.java \
        AltosUIDataPoint.java \
        AltosUIDataSet.java \
-       AltosUIGraph.java \
        AltosUIGrapher.java \
        AltosUIDialog.java \
        AltosUIEnable.java \
@@ -28,7 +27,9 @@ altosuilib_JAVA = \
        AltosUIMarker.java \
        AltosUIPreferencesBackend.java \
        AltosUIPreferences.java \
-       AltosUISeries.java \
+       AltosUIFlightSeries.java \
+       AltosUIGraph.java \
+       AltosGraph.java \
        AltosUSBDevice.java \
        AltosVoice.java \
        AltosDisplayThread.java \
@@ -50,9 +51,6 @@ altosuilib_JAVA = \
        AltosInfoTable.java \
        AltosFlightInfoTableModel.java \
        AltosFlightStatsTable.java \
-       AltosGraph.java \
-       AltosGraphDataPoint.java \
-       AltosGraphDataSet.java \
        AltosBTDevice.java \
        AltosBTDeviceIterator.java \
        AltosBTManage.java \
@@ -67,6 +65,7 @@ altosuilib_JAVA = \
        AltosUITelemetryList.java \
        AltosUIRateList.java \
        AltosUIImage.java \
+       AltosUITimeSeries.java \
        OSXAdapter.java
 
 JAR=altosuilib_$(ALTOSUILIB_VERSION).jar
index de5d58362127ddcd745ade547c350474955cbde6..c338396f90545da359e4cf1fe62e93d3ba6eb381 100755 (executable)
@@ -55,7 +55,7 @@ Copyright Â© 2003-2007 Apple, Inc., All Rights Reserved
 
 */
 
-package org.altusmetrum.altosuilib_11;
+package org.altusmetrum.altosuilib_12;
 
 import java.lang.reflect.*;
 import java.util.HashMap;
index 990382f48e56cc268905999596427204bf24e1a8..1a8fe13f37a5503a7f7547fcdd3a0506c012e965 100755 (executable)
@@ -7,8 +7,8 @@ else
     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
index 3e6658e9d45cd96bba45123b273c5be2740cc21d..f6de573e02f1a344688326ec99c55b1f50c72382 100644 (file)
@@ -18,13 +18,13 @@ dnl
 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'`
@@ -34,8 +34,8 @@ AC_SUBST(ANDROID_VERSION)
 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])
index 0d01279fbe819d4d533fd38c38c2314396fb0bfd..bbda63019535212cf109df153bdaf1755b7c3008 100644 (file)
@@ -167,7 +167,8 @@ OUTLINE_TXT_FILES=\
        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)
 
diff --git a/doc/telegps-outline.txt b/doc/telegps-outline.txt
new file mode 100644 (file)
index 0000000..bd1495b
--- /dev/null
@@ -0,0 +1,9 @@
+= 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"]
diff --git a/doc/telegps.svg b/doc/telegps.svg
new file mode 100644 (file)
index 0000000..702265c
--- /dev/null
@@ -0,0 +1,33 @@
+<?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>
index 8f69c1ad9661df9b95290c007d89467a8ca8ec9a..69fe7a5716a96d002eb94cb4854dc7f0aeb6d4b2 100644 (file)
@@ -24,11 +24,15 @@ WINDOWS_SRC=\
 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
 
diff --git a/libaltos/btletest.c b/libaltos/btletest.c
new file mode 100644 (file)
index 0000000..0e32541
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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;
+}
index 7ad2c102c191271e976bd32e5cd7a7b20ca6b00b..52b62358db92d70868013838e2a6bb7ef8a41ee1 100644 (file)
@@ -14,18 +14,14 @@ micropeakdir=$(datadir)/java
 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
index d502b9f7fdb001473775d034e11bfe54af838307..70492a07abbebf5e95eaf4ac128ba1f03227590c 100644 (file)
@@ -21,86 +21,21 @@ package org.altusmetrum.micropeak;
 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;
@@ -213,69 +148,45 @@ public class MicroData implements AltosUIDataSet {
                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;
        }
@@ -285,31 +196,27 @@ public class MicroData implements AltosUIDataSet {
        }
 
        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) {
@@ -325,18 +232,24 @@ public class MicroData implements AltosUIDataSet {
        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));
                }
        }
 
@@ -344,9 +257,20 @@ public class MicroData implements AltosUIDataSet {
                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 {
@@ -357,11 +281,30 @@ public class MicroData implements AltosUIDataSet {
 
                        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);
@@ -380,38 +323,40 @@ public class MicroData implements AltosUIDataSet {
                                                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;
-       }
-
 }
diff --git a/micropeak/MicroDataPoint.java b/micropeak/MicroDataPoint.java
deleted file mode 100644 (file)
index 4207929..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
index 010612a0f37c34b21339128919d3b5948040ad25..db2662a0af1657bcbb2cc790c2cc3311f1b19841 100644 (file)
@@ -22,7 +22,7 @@ import javax.swing.*;
 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 {
 
index 2326ea089f3d930bcf88c7c45e73c6f94586dda9..e5f548214dc8324910c56542bbea55f3e5a1281c 100644 (file)
@@ -24,8 +24,8 @@ import javax.swing.*;
 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;
index f106268131654f3f13c894b0f8b48b133555f042..36700e755c6f39cbcdf7f72a2f51ec5790061674 100644 (file)
@@ -24,8 +24,8 @@ import java.util.ArrayList;
 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 {
 
index b341f350392e76622c55694c1985b362b2435f8f..20f6db55be32ef4a5daf9201c5feb3eb328ee10b 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;
 
 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 {
 
index c068244bd835973fee7dd5e7c0ce33dc6ede167c..85f7aed4cdf64e115086bccd11ebdee2063d50f0 100644 (file)
@@ -21,8 +21,8 @@ package org.altusmetrum.micropeak;
 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;
index b6f1f76d7d74052a1fb7ac3d1f66b25352c15761..d9ad8404ca4c5ac75269c50e238e6ff95b066bfe 100644 (file)
@@ -22,7 +22,7 @@ import java.awt.*;
 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 = {
diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java
deleted file mode 100644 (file)
index 64a43bd..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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
index 9023f452df7f4d4578beda8b13b857c1351723e2..607bf20c678607f2f5621a230338ea5c000ed04d 100644 (file)
@@ -24,18 +24,17 @@ import javax.swing.*;
 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;
@@ -47,9 +46,12 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
                        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;
@@ -265,8 +267,9 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
                });
 
                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");
@@ -324,8 +327,9 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
                                                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();
                                }
                        }
                }
index f00d7ea38462dc876080d9ddd5dc82e97097867f..d1d5d07682a1bc4c1bff1c25e4970adf6c8bec56 100644 (file)
@@ -21,8 +21,8 @@ package org.altusmetrum.micropeak;
 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 {
 
@@ -30,7 +30,7 @@ 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()));
index 5dda5b8c53dafdcdac34a87f6c621cc25362f72d..9da769144c3b13584916fd829d212478e271d1ae 100644 (file)
@@ -25,8 +25,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 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 {
 
index 43dfd18bd35f4cd1c898e96bf3e0d353aa23aca1..c1b2a7ad3425466528ca534210dd3937f8977a21 100644 (file)
@@ -21,7 +21,7 @@ package org.altusmetrum.micropeak;
 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;
index 2e6dd23671656ad3d7a4b2d1cb90c372d67cbd45..d33a36b3ac5807cf8b1fe62aab1cd2d279009671 100644 (file)
@@ -21,7 +21,7 @@ package org.altusmetrum.micropeak;
 import java.util.*;
 import java.io.*;
 import libaltosJNI.*;
-import org.altusmetrum.altosuilib_11.*;
+import org.altusmetrum.altosuilib_12.*;
 
 public interface MicroSerialLog {
 
diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java
deleted file mode 100644 (file)
index b963753..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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());
-       }
-}
diff --git a/micropeak/MicroStatsTable.java b/micropeak/MicroStatsTable.java
deleted file mode 100644 (file)
index e095e3a..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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());
-       }
-       
-}
index 4ab5fcc96b33e0d01396d42ee1d6e87c24ac445c..a2db383515ed30dd8055a9842e56bef16ecbfc03 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.micropeak;
 
 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 {
 
index f668fb66e7435f720a08d20cb8d87291326ebb48..c33aa536fde6578d8aaed0bac73454b181fcf93b 100644 (file)
@@ -126,13 +126,15 @@ struct ao_hmc5883_sample ao_hmc5883_current;
 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();
        }
 }
 
@@ -141,10 +143,8 @@ static struct ao_task ao_hmc5883_task;
 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[] = {
index 78637b029ead55cd988f3421d4624d0225dc974c..b90733df0968e09a19cf97e582c03e247aa94193 100644 (file)
@@ -77,7 +77,7 @@
 #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;
index 650407ad8b679d8f98478e82e84da422b1c3bdce..81d3c16cc76479f3eb2298fb23292d0d3191714a 100644 (file)
@@ -192,7 +192,7 @@ _ao_mpu6000_setup(void)
        _ao_mpu6000_wait_alive();
 
        /* Reset the whole chip */
-       
+
        _ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1,
                              (1 << MPU6000_PWR_MGMT_1_DEVICE_RESET));
 
@@ -292,7 +292,7 @@ _ao_mpu6000_setup(void)
 
                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);
@@ -315,7 +315,7 @@ _ao_mpu6000_setup(void)
        /* 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;
 }
@@ -325,6 +325,7 @@ struct ao_mpu6000_sample    ao_mpu6000_current;
 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
@@ -335,14 +336,15 @@ ao_mpu6000(void)
 #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();
        }
 }
 
@@ -351,16 +353,13 @@ static struct ao_task ao_mpu6000_task;
 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[] = {
@@ -374,7 +373,7 @@ ao_mpu6000_init(void)
        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));
 
@@ -386,7 +385,7 @@ ao_mpu6000_init(void)
        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]);
 }
index 0afdf01276b3a5d40337308a5058d1a99f297741..914e0c1b3c7b620ca40c23ee82f88c9ac5b5576e 100644 (file)
@@ -201,11 +201,13 @@ __xdata struct ao_ms5607_sample   ao_ms5607_current;
 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();
index 4e3d12cb42b7b1f67ee74cbb859f14b4f9dc3210..98dc35b55eee33c8b7cd8ba069912423eaf23674 100644 (file)
@@ -39,7 +39,7 @@ static void
 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) {
@@ -100,84 +100,81 @@ static const char *status_strings[] = {
        "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)
 {
@@ -192,7 +189,7 @@ ao_rn_drain(void)
 {
        int     timeout = 0;
 
-       ao_rn_dbg("drain...\n");
+//     ao_rn_dbg("drain...\n");
        ao_serial_rn_drain();
        while (!timeout) {
                ao_arch_block_interrupts();
@@ -204,13 +201,13 @@ ao_rn_drain(void)
                }
                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)
@@ -244,20 +241,20 @@ ao_rn_wait_for(int timeout, char *match)
        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;
 }
 
@@ -266,20 +263,20 @@ ao_rn_wait_line(AO_TICK_TYPE giveup_time, char *line, int len)
 {
        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;
                }
 
@@ -302,7 +299,7 @@ ao_rn_wait_status(void)
        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)
@@ -317,7 +314,7 @@ ao_rn_set_name(void)
        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 {
@@ -330,7 +327,7 @@ ao_rn_set_name(void)
 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);
 }
@@ -404,12 +401,18 @@ ao_rn(void)
                        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
@@ -417,7 +420,9 @@ ao_rn(void)
                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) {
@@ -433,6 +438,12 @@ ao_rn(void)
                        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) {
@@ -465,17 +476,27 @@ ao_rn(void)
 
        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
@@ -487,27 +508,11 @@ ao_rn(void)
                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
 }
 
@@ -539,19 +544,39 @@ ao_rn_factory(void)
        /* 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 },
 };
 
index d6fea23a87ba87c26f6d3f19e2785bee7e4c2537..a4dcea38df5a060d566a99d2e95b547bb1ad7000 100644 (file)
@@ -56,7 +56,7 @@
 
 */
 
-#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
index 5983bb9e9ff1a9627857079caa917aa360e22583..45c6891d8ad790c8b8b3c32090f89cf38db0033f 100644 (file)
@@ -42,7 +42,7 @@
 
 #define PACKET_HAS_SLAVE       0
 
-#define AO_LOG_FORMAT          AO_LOG_FORMAT_EASYMINI
+#define AO_LOG_FORMAT          AO_LOG_FORMAT_EASYMINI1
 
 /* USART */
 
index c141d1a6f5969577e4ad63b763eb919deaf3327e..2ec0e90b803c22dd687b1af90234733a14f84616 100644 (file)
@@ -44,7 +44,7 @@
 #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
 
index 5c568c99e9e3bdd34906c14c92a1bf30d0f27a17..aca669db668c84e5aabbc818f588a59fe299c4a0 100644 (file)
@@ -45,7 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state;
 #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 */
@@ -53,6 +53,7 @@ extern __pdata enum ao_flight_state ao_log_state;
 #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;
@@ -252,8 +253,8 @@ struct ao_log_mega {
                        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 */
index a0212198d3a0ae70128fc3198d259c14b9446ccb..b86abe7af8ebec882225c88c4f5e34619ff13195 100644 (file)
@@ -135,8 +135,8 @@ ao_log(void)
 #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);
index a4c73a869343152800c030bac0490ff3cc1e30e0..2ae1e41bb42ffb31701176424c461831c52d98b6 100644 (file)
@@ -160,8 +160,8 @@ ao_send_mega_sensor(void)
 
 #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();
index 45aaeb075c2f6d7deb9b0ddda379d37a5feb30b9..23e3ed7db7c4a5309f4b76bc7d5db6da424a0a86 100644 (file)
@@ -198,8 +198,8 @@ struct ao_telemetry_mega_sensor {
        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 */
 };
 
index 13a4fd10316ed26818b4dee03e3399f2fa852a4a..fa2ed804f6a6bccce59043c4f7433ae4d47f042f 100644 (file)
@@ -53,7 +53,8 @@ extern uint8_t ao_on_battery;
 #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
index c625471e4b1e9ce39caaf6b7c17a346be76e6953..ef56231334e28894a980f08042a1e72c8530a40f 100644 (file)
@@ -195,7 +195,7 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)
 }
 
 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) |
@@ -236,6 +236,10 @@ ao_usart_init(struct ao_stm_usart *usart)
                          (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);
 }
@@ -244,8 +248,6 @@ ao_usart_init(struct ao_stm_usart *usart)
 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
 
@@ -441,7 +443,7 @@ ao_serial_init(void)
        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);
@@ -494,10 +496,7 @@ ao_serial_init(void)
        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);
@@ -541,7 +540,7 @@ ao_serial_init(void)
        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);
index e20b57550982437f64236b0cd79617f20b83b7c1..59cfde2ed8bc044fb9580fd4693f195dc1f9e4ee 100644 (file)
@@ -180,7 +180,7 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)
 }
 
 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) |
@@ -223,44 +223,39 @@ ao_usart_init(struct ao_stm_usart *usart)
                           (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;
@@ -391,13 +386,13 @@ ao_serial_init(void)
         */
 
 #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);
@@ -409,7 +404,7 @@ ao_serial_init(void)
        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);
@@ -428,8 +423,7 @@ ao_serial_init(void)
         */
 
 # 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
@@ -447,8 +441,7 @@ ao_serial_init(void)
 #  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
@@ -472,10 +465,7 @@ ao_serial_init(void)
        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);
index 40d1f6e472dc9bf2958f42948a56b0d98ec635dc..4636c046fd2f4813af436ac268b195fe5303430b 100644 (file)
@@ -55,6 +55,7 @@ ALTOS_SRC = \
        ao_convert_volt.c \
        ao_packet_master.c \
        ao_packet.c \
+       ao_send_packet.c \
        ao_monitor.c \
        $(PROFILE) \
        $(SAMPLE_PROFILE) \
index 8775d99380312ea92e779bcfd61cbb15ff0c8613..63633c90ceea197c44bef6d1bf078f1d67f28319 100644 (file)
@@ -23,6 +23,7 @@
 #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
@@ -53,6 +54,7 @@ main(void)
        ao_radio_init();
        ao_packet_master_init();
        ao_monitor_init();
+       ao_send_packet_init();
 
        ao_config_init();
 
index 316511207c9de47936e994bd9cb50b9219e52dcf..38ac7513d055e94530d7982adbda21503389991c 100644 (file)
@@ -14,6 +14,7 @@ INC = \
        ao_product.h \
        ao_cc1200_CC1200.h \
        ao_task.h \
+       ao_rn4678.h \
        stm32f0.h \
        Makefile
 
index baf3db69852c83802fb5acd10670a2077853b67a..f3d70d1ad31eb1e81f698345a7aa349d48af152e 100644 (file)
@@ -54,7 +54,7 @@
 #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)
@@ -75,7 +75,6 @@
 #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 */
index b2f5a5ab827920451f30ea960150c13cd5941829..d36d9d824d3c54589bc9eff801be7a9c237c04fd 100644 (file)
@@ -34,7 +34,7 @@
 #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
index a22abe463e1ea50940a3ddb35fb7b123eed91556..a0c2d5feea7658a07e7dc4eb5784135e0d275e5d 100644 (file)
@@ -1,7 +1,7 @@
 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
@@ -37,6 +37,9 @@ ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.
 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 $@ $<
 
index 25ddb48fefb6f982a4558eac59c99089e463f1e3..d3d39f2a1b721b92d9327345964bf432c15b205c 100644 (file)
@@ -46,7 +46,7 @@
 
 int ao_gps_new;
 
-#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2)
+#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI)
 #define TELEMETRUM_V1 1
 #endif
 
@@ -84,6 +84,18 @@ struct ao_adc {
 };
 #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
 /*
@@ -323,7 +335,7 @@ struct ao_cmds {
 #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;
@@ -475,7 +487,7 @@ ao_insert(void)
 #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);
@@ -670,6 +682,19 @@ int32(uint8_t *bytes, int off)
        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
@@ -694,12 +719,14 @@ ao_sleep(void *wchan)
                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;
                        }
@@ -829,6 +856,72 @@ ao_sleep(void *wchan)
                                }
                        }
 #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;
@@ -1007,7 +1100,7 @@ ao_sleep(void *wchan)
                        if (type != 'F' && !ao_flight_started)
                                continue;
 
-#if TELEMEGA || TELEMETRUM_V2
+#if TELEMEGA || TELEMETRUM_V2 || EASYMINI
                        (void) a;
                        (void) b;
 #else
index cf2cbd4fefce4e114fb8605cbdda3a2a5ff535cb..3646f000a450d2b65a8c1304520a7a84098f248c 100644 (file)
@@ -25,8 +25,8 @@ import java.io.*;
 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
@@ -152,7 +152,7 @@ public class TeleGPS
                        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) {
@@ -287,23 +287,30 @@ public class TeleGPS
                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) {
                }
@@ -612,40 +619,28 @@ public class TeleGPS
                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;
                }
index d24e7471eaeba1a54cb7eef73a58082ffda00572..7fc15ba991695fd5d2fa2705442591a78933d9c4 100644 (file)
@@ -23,8 +23,8 @@ import javax.swing.*;
 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 {
 
index dd3965b48960597ac70ca5525fc47abf9dfbb7d7..88ced19248298b0c80119826de3a3040eb0d2a83 100644 (file)
@@ -23,8 +23,8 @@ import java.awt.*;
 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
@@ -131,7 +131,7 @@ public class TeleGPSConfigUI
        }
 
        public double pyro_firing_time() {
-               return -1;
+               return AltosLib.MISSING;
        }
 
        boolean is_telemetrum() {
@@ -140,46 +140,46 @@ public class TeleGPSConfigUI
        }
 
        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");
@@ -675,7 +675,7 @@ public class TeleGPSConfigUI
        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();
@@ -712,21 +712,24 @@ public class TeleGPSConfigUI
        }
 
        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() {
@@ -734,45 +737,32 @@ public class TeleGPSConfigUI
        }
 
        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() {
@@ -780,12 +770,27 @@ public class TeleGPSConfigUI
        }
 
        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;
@@ -828,15 +833,15 @@ public class TeleGPSConfigUI
        }
 
        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)
@@ -859,87 +864,92 @@ public class TeleGPSConfigUI
        }
 
        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;
        }
 }
index a9c80dc00d537cd60cb87c892e72abfad257583f..fdf0e2019af56c66af8acadc61d2b56535791e1d 100644 (file)
@@ -22,8 +22,8 @@ import java.awt.*;
 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 {
 
@@ -31,7 +31,9 @@ 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;
 
@@ -130,11 +132,12 @@ public class TeleGPSDisplayThread extends Thread {
                }
 
                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() {
@@ -144,17 +147,17 @@ public class TeleGPSDisplayThread extends Thread {
 
        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;
        }
 
@@ -173,7 +176,6 @@ public class TeleGPSDisplayThread extends Thread {
                                                listener_state.running = false;
                                                break;
                                        }
-                                       reader.update(state);
                                        show_safely();
                                        told = tell();
                                        idle_thread.notice(told);
index 55ee370e33b2a4e1dda1e3b3a0dd629114d1f7a4..9d8c6bf5a4ae1444ae616d7c3cbf1f6c19ebdba0 100644 (file)
@@ -27,14 +27,14 @@ import javax.swing.*;
 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;
@@ -42,13 +42,33 @@ public class TeleGPSGraphUI extends AltosUIFrame
        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);
                }
        }
 
@@ -58,16 +78,35 @@ public class TeleGPSGraphUI extends AltosUIFrame
                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();
@@ -75,11 +114,14 @@ public class TeleGPSGraphUI extends AltosUIFrame
                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) {
index f4fa7216b979631c301d57a6fe420daca2a3dacf..383a0a4449f93c01df1fc58b83ba3eb43435fcb4 100644 (file)
@@ -22,8 +22,8 @@ import java.util.*;
 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 {
 
index 619523268e9268e8f8280e30016fb9e93e344591..58b3ae35950a5ba80a488d451d9276d043824bdc 100644 (file)
@@ -23,7 +23,7 @@ import java.awt.event.*;
 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
index 9ba0b7a59cabf42b7cee93b371750a530d0fd2e1..2117339486751156f07072c393cf60b5c2a95720 100644 (file)
@@ -22,8 +22,8 @@ import java.util.*;
 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 {
 
@@ -124,10 +124,11 @@ 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) {
@@ -137,9 +138,8 @@ public class TeleGPSState extends AltosUIFlightTab {
 
        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
index 5479f43a025927f762c4051aed61dff1b84185d6..e1be69a495717f156e1f5ea5d9a0c09e97eedc0e 100644 (file)
@@ -20,8 +20,8 @@ package org.altusmetrum.telegps;
 
 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;
@@ -75,11 +75,14 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
                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);
@@ -100,12 +103,13 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        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;
                        }
                }
 
@@ -126,12 +130,13 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
                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;
                        }
                }
 
index ac37af315b50b8abbc9695ddebd8807b1edfcad0..1b66d14215d495d5bd7fca352584c9d1e94b543d 100644 (file)
@@ -19,7 +19,7 @@
 package org.altusmetrum.telegps;
 
 import java.awt.event.*;
-import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altoslib_12.*;
 
 public class TeleGPSStatusUpdate implements ActionListener {