altoslib: Add EasyTimer-v2 support
authorKeith Packard <keithp@keithp.com>
Tue, 30 Jan 2024 02:39:27 +0000 (18:39 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 1 Feb 2024 01:50:19 +0000 (17:50 -0800)
Log parsing and idle monitor.

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosConfigData.java
altoslib/AltosEepromRecordSet.java
altoslib/AltosEepromRecordTimer.java [new file with mode: 0644]
altoslib/AltosIMU.java
altoslib/AltosIdleFetch.java
altoslib/AltosLib.java
altoslib/AltosMag.java
altoslib/AltosSensorEasyTimer2.java [new file with mode: 0644]
altoslib/Makefile.am

index ce34db7fd67ccc06b01dcb9a25c61dadba3421dc..17a81329e26971ef922c369ebe5c904cf98bb0ee 100644 (file)
@@ -223,6 +223,9 @@ public class AltosConfigData {
                case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
                        /* ADXL375 */
                        return -value;
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       /* BMI088 */
+                       return -value;
                default:
                        if (product.startsWith("EasyTimer-"))
                                return -value;
index 2c2089d7ebb90d42a5e583fb2f2ca08d4385fc2a..c42f78af1abf07e8df6284f2eb51dbdf3b7b8f4c 100644 (file)
@@ -111,6 +111,9 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
                        record = new AltosEepromRecordMotor(eeprom);
                        break;
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       record = new AltosEepromRecordTimer(eeprom);
+                       break;
                }
 
                ordered = new TreeSet<AltosEepromRecord>();
diff --git a/altoslib/AltosEepromRecordTimer.java b/altoslib/AltosEepromRecordTimer.java
new file mode 100644 (file)
index 0000000..91dcb6a
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright © 2024 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_14;
+
+public class AltosEepromRecordTimer extends AltosEepromRecord {
+       public static final int record_length = 32;
+
+       private int log_format;
+
+       private int imu_type() {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       return AltosIMU.imu_type_easytimer_v2;
+               default:
+                       return AltosLib.MISSING;
+               }
+       }
+
+       private int imu_model() {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       return AltosLib.model_bmi088;
+               }
+               return AltosLib.MISSING;
+       }
+
+       private boolean sensor_normalized() {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       return true;
+               }
+               return false;
+       }
+
+       private int mag_model() {
+               switch (log_format) {
+               case AltosLib.AO_LOG_FORMAT_EASYTIMER_2:
+                       return AltosLib.model_mmc5983;
+               }
+               return AltosLib.MISSING;
+       }
+
+       /* AO_LOG_FLIGHT elements */
+       private int flight() { return data16(0); }
+       private int ground_accel() { return data16(2); }
+       private int ground_pres() { return AltosLib.MISSING; }
+       private int ground_accel_along() { return data16(4); }
+       private int ground_accel_across() { return data16(6); }
+       private int ground_accel_through() { return data16(8); }
+       private int ground_roll() { return data32(12); }
+       private int ground_pitch() { return data32(16); }
+       private int ground_yaw() { return data32(20); }
+
+       /* AO_LOG_STATE elements */
+       private int state() { return data16(0); }
+       private int reason() { return data16(2); }
+
+       /* AO_LOG_SENSOR elements */
+
+       private int accel_along() { return data16(0); }
+       private int accel_across() { return data16(2); }
+       private int accel_through() { return data16(4); }
+       private int gyro_roll() { return data16(6); }
+       private int gyro_pitch() { return data16(8); }
+       private int gyro_yaw() { return data16(10); }
+       private int mag_along() { return data16(12); }
+       private int mag_across() { return data16(14); }
+       private int mag_through() { return data16(16); }
+
+       private int accel() { return -accel_along(); }
+
+       private int v_batt() { return data16(18); }
+       private int v_pbatt() { return data16(20); }
+       private int nsense() { return 2; }
+       private int sense(int i) { return data16(22 + i * 2); }
+       private int pyro() { return data16(26); }
+
+       public void provide_data(AltosDataListener listener, AltosCalData cal_data) {
+               super.provide_data(listener, cal_data);
+
+               cal_data.set_imu_type(imu_type());
+               cal_data.set_imu_model(imu_model());
+               cal_data.set_mag_model(mag_model());
+
+               switch (cmd()) {
+               case AltosLib.AO_LOG_FLIGHT:
+                       cal_data.set_flight(flight());
+                       cal_data.set_ground_accel(ground_accel());
+                       listener.set_accel_ground(cal_data.accel_along(ground_accel_along()),
+                                                 cal_data.accel_across(ground_accel_across()),
+                                                 cal_data.accel_through(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:
+                       listener.set_state(state());
+                       break;
+               case AltosLib.AO_LOG_SENSOR:
+                       AltosConfigData config_data = eeprom.config_data();
+
+                       int     accel_along = accel_along();
+                       int     accel_across = accel_across();
+                       int     accel_through = accel_through();
+                       int     gyro_roll = gyro_roll();
+                       int     gyro_pitch = gyro_pitch();
+                       int     gyro_yaw = gyro_yaw();
+
+                       int     mag_along = mag_along();
+                       int     mag_across = mag_across();
+                       int     mag_through = mag_through();
+
+                       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));
+
+                       listener.set_acceleration(cal_data.acceleration(accel()));
+
+                       listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+                       listener.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+
+                       int nsense = nsense();
+
+                       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));
+
+                       listener.set_igniter_voltage(voltages);
+                       listener.set_pyro_fired(pyro());
+                       break;
+               }
+       }
+
+       public AltosEepromRecord next() {
+               int     s = next_start();
+               if (s < 0)
+                       return null;
+               return new AltosEepromRecordTimer(eeprom, s);
+       }
+
+       public AltosEepromRecordTimer(AltosEeprom eeprom, int start) {
+               super(eeprom, start, record_length);
+               log_format = eeprom.config_data().log_format;
+       }
+
+       public AltosEepromRecordTimer(AltosEeprom eeprom) {
+               this(eeprom, 0);
+       }
+}
index b4ba5a563e08c3b3f768dd9cad3b837eae4249db..436d54cc7c0ffc93e8904d8c887dda764f313602 100644 (file)
@@ -73,11 +73,13 @@ public class AltosIMU implements Cloneable {
                case imu_type_easymega_v1:
                case imu_type_easymega_v2:
                        return counts_per_g_mpu;
-               case  imu_type_telemega_v4:
+               case imu_type_telemega_v4:
                case imu_type_easytimer_v1:
                        return counts_per_g_bmx;
                case imu_type_easymotor_v2:
                        return counts_per_g_adxl;
+               case imu_type_easytimer_v2:
+                       return counts_per_g_bmi088;
                }
 
                return AltosLib.MISSING;
@@ -251,6 +253,8 @@ public class AltosIMU implements Cloneable {
 
        public static final int imu_type_easymotor_v2 = 6;      /* ADXL375 (accel only) */
 
+       public static final int imu_type_easytimer_v2 = 7;      /* BMI088 */
+
        private int accel_across(int imu_type) {
 
                if (accel_across != AltosLib.MISSING)
@@ -391,6 +395,7 @@ public class AltosIMU implements Cloneable {
        private static boolean is_primary_accel(int imu_type) {
                switch (imu_type) {
                case imu_type_easytimer_v1:
+               case imu_type_easytimer_v2:
                        return true;
                default:
                        return false;
index 90f4f53e0374407ed1d124e61d055b843d418154..2b92d729c0809b9db23e3f7a4cfd73adbbb48dc7 100644 (file)
@@ -40,6 +40,7 @@ class AltosIdler {
        static final int        idle_adxl375 = 10;
        static final int        idle_adxl375_easymotor_v2 = 11;
        static final int        idle_imu = 12;
+       static final int        idle_imu_et_v2 = 13;
 
        static final int        idle_sensor_tm = 100;
        static final int        idle_sensor_metrum = 101;
@@ -54,6 +55,7 @@ class AltosIdler {
        static final int        idle_sensor_easytimer1 = 110;
        static final int        idle_sensor_easymotor2 = 111;
        static final int        idle_sensor_emini3 = 112;
+       static final int        idle_sensor_etimer2 = 113;
 
        public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException, TimeoutException, AltosUnknownProduct {
                for (int idler : idlers) {
@@ -79,6 +81,9 @@ class AltosIdler {
                        case idle_imu_et_v1:
                                AltosIMU.provide_data(listener, link, AltosIMU.imu_type_easytimer_v1);
                                break;
+                       case idle_imu_et_v2:
+                               AltosIMU.provide_data(listener, link, AltosIMU.imu_type_easytimer_v2);
+                               break;
                        case idle_imu:
                                AltosIMU.provide_data(listener, link, AltosLib.MISSING);
                                break;
@@ -267,6 +272,9 @@ public class AltosIdleFetch implements AltosDataProvider {
                new AltosIdler("EasyMotor-v2",
                               AltosIdler.idle_adxl375_easymotor_v2,
                               AltosIdler.idle_sensor_easymotor2),
+               new AltosIdler("EasyTimer-v2",
+                              AltosIdler.idle_imu_et_v2,
+                              AltosIdler.idle_sensor_easymotor2),
        };
 
        AltosLink               link;
index 5293badce58eee47e6fb109741e7caced1e2be04..7cd0e15c7830f9a9d6150936de7795e62f127278 100644 (file)
@@ -387,6 +387,7 @@ public class AltosLib {
        public static final int AO_LOG_FORMAT_EASYMOTOR = 20;
        public static final int AO_LOG_FORMAT_TELEMEGA_5 = 21;
        public static final int AO_LOG_FORMAT_TELEMEGA_6 = 22;
+       public static final int AO_LOG_FORMAT_EASYTIMER_2 = 23;
        public static final int AO_LOG_FORMAT_NONE = 127;
 
        public static final int model_mpu6000 = 0;
index c7f1ac1dfabba9bea522fc55d9c577cf0e9f20d3..6e11f3fd0a03a4bd4e7bee67fe142a0a0f682eb7 100644 (file)
@@ -45,6 +45,8 @@ public class AltosMag implements Cloneable {
                case AltosIMU.imu_type_telemega_v1_v2:
                case AltosIMU.imu_type_easymega_v1:
                        return counts_per_gauss_hmc5883;
+               case AltosIMU.imu_type_easytimer_v2:
+                       return counts_per_gauss_mmc5983;
                }
 
                return AltosIMU.counts_per_gauss(imu_type, mag_model);
diff --git a/altoslib/AltosSensorEasyTimer2.java b/altoslib/AltosSensorEasyTimer2.java
new file mode 100644 (file)
index 0000000..4d8102c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2020 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_14;
+
+import java.util.concurrent.TimeoutException;
+
+class AltosSensorEasyTimer2 {
+       int             tick;
+       int[]           sense;
+       int             v_batt;
+       int             v_pbatt;
+       int             temp;
+
+       public AltosSensorEasyTimer2() {
+               sense = new int[2];
+       }
+
+       public AltosSensorEasyTimer2(AltosLink link) throws InterruptedException, TimeoutException {
+               this();
+               String[] items = link.adc();
+               for (int i = 0; i < items.length;) {
+                       if (items[i].equals("tick:")) {
+                               tick = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       if (items[i].equals("A:")) {
+                               sense[0] = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       if (items[i].equals("B:")) {
+                               sense[1] = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       if (items[i].equals("batt:")) {
+                               v_batt = Integer.parseInt(items[i+1]);
+                               i += 2;
+                               continue;
+                       }
+                       i++;
+               }
+       }
+
+       static public void provide_data(AltosDataListener listener, AltosLink link) throws InterruptedException {
+               try {
+                       AltosSensorEasyTimer2   sensor_easytimer2 = new AltosSensorEasyTimer2(link);
+
+                       listener.set_battery_voltage(AltosConvert.easy_timer_voltage(sensor_easytimer2.v_batt));
+
+                       double[]        igniter_voltage = new double[2];
+                       for (int i = 0; i < 2; i++)
+                               igniter_voltage[i] = AltosConvert.easy_timer_voltage(sensor_easytimer2.sense[i]);
+                       listener.set_igniter_voltage(igniter_voltage);
+
+               } catch (TimeoutException te) {
+               }
+       }
+}
+
index a030e2cb773ff8939f8aba53eea16464dbe8cd69..7cb2ef6fbc82ca0dc2c07dd09411a34a1563a80c 100644 (file)
@@ -51,6 +51,7 @@ altoslib_JAVA = \
        AltosEepromRecordMicroPeak2.java \
        AltosEepromRecordMotor.java \
        AltosEepromRecordSet.java \
+       AltosEepromRecordTimer.java \
        AltosEepromChunk.java \
        AltosEepromDownload.java \
        AltosEepromMonitor.java \
@@ -108,6 +109,7 @@ altoslib_JAVA = \
        AltosSensorMM.java \
        AltosSensorEMini.java \
        AltosSensorEasyTimer1.java \
+       AltosSensorEasyTimer2.java \
        AltosSensorTM.java \
        AltosSensorTMini2.java \
        AltosSensorTMini3.java \