From 1747ab07dab6f4e977e0c3e83b57510cd668e369 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Thu, 19 Jul 2012 11:40:20 -0600 Subject: telescience: steal last adc channel for icp3 most recent value Make the ICP3 rpm counter use in ao_adc_avr.c optional Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 7 ++++++- src/avr/ao_pins.h | 2 ++ src/telepyro-v0.1/Makefile | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 3a262977..739a6d4a 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_pwmin.h" volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; @@ -93,9 +94,13 @@ ISR(ADC_vect) value = ADCL; value |= (ADCH << 8); ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = value; - if (++ao_adc_channel < NUM_ADC) + if (++ao_adc_channel < NUM_ADC - 1) ao_adc_start(); else { +#if HAS_ICP3_COUNT + /* steal last adc channel for pwm input */ + ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = ao_icp3_count; +#endif ADCSRA = ADCSRA_INIT; ao_data_ring[ao_data_head].tick = ao_time(); ao_data_head = ao_data_ring_next(ao_data_head); diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index bc423ff7..0f49db0b 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -47,6 +47,7 @@ #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 #define AVR_CLOCK 8000000UL + #define HAS_ICP3_COUNT 1 #define SPI_CS_PORT PORTE #define SPI_CS_DIR DDRE @@ -81,6 +82,7 @@ #define IS_COMPANION 1 #define HAS_ORIENT 0 #define ao_storage_pos_t uint16_t + #define HAS_ICP3_COUNT 0 #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile index 2ccd565f..6743ba66 100644 --- a/src/telepyro-v0.1/Makefile +++ b/src/telepyro-v0.1/Makefile @@ -96,7 +96,7 @@ ao_product.o: ao_product.c ao_product.h distclean: clean clean: - rm -f $(OBJ) + rm -f $(OBJ) $(PROG) $(PROG).hex rm -f ao_product.h install: -- cgit v1.2.3 From 1d7e6f5dcb29535cde9b7dfd6998d7889baf835b Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Tue, 17 Jul 2012 13:23:48 -0600 Subject: first work on PWM input to TeleScience, 'p' command displays timer 1 --- src/avr/ao_pwmin.c | 54 +++++++++++++++++++++++++++++++++++++++++++ src/avr/ao_pwmin.h | 18 +++++++++++++++ src/product/ao_telescience.c | 2 ++ src/telescience-v0.1/Makefile | 1 + 4 files changed, 75 insertions(+) create mode 100644 src/avr/ao_pwmin.c create mode 100644 src/avr/ao_pwmin.h diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c new file mode 100644 index 00000000..4d96404d --- /dev/null +++ b/src/avr/ao_pwmin.c @@ -0,0 +1,54 @@ +/* + * Copyright © 2012 Robert D. Garbee + * + * 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. + */ + +#include "ao.h" +#include "ao_pwmin.h" + +/* + * This code implements a PWM input using ICP3. + * + * The initial use is to measure wind speed in the ULA/Ball summer intern + * project payload developed at Challenger Middle School. + */ + +static void +ao_pwmin_display(void) __reentrant +{ + uint8_t lo = TCNT1L; + uint8_t hi = TCNT1H; + uint16_t value = (hi <<8) | lo; + + /* now display the value we read */ + printf("timer 1: %5u", value); + +} + +__code struct ao_cmds ao_pwmin_cmds[] = { + { ao_pwmin_display, "p\0PWM input" }, + { 0, NULL }, +}; + +void +ao_pwmin_init(void) +{ + /* do hardware setup here */ + /* set the spike filter bit in the TCCR3B register */ + + ao_cmd_register(&ao_pwmin_cmds[0]); +} + + diff --git a/src/avr/ao_pwmin.h b/src/avr/ao_pwmin.h new file mode 100644 index 00000000..bbab4ddc --- /dev/null +++ b/src/avr/ao_pwmin.h @@ -0,0 +1,18 @@ +/* + * Copyright © 2012 Robert D. Garbee + * + * 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. + */ + +void ao_pwmin_init(void); diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 45b6d40e..2d594d7f 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_pwmin.h" int main(void) @@ -34,6 +35,7 @@ main(void) ao_usb_init(); ao_adc_init(); ao_log_single_init(); + ao_pwmin_init(); ao_start_scheduler(); return 0; } diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index d24128ef..5542913d 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -53,6 +53,7 @@ ALTOS_SRC = \ ao_adc_avr.c \ ao_science_slave.c \ ao_spi_slave.c \ + ao_pwmin.c \ $(TELESCIENCE_STORAGE)\ $(TELESCIENCE_LOG) -- cgit v1.2.3 From ed5aa2329985ffbaba74514e0555f67fc378a8d8 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 13:41:27 -0600 Subject: Timer 3 working with slower clock and all 16 bits. --- src/avr/ao_pwmin.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 4d96404d..edcb1636 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,6 +25,8 @@ * project payload developed at Challenger Middle School. */ +volatile __data uint16_t ao_tick3_count; + static void ao_pwmin_display(void) __reentrant { @@ -32,10 +34,19 @@ ao_pwmin_display(void) __reentrant uint8_t hi = TCNT1H; uint16_t value = (hi <<8) | lo; + uint8_t lo3 = TCNT3L; + uint8_t hi3 = TCNT3H; + uint16_t value3 = (hi3 <<8) | lo3; + /* now display the value we read */ - printf("timer 1: %5u", value); + printf("timer 1: %5u %2x %2x\n", value, hi, lo); + printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); } +ISR(TIMER3_COMPA_vect) +{ + ++ao_tick3_count; +} __code struct ao_cmds ao_pwmin_cmds[] = { { ao_pwmin_display, "p\0PWM input" }, @@ -46,6 +57,18 @@ void ao_pwmin_init(void) { /* do hardware setup here */ + TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ + (0 << WGM30)); /* normal mode, OCR3A */ + TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ + (0 << ICES3) | /* input capture on falling edge (don't care) */ + (0 << WGM33) | /* normal mode, OCR3A */ + (0 << WGM32) | /* normal mode, OCR3A */ + (4 << CS30)); /* clk/256 from prescaler */ + + OCR3A = 1250; /* 8MHz clock */ + + TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ + /* set the spike filter bit in the TCCR3B register */ ao_cmd_register(&ao_pwmin_cmds[0]); -- cgit v1.2.3 From da7ac5e95575f6aa1d2514748869771b7686c0e1 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 14:24:05 -0600 Subject: ICP3 working --- src/avr/ao_pwmin.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index edcb1636..73a153b2 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,27 +25,20 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_tick3_count; +volatile __data uint16_t ao_icp3_count; static void ao_pwmin_display(void) __reentrant { - uint8_t lo = TCNT1L; - uint8_t hi = TCNT1H; - uint16_t value = (hi <<8) | lo; - - uint8_t lo3 = TCNT3L; - uint8_t hi3 = TCNT3H; - uint16_t value3 = (hi3 <<8) | lo3; - - /* now display the value we read */ - printf("timer 1: %5u %2x %2x\n", value, hi, lo); - printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); + /* display the most recent value */ + printf("icp 3: %5u\n", ao_icp3_count); } -ISR(TIMER3_COMPA_vect) +ISR(TIMER3_CAPT_vect) { - ++ao_tick3_count; + uint8_t lo = ICR3L; + uint8_t hi = ICR3H; + ao_icp3_count = (hi <<8) | lo; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -59,15 +52,15 @@ ao_pwmin_init(void) /* do hardware setup here */ TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ (0 << WGM30)); /* normal mode, OCR3A */ - TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ + TCCR3B = ((1 << ICNC3) | /* input capture noise canceler on */ (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ (4 << CS30)); /* clk/256 from prescaler */ - OCR3A = 1250; /* 8MHz clock */ + - TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ + TIMSK3 = (1 << ICIE3); /* Interrupt on input compare */ /* set the spike filter bit in the TCCR3B register */ -- cgit v1.2.3 From ac318c19594569532f1fa53b639eefa28d9b7c34 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 18:41:00 -0600 Subject: telescience: correctly calculating rate values with higher resolution --- src/avr/ao_pwmin.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 73a153b2..84397357 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,20 +25,40 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_icp3_count; +volatile __data uint16_t ao_icp3_count = 0; +volatile __data uint16_t ao_icp3_last = 0; + +uint16_t ao_icp3(void) +{ + uint16_t v; + ao_arch_critical( + v = ao_icp3_count; + ); + return v; +} static void ao_pwmin_display(void) __reentrant { /* display the most recent value */ - printf("icp 3: %5u\n", ao_icp3_count); + printf("icp 3: %5u\n", ao_icp3()); } + + ISR(TIMER3_CAPT_vect) { + uint8_t lo = ICR3L; uint8_t hi = ICR3H; - ao_icp3_count = (hi <<8) | lo; + uint16_t ao_icp3_this = (hi <<8) | lo; + + /* handling counter rollovers */ + if (ao_icp3_this >= ao_icp3_last) + ao_icp3_count = ao_icp3_this - ao_icp3_last; + else + ao_icp3_count = ao_icp3_this + (65536 - ao_icp3_last); + ao_icp3_last = ao_icp3_this; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -56,7 +76,7 @@ ao_pwmin_init(void) (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ - (4 << CS30)); /* clk/256 from prescaler */ + (3 << CS30)); /* clk/64 from prescaler */ -- cgit v1.2.3 From 14698c424f833dc6d2fb38f69f5f661804cf8303 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 16 Oct 2012 22:17:25 -0700 Subject: altos: Only enable PWM on telescience_pwm product Signed-off-by: Keith Packard --- src/avr/ao_pins.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 0f49db0b..0aa978e9 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -32,7 +32,7 @@ #define HAS_BEEP 0 #endif -#ifdef TELESCIENCE +#if defined(TELESCIENCE) || defined(TELESCIENCE_PWM) #define LEDS_AVAILABLE 0 #define HAS_USB 1 #define HAS_LOG 1 @@ -47,7 +47,11 @@ #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 #define AVR_CLOCK 8000000UL +#ifdef TELESCIENCE_PWM #define HAS_ICP3_COUNT 1 +#else + #define HAS_ICP3_COUNT 0 +#endif #define SPI_CS_PORT PORTE #define SPI_CS_DIR DDRE -- cgit v1.2.3 From f34f0ac7f355149446374a4c82dbf004919bc2dd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 16 Oct 2012 22:21:04 -0700 Subject: altos: Add telescience-pwm product Split out special PWM-sampling telescience product Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 2 +- src/avr/ao_pwmin.h | 2 + src/product/ao_telescience.c | 4 ++ src/telescience-pwm/.gitignore | 2 + src/telescience-pwm/Makefile | 116 +++++++++++++++++++++++++++++++++++++++++ src/telescience-v0.1/Makefile | 1 - 6 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 src/telescience-pwm/.gitignore create mode 100644 src/telescience-pwm/Makefile diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 739a6d4a..231512b2 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -94,7 +94,7 @@ ISR(ADC_vect) value = ADCL; value |= (ADCH << 8); ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = value; - if (++ao_adc_channel < NUM_ADC - 1) + if (++ao_adc_channel < NUM_ADC - HAS_ICP3_COUNT) ao_adc_start(); else { #if HAS_ICP3_COUNT diff --git a/src/avr/ao_pwmin.h b/src/avr/ao_pwmin.h index bbab4ddc..8097d399 100644 --- a/src/avr/ao_pwmin.h +++ b/src/avr/ao_pwmin.h @@ -16,3 +16,5 @@ */ void ao_pwmin_init(void); + +extern volatile __data uint16_t ao_icp3_count; diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 2d594d7f..d448d318 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -16,7 +16,9 @@ */ #include "ao.h" +#if HAS_ICP3_COUNT #include "ao_pwmin.h" +#endif int main(void) @@ -35,7 +37,9 @@ main(void) ao_usb_init(); ao_adc_init(); ao_log_single_init(); +#if HAS_ICP3_COUNT ao_pwmin_init(); +#endif ao_start_scheduler(); return 0; } diff --git a/src/telescience-pwm/.gitignore b/src/telescience-pwm/.gitignore new file mode 100644 index 00000000..dfccadf8 --- /dev/null +++ b/src/telescience-pwm/.gitignore @@ -0,0 +1,2 @@ +telescience-v0.1* +ao_product.h diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile new file mode 100644 index 00000000..43d77e2e --- /dev/null +++ b/src/telescience-pwm/Makefile @@ -0,0 +1,116 @@ +# +# AltOS build +# +# +vpath % ..:../core:../product:../drivers:../avr +vpath ao-make-product.5c ../util + +MCU=atmega32u4 +DUDECPUTYPE=m32u4 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_arch.h \ + ao_usb.h \ + ao_pins.h \ + ao_product.h + +# +# Common AltOS sources +# +TELESCIENCE_STORAGE= \ + ao_m25.c \ + ao_spi_usart.c \ + ao_storage.c + +TELESCIENCE_LOG= \ + ao_log_single.c \ + ao_log_telescience.c + +ALTOS_SRC = \ + ao_clock.c \ + ao_cmd.c \ + ao_mutex.c \ + ao_panic.c \ + ao_product.c \ + ao_stdio.c \ + ao_task.c \ + ao_timer.c \ + ao_led.c \ + ao_avr_stdio.c \ + ao_romconfig.c \ + ao_usb_avr.c \ + ao_adc_avr.c \ + ao_science_slave.c \ + ao_spi_slave.c \ + ao_pwmin.c \ + $(TELESCIENCE_STORAGE)\ + $(TELESCIENCE_LOG) + +PRODUCT=TeleScience-PWM +MCU=atmega32u4 +PRODUCT_DEF=-DTELESCIENCE -DTELESCIENCE_PWM +IDPRODUCT=0x0011 +CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR + +NICKLE=nickle + +PROG=telescience-pwm + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.o: ao_product.c ao_product.h + +%.o : %.c $(INC) + $(call quiet,CC) -c $(CFLAGS) $< + +distclean: clean + +clean: + rm -f *.o $(PROG) $(PROG).hex + rm -f ao_product.h + +install: + +uninstall: + +$(OBJ): ao_product.h $(INC) diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 5542913d..d24128ef 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -53,7 +53,6 @@ ALTOS_SRC = \ ao_adc_avr.c \ ao_science_slave.c \ ao_spi_slave.c \ - ao_pwmin.c \ $(TELESCIENCE_STORAGE)\ $(TELESCIENCE_LOG) -- cgit v1.2.3 From 3aba5eb5a75dff3e7c8778561c533903eacb110a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 16 Oct 2012 22:33:34 -0700 Subject: altos: Build telescience-pwm product when possible Signed-off-by: Keith Packard --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index b8828d46..1949e554 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,7 +27,7 @@ ifneq ($(shell which sdcc),) endif ifneq ($(shell which avr-gcc),) - SUBDIRS += telescience-v0.1 telepyro-v0.1 + SUBDIRS += telescience-v0.1 telescience-pwm telepyro-v0.1 endif ifneq ($(shell which arm-none-eabi-gcc),) -- cgit v1.2.3 From eea141b2f35722bad4cd31d9484d6d794646f815 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 13:01:03 -0700 Subject: altos/stm: Stop spewing clock out PA8 pin This was used to debug the clock bringup, but is not useful anymore, and probably a bad idea to boot. Signed-off-by: Keith Packard --- src/stm/ao_timer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 1132f748..f3011d3f 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -266,6 +266,7 @@ ao_clock_init(void) stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF); +#if DEBUG_THE_CLOCK /* Output SYSCLK on PA8 for measurments */ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); @@ -276,4 +277,5 @@ ao_clock_init(void) stm_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE); stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL); +#endif } -- cgit v1.2.3 From db0bbf76b5d739b5d7628bc9139dc8fecd501ac3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 13:02:05 -0700 Subject: altosui: Add new filename filters Allow the user to restrict filenames to telem, eeprom or mega files Signed-off-by: Keith Packard --- altosui/AltosDataChooser.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index 4d2f321e..a8a2ca49 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -70,6 +70,12 @@ public class AltosDataChooser extends JFileChooser { public AltosDataChooser(JFrame in_frame) { frame = in_frame; setDialogTitle("Select Flight Record File"); + setFileFilter(new FileNameExtensionFilter("TeleMetrum eeprom file", + "eeprom")); + setFileFilter(new FileNameExtensionFilter("Telemetry file", + "telem")); + setFileFilter(new FileNameExtensionFilter("MegaMetrum eeprom file", + "mega")); setFileFilter(new FileNameExtensionFilter("Flight data file", "telem", "eeprom", "mega")); setCurrentDirectory(AltosUIPreferences.logdir()); -- cgit v1.2.3 From 84a144e8b479550406323bc3b2cf89026b770746 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 13:02:40 -0700 Subject: altosui: Correct megametrum eeprom filename date Was fetching day-of-month from the year field Signed-off-by: Keith Packard --- altosui/AltosEepromDownload.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index a5e99749..21b46740 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -283,7 +283,7 @@ public class AltosEepromDownload implements Runnable { if (r.cmd == Altos.AO_LOG_GPS_TIME) { year = 2000 + r.data8(14); month = r.data8(15); - day = r.data8(14); + day = r.data8(16); want_file = true; } -- cgit v1.2.3 From 1f5a453cb4650fc97cc990a9e42242278c29cc04 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 13:42:00 -0700 Subject: altoslib: MegaMetrum eeprom never loses GPS date TeleMetrum had a firmware bug that would fail to record the GPS date and time correctly, that was hacked around in altosui, but isn't needed for MegaMetrum. Remove those hacks from the MM path. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 7 +--- altoslib/AltosEepromMegaIterable.java | 76 ----------------------------------- altoslib/AltosOrderedMegaRecord.java | 12 ------ 3 files changed, 1 insertion(+), 94 deletions(-) diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 26bacf8d..25a29fb2 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -66,12 +66,7 @@ public class AltosEepromMega { public int mag_x() { return data16(20); } public int mag_y() { return data16(22); } public int mag_z() { return data16(24); } - public int accel() { - int a = data16(26); - if (a != 0xffff) - return a; - return accel_y(); - } + public int accel() { return data16(26); } /* AO_LOG_VOLT elements */ public int v_batt() { return data16(0); } diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 1ab2fcc8..003bff44 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -347,40 +347,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { } } - /* - * Given an AO_LOG_GPS_TIME record with correct time, and one - * missing time, rewrite the missing time values with the good - * ones, assuming that the difference between them is 'diff' seconds - */ - void update_time(AltosOrderedMegaRecord good, AltosOrderedMegaRecord bad) { - - int diff = (bad.tick - good.tick + 50) / 100; - - int hour = (good.a & 0xff); - int minute = (good.a >> 8); - int second = (good.b & 0xff); - int flags = (good.b >> 8); - int seconds = hour * 3600 + minute * 60 + second; - - /* Make sure this looks like a good GPS value */ - if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) - flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); - flags |= AltosLib.AO_GPS_RUNNING; - flags |= AltosLib.AO_GPS_VALID; - - int new_seconds = seconds + diff; - if (new_seconds < 0) - new_seconds += 24 * 3600; - int new_second = (new_seconds % 60); - int new_minutes = (new_seconds / 60); - int new_minute = (new_minutes % 60); - int new_hours = (new_minutes / 60); - int new_hour = (new_hours % 24); - - bad.a = new_hour + (new_minute << 8); - bad.b = new_second + (flags << 8); - } - /* * Read the whole file, dumping records into a RB tree so * we can enumerate them in time order -- the eeprom data @@ -416,48 +382,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { continue; } - /* Two firmware bugs caused the loss of some GPS data. - * The flight date would never be recorded, and often - * the flight time would get overwritten by another - * record. Detect the loss of the GPS date and fix up the - * missing time records - */ - if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { - gps_date_record = record; - continue; - } - - /* go back and fix up any missing time values */ - if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { - last_gps_time = record; - if (missing_time) { - Iterator iterator = records.iterator(); - while (iterator.hasNext()) { - AltosOrderedMegaRecord old = iterator.next(); - if (old.cmd == AltosLib.AO_LOG_GPS_TIME && - old.a == -1 && old.b == -1) - { - update_time(record, old); - } - } - missing_time = false; - } - } - - if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { - if (last_gps_time == null || last_gps_time.tick != record.tick) { - AltosOrderedMegaRecord add_gps_time = new AltosOrderedMegaRecord(AltosLib.AO_LOG_GPS_TIME, - record.tick, - -1, -1, index-1); - if (last_gps_time != null) - update_time(last_gps_time, add_gps_time); - else - missing_time = true; - - records.add(add_gps_time); - record.index = index++; - } - } records.add(record); /* Bail after reading the 'landed' record; we're all done */ diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java index 05423dd9..3aaf7b5b 100644 --- a/altoslib/AltosOrderedMegaRecord.java +++ b/altoslib/AltosOrderedMegaRecord.java @@ -43,18 +43,6 @@ class AltosOrderedMegaRecord extends AltosEepromMega implements Comparable Date: Sun, 21 Oct 2012 14:10:32 -0700 Subject: altoslib: remove a couple of TM log record types from MM log parsing PRESSURE and DEPLOY log records don't occurin MM eeprom files. Signed-off-by: Keith Packard --- altoslib/AltosEepromMegaIterable.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 003bff44..50f9d33d 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -106,15 +106,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { eeprom.sensor_tick = record.tick; has_accel = true; break; - case AltosLib.AO_LOG_PRESSURE: - state.pres = record.b; - state.flight_pres = state.pres; - if (eeprom.n_pad_samples == 0) { - eeprom.n_pad_samples++; - state.ground_pres = state.pres; - } - eeprom.seen |= seen_sensor; - break; case AltosLib.AO_LOG_TEMP_VOLT: state.v_batt = record.v_batt(); state.v_pyro = record.v_pbatt(); @@ -122,14 +113,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { state.sense[i] = record.sense(i); eeprom.seen |= seen_temp_volt; break; -// -// case AltosLib.AO_LOG_DEPLOY: -// state.drogue = record.a; -// state.main = record.b; -// eeprom.seen |= seen_deploy; -// has_ignite = true; -// break; - case AltosLib.AO_LOG_STATE: state.state = record.state(); break; -- cgit v1.2.3 From dec2e455935a71dec13b84bb886252b7f4a1a641 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 14:11:07 -0700 Subject: altoslib: Compute accelerometer speed from megametrum eeprom data Duplicates code from the TM eeprom state tracking code. Signed-off-by: Keith Packard --- altoslib/AltosRecordMM.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 5f952f7a..63b37f82 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -111,7 +111,11 @@ public class AltosRecordMM extends AltosRecord { } public double accel_speed() { - return speed; + if (speed != MISSING) + return speed; + if (flight_vel == MISSING) + return MISSING; + return flight_vel / (accel_counts_per_mss() * 100.0); } public void copy (AltosRecordMM old) { -- cgit v1.2.3 From 7894c27b2b2c3c46a7c107c8acd5977830f006cf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 16:13:14 -0700 Subject: altoslib: Move computed state from AltosRecord to AltosState Make AltosRecord simply track the raw data and have AltosState hold all computed values, including cross-packet averages and computed speeds. Signed-off-by: Keith Packard --- altoslib/AltosIdleMonitor.java | 2 +- altoslib/AltosRecord.java | 99 +++++++++++------------------- altoslib/AltosRecordMM.java | 18 +----- altoslib/AltosRecordTM.java | 21 +------ altoslib/AltosState.java | 69 ++++++++++++++++----- altoslib/AltosTelemetryRecordLegacy.java | 24 ++++---- altoslib/AltosTelemetryRecordMegaData.java | 6 +- altoslib/AltosTelemetryRecordRaw.java | 2 +- altoslib/AltosTelemetryRecordSensor.java | 6 +- altoslib/Makefile.am | 1 + altosui/AltosAscent.java | 2 +- altosui/AltosCSV.java | 8 +-- altosui/AltosDataPoint.java | 5 +- altosui/AltosDataPointReader.java | 47 +++++++------- altosui/AltosDescent.java | 2 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosFlightStats.java | 10 +-- altosui/AltosGraphUI.java | 7 +-- altosui/AltosInfoTable.java | 4 +- altosui/AltosKML.java | 2 +- altosui/AltosLanded.java | 2 +- 21 files changed, 153 insertions(+), 186 deletions(-) diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 2c4965ff..07d8930d 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -97,7 +97,7 @@ public class AltosIdleMonitor extends Thread { else if (has_sensor_mm(config_data)) record = sensor_mm(config_data); else - record = new AltosRecord(); + record = new AltosRecordNone(); if (has_gps(config_data)) gps = new AltosGPSQuery(link, config_data); diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 8bab1d0c..09169515 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosLib; -public class AltosRecord implements Comparable , Cloneable { +public abstract class AltosRecord implements Comparable , Cloneable { public static final int seen_flight = 1; public static final int seen_sensor = 2; @@ -43,11 +43,6 @@ public class AltosRecord implements Comparable , Cloneable { public int state; public int tick; - /* Current flight dynamic state */ - public double acceleration; /* m/s² */ - public double speed; /* m/s */ - public double height; /* m */ - public AltosGPS gps; public boolean new_gps; @@ -63,6 +58,11 @@ public class AltosRecord implements Comparable , Cloneable { public AltosRecordCompanion companion; + /* Telemetry sources have these values recorded from the flight computer */ + public double kalman_height; + public double kalman_speed; + public double kalman_acceleration; + /* * Abstract methods that convert record data * to standard units: @@ -75,76 +75,48 @@ public class AltosRecord implements Comparable , Cloneable { * temperature: °C */ - public double raw_pressure() { return MISSING; } - - public double filtered_pressure() { return MISSING; } - - public double ground_pressure() { return MISSING; } - - public double battery_voltage() { return MISSING; } + abstract public double pressure(); + abstract public double ground_pressure(); + abstract public double acceleration(); - public double main_voltage() { return MISSING; } + public double altitude() { + double p = pressure(); - public double drogue_voltage() { return MISSING; } - - public double temperature() { return MISSING; } - - public double acceleration() { return MISSING; } - - public double accel_speed() { return MISSING; } - - public AltosIMU imu() { return null; } - - public AltosMag mag() { return null; } - - /* - * Convert various pressure values to altitude - */ - - public double raw_altitude() { - double p = raw_pressure(); if (p == MISSING) return MISSING; return AltosConvert.pressure_to_altitude(p); } public double ground_altitude() { - double p = ground_pressure(); + double p = ground_pressure(); + if (p == MISSING) return MISSING; return AltosConvert.pressure_to_altitude(p); } - public double filtered_altitude() { - double ga = ground_altitude(); - if (height != MISSING && ga != MISSING) - return height + ga; + public double height() { + double g = ground_altitude(); + double a = altitude(); - double p = filtered_pressure(); - if (p == MISSING) - return raw_altitude(); - return AltosConvert.pressure_to_altitude(p); + if (g == MISSING) + return MISSING; + if (a == MISSING) + return MISSING; + return a - g; } - public double filtered_height() { - if (height != MISSING) - return height; + public double battery_voltage() { return MISSING; } - double f = filtered_altitude(); - double g = ground_altitude(); - if (f == MISSING || g == MISSING) - return MISSING; - return f - g; - } + public double main_voltage() { return MISSING; } - public double raw_height() { - double r = raw_altitude(); - double g = ground_altitude(); + public double drogue_voltage() { return MISSING; } - if (r == MISSING || g == MISSING) - return height; - return r - g; - } + public double temperature() { return MISSING; } + + public AltosIMU imu() { return null; } + + public AltosMag mag() { return null; } public String state() { return AltosLib.state_name(state); @@ -164,12 +136,12 @@ public class AltosRecord implements Comparable , Cloneable { status = old.status; state = old.state; tick = old.tick; - acceleration = old.acceleration; - speed = old.speed; - height = old.height; gps = new AltosGPS(old.gps); new_gps = old.new_gps; companion = old.companion; + kalman_acceleration = old.kalman_acceleration; + kalman_speed = old.kalman_speed; + kalman_height = old.kalman_height; } public AltosRecord clone() { @@ -192,11 +164,12 @@ public class AltosRecord implements Comparable , Cloneable { status = 0; state = AltosLib.ao_flight_startup; tick = 0; - acceleration = MISSING; - speed = MISSING; - height = MISSING; gps = new AltosGPS(); new_gps = false; companion = null; + + kalman_acceleration = MISSING; + kalman_speed = MISSING; + kalman_height = MISSING; } } diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 63b37f82..9f529234 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -19,6 +19,7 @@ package org.altusmetrum.AltosLib; public class AltosRecordMM extends AltosRecord { + /* Sensor values */ public int accel; public int pres; public int temp; @@ -45,16 +46,12 @@ public class AltosRecordMM extends AltosRecord { return raw / 4095.0; } - public double raw_pressure() { + public double pressure() { if (pres != MISSING) return pres; return MISSING; } - public double filtered_pressure() { - return raw_pressure(); - } - public double ground_pressure() { if (ground_pres != MISSING) return ground_pres; @@ -98,9 +95,6 @@ public class AltosRecordMM extends AltosRecord { } public double acceleration() { - if (acceleration != MISSING) - return acceleration; - if (ground_accel == MISSING || accel == MISSING) return MISSING; @@ -110,14 +104,6 @@ public class AltosRecordMM extends AltosRecord { return (ground_accel - accel) / accel_counts_per_mss(); } - public double accel_speed() { - if (speed != MISSING) - return speed; - if (flight_vel == MISSING) - return MISSING; - return flight_vel / (accel_counts_per_mss() * 100.0); - } - public void copy (AltosRecordMM old) { super.copy(old); diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java index 37accef6..9530be31 100644 --- a/altoslib/AltosRecordTM.java +++ b/altoslib/AltosRecordTM.java @@ -18,6 +18,8 @@ package org.altusmetrum.AltosLib; public class AltosRecordTM extends AltosRecord { + + /* Sensor values */ public int accel; public int pres; public int temp; @@ -57,18 +59,12 @@ public class AltosRecordTM extends AltosRecord { return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; } - public double raw_pressure() { + public double pressure() { if (pres == MISSING) return MISSING; return barometer_to_pressure(pres); } - public double filtered_pressure() { - if (flight_pres == MISSING) - return MISSING; - return barometer_to_pressure(flight_pres); - } - public double ground_pressure() { if (ground_pres == MISSING) return MISSING; @@ -121,22 +117,11 @@ public class AltosRecordTM extends AltosRecord { } public double acceleration() { - if (acceleration != MISSING) - return acceleration; - if (ground_accel == MISSING || accel == MISSING) return MISSING; return (ground_accel - accel) / accel_counts_per_mss(); } - public double accel_speed() { - if (speed != MISSING) - return speed; - if (flight_vel == MISSING) - return MISSING; - return flight_vel / (accel_counts_per_mss() * 100.0); - } - public void copy(AltosRecordTM old) { super.copy(old); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 2e4d8870..f28dd1c6 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -40,17 +40,17 @@ public class AltosState { public double ground_altitude; public double altitude; public double height; - public double speed; public double acceleration; public double battery; public double temperature; public double main_sense; public double drogue_sense; + public double accel_speed; public double baro_speed; public double max_height; public double max_acceleration; - public double max_speed; + public double max_accel_speed; public double max_baro_speed; public AltosGPS gps; @@ -76,20 +76,39 @@ public class AltosState { public int speak_tick; public double speak_altitude; - public void init (AltosRecord cur, AltosState prev_state) { - //int i; - //AltosRecord prev; + public double speed() { + if (ascent) + return accel_speed; + else + return baro_speed; + } + + public double max_speed() { + if (max_accel_speed != 0) + return max_accel_speed; + return max_baro_speed; + } + public void init (AltosRecord cur, AltosState prev_state) { data = cur; ground_altitude = data.ground_altitude(); - altitude = data.raw_altitude(); - height = data.filtered_height(); + + altitude = data.altitude(); + + if (data.kalman_height != AltosRecord.MISSING) + height = data.kalman_height; + else { + if (prev_state != null) + height = (prev_state.height * 15 + altitude - ground_altitude) / 16.0; + } report_time = System.currentTimeMillis(); - acceleration = data.acceleration(); - speed = data.accel_speed(); + if (data.kalman_acceleration != AltosRecord.MISSING) + acceleration = data.kalman_acceleration; + else + acceleration = data.acceleration(); temperature = data.temperature(); drogue_sense = data.drogue_voltage(); main_sense = data.main_voltage(); @@ -108,7 +127,7 @@ public class AltosState { pad_alt = prev_state.pad_alt; max_height = prev_state.max_height; max_acceleration = prev_state.max_acceleration; - max_speed = prev_state.max_speed; + max_accel_speed = prev_state.max_accel_speed; max_baro_speed = prev_state.max_baro_speed; imu = prev_state.imu; mag = prev_state.mag; @@ -119,23 +138,39 @@ public class AltosState { time_change = (tick - prev_state.tick) / 100.0; - /* compute barometric speed */ + if (data.kalman_speed != AltosRecord.MISSING) { + baro_speed = accel_speed = data.kalman_speed; + } else { + /* compute barometric speed */ - double height_change = height - prev_state.height; - if (data.speed != AltosRecord.MISSING) - baro_speed = data.speed; - else { + double height_change = height - prev_state.height; if (time_change > 0) baro_speed = (prev_state.baro_speed * 3 + (height_change / time_change)) / 4.0; else baro_speed = prev_state.baro_speed; + + if (acceleration == AltosRecord.MISSING) { + /* Fill in mising acceleration value */ + accel_speed = baro_speed; + if (time_change > 0) + acceleration = (accel_speed - prev_state.accel_speed) / time_change; + else + acceleration = prev_state.acceleration; + } else { + /* compute accelerometer speed */ + accel_speed = prev_state.accel_speed + acceleration * time_change; + } } + } else { npad = 0; ngps = 0; gps = null; baro_speed = 0; + accel_speed = 0; time_change = 0; + if (acceleration == AltosRecord.MISSING) + acceleration = 0; } time = tick / 100.0; @@ -180,8 +215,8 @@ public class AltosState { /* Only look at accelerometer data under boost */ if (boost && acceleration > max_acceleration && acceleration != AltosRecord.MISSING) max_acceleration = acceleration; - if (boost && speed > max_speed && speed != AltosRecord.MISSING) - max_speed = speed; + if (boost && accel_speed > max_accel_speed && accel_speed != AltosRecord.MISSING) + max_accel_speed = accel_speed; if (boost && baro_speed > max_baro_speed && baro_speed != AltosRecord.MISSING) max_baro_speed = baro_speed; diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java index 21176069..43189794 100644 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ b/altoslib/AltosTelemetryRecordLegacy.java @@ -257,9 +257,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); /* flight computer values */ - record.acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - record.speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - record.height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); + record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); + record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); @@ -334,9 +334,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { /* Old TeleDongle code with kalman-reporting TeleMetrum code */ if ((record.flight_vel & 0xffff0000) == 0x80000000) { - record.speed = ((short) record.flight_vel) / 16.0; - record.acceleration = record.flight_accel / 16.0; - record.height = record.flight_pres; + record.kalman_speed = ((short) record.flight_vel) / 16.0; + record.kalman_acceleration = record.flight_accel / 16.0; + record.kalman_height = record.flight_pres; record.flight_vel = AltosRecord.MISSING; record.flight_pres = AltosRecord.MISSING; record.flight_accel = AltosRecord.MISSING; @@ -455,9 +455,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.accel_minus_g = int16(19); if (uint16(11) == 0x8000) { - record.acceleration = int16(5); - record.speed = int16(9); - record.height = int16(13); + record.kalman_acceleration = int16(5); + record.kalman_speed = int16(9); + record.kalman_height = int16(13); record.flight_accel = AltosRecord.MISSING; record.flight_vel = AltosRecord.MISSING; record.flight_pres = AltosRecord.MISSING; @@ -465,9 +465,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.flight_accel = int16(5); record.flight_vel = uint32(9); record.flight_pres = int16(13); - record.acceleration = AltosRecord.MISSING; - record.speed = AltosRecord.MISSING; - record.height = AltosRecord.MISSING; + record.kalman_acceleration = AltosRecord.MISSING; + record.kalman_speed = AltosRecord.MISSING; + record.kalman_height = AltosRecord.MISSING; } record.gps = null; diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java index 8f55d238..16a7b80c 100644 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ b/altoslib/AltosTelemetryRecordMegaData.java @@ -83,9 +83,9 @@ public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { next.accel_plus_g = accel_plus_g; next.accel_minus_g = accel_minus_g; - next.acceleration = acceleration / 16.0; - next.speed = speed / 16.0; - next.height = height; + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; next.seen |= AltosRecord.seen_flight | AltosRecord.seen_temp_volt; diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java index fbb373d5..c21da6fc 100644 --- a/altoslib/AltosTelemetryRecordRaw.java +++ b/altoslib/AltosTelemetryRecordRaw.java @@ -65,7 +65,7 @@ public class AltosTelemetryRecordRaw extends AltosTelemetryRecord { if (previous != null) next = previous.clone(); else - next = new AltosRecord(); + next = new AltosRecordNone(); next.serial = serial; next.tick = tick; return next; diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java index 319a91b3..f1fc156c 100644 --- a/altoslib/AltosTelemetryRecordSensor.java +++ b/altoslib/AltosTelemetryRecordSensor.java @@ -86,9 +86,9 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.main = AltosRecord.MISSING; } - next.acceleration = acceleration / 16.0; - next.speed = speed / 16.0; - next.height = height; + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; next.ground_pres = ground_pres; if (type == packet_type_TM_sensor) { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index b56d8af1..f04c10c6 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -46,6 +46,7 @@ AltosLib_JAVA = \ $(SRC)/AltosRecordCompanion.java \ $(SRC)/AltosRecordIterable.java \ $(SRC)/AltosRecord.java \ + $(SRC)/AltosRecordNone.java \ $(SRC)/AltosRecordTM.java \ $(SRC)/AltosRecordMM.java \ $(SRC)/AltosReplayReader.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 007c74ec..a05c4404 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -251,7 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, int crc_errors) { - double speed = state.speed; + double speed = state.accel_speed; if (!state.ascent) speed = state.baro_speed; show(AltosConvert.speed, speed); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index f8cc1ed6..1c929a7c 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -128,10 +128,10 @@ public class AltosCSV implements AltosWriter { void write_basic(AltosRecord record) { out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", record.acceleration(), - record.raw_pressure(), - record.raw_altitude(), - record.raw_height(), - record.accel_speed(), + record.pressure(), + record.altitude(), + record.height(), + state.accel_speed, state.baro_speed, record.temperature(), record.battery_voltage(), diff --git a/altosui/AltosDataPoint.java b/altosui/AltosDataPoint.java index 5e077320..4956e9f3 100644 --- a/altosui/AltosDataPoint.java +++ b/altosui/AltosDataPoint.java @@ -16,11 +16,8 @@ interface AltosDataPoint { String state_name(); double acceleration(); - double pressure(); - double altitude(); double height(); - double accel_speed(); - double baro_speed(); + double speed(); double temperature(); double battery_voltage(); double drogue_voltage(); diff --git a/altosui/AltosDataPointReader.java b/altosui/AltosDataPointReader.java index 2316cf97..88df081f 100644 --- a/altosui/AltosDataPointReader.java +++ b/altosui/AltosDataPointReader.java @@ -12,7 +12,6 @@ import org.altusmetrum.AltosLib.*; class AltosDataPointReader implements Iterable { Iterator iter; AltosState state; - AltosRecord record; boolean has_gps; boolean has_accel; boolean has_ignite; @@ -22,7 +21,7 @@ class AltosDataPointReader implements Iterable { public AltosDataPointReader(AltosRecordIterable reader) { this.iter = reader.iterator(); this.state = null; - has_accel = reader.has_accel(); + has_accel = true; has_gps = reader.has_gps(); has_ignite = reader.has_ignite(); } @@ -30,35 +29,31 @@ class AltosDataPointReader implements Iterable { private void read_next_record() throws NoSuchElementException { - record = iter.next(); - state = new AltosState(record, state); + state = new AltosState(iter.next(), state); } private AltosDataPoint current_dp() { - assert this.record != null; + assert this.state != null; return new AltosDataPoint() { - public int version() { return record.version; } - public int serial() { return record.serial; } - public int flight() { return record.flight; } - public String callsign() { return record.callsign; } - public double time() { return record.time; } - public double rssi() { return record.rssi; } + public int version() { return state.data.version; } + public int serial() { return state.data.serial; } + public int flight() { return state.data.flight; } + public String callsign() { return state.data.callsign; } + public double time() { return state.data.time; } + public double rssi() { return state.data.rssi; } - public int state() { return record.state; } - public String state_name() { return record.state(); } + public int state() { return state.state; } + public String state_name() { return state.data.state(); } - public double acceleration() { return record.acceleration(); } - public double pressure() { return record.raw_pressure(); } - public double altitude() { return record.raw_altitude(); } - public double height() { return record.raw_height(); } - public double accel_speed() { return record.accel_speed(); } - public double baro_speed() { return state.baro_speed; } - public double temperature() { return record.temperature(); } - public double battery_voltage() { return record.battery_voltage(); } - public double drogue_voltage() { return record.drogue_voltage(); } - public double main_voltage() { return record.main_voltage(); } - public boolean has_accel() { return has_accel; } + public double acceleration() { return state.acceleration; } + public double height() { return state.height; } + public double speed() { return state.speed(); } + public double temperature() { return state.temperature; } + public double battery_voltage() { return state.battery; } + public double drogue_voltage() { return state.drogue_sense; } + public double main_voltage() { return state.main_sense; } + public boolean has_accel() { return true; } // return state.acceleration != AltosRecord.MISSING; } }; } @@ -68,14 +63,14 @@ class AltosDataPointReader implements Iterable { throw new UnsupportedOperationException(); } public boolean hasNext() { - if (record != null && record.state == Altos.ao_flight_landed) + if (state != null && state.state == Altos.ao_flight_landed) return false; return iter.hasNext(); } public AltosDataPoint next() { do { read_next_record(); - } while (record.time < -1.0 && hasNext()); + } while (state.data.time < -1.0 && hasNext()); return current_dp(); } }; diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index a71cdc10..2ea7cbfa 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -256,7 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, int crc_errors) { - double speed = state.speed; + double speed = state.accel_speed; if (!state.ascent) speed = state.baro_speed; show(AltosConvert.speed, speed); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index f7a1d03e..1ba70c7e 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -197,7 +197,7 @@ public class AltosDisplayThread extends Thread { if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_speed + 0.5)); + AltosConvert.speed.say_units(state.max_accel_speed + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index e48cb608..1653ca57 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -24,7 +24,7 @@ public class AltosFlightStats { double max_height; double max_speed; double max_acceleration; - double[] state_speed = new double[Altos.ao_flight_invalid + 1]; + double[] state_accel_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_baro_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_accel = new double[Altos.ao_flight_invalid + 1]; int[] state_count = new int[Altos.ao_flight_invalid + 1]; @@ -123,7 +123,7 @@ public class AltosFlightStats { } } state_accel[state.state] += state.acceleration; - state_speed[state.state] += state.speed; + state_accel_speed[state.state] += state.accel_speed; state_baro_speed[state.state] += state.baro_speed; state_count[state.state]++; if (state_start[state.state] == 0.0) @@ -131,8 +131,8 @@ public class AltosFlightStats { if (state_end[state.state] < state.time) state_end[state.state] = state.time; max_height = state.max_height; - if (state.max_speed != 0) - max_speed = state.max_speed; + if (state.max_accel_speed != 0) + max_speed = state.max_accel_speed; else max_speed = state.max_baro_speed; max_acceleration = state.max_acceleration; @@ -140,7 +140,7 @@ public class AltosFlightStats { } for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { if (state_count[s] > 0) { - state_speed[s] /= state_count[s]; + state_accel_speed[s] /= state_count[s]; state_baro_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; } diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index cb8e3d20..f59f70ba 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -40,12 +40,7 @@ public class AltosGraphUI extends AltosFrame AltosGraphTime.Element speed = new AltosGraphTime.TimeSeries(String.format("Speed (%s)", AltosConvert.speed.show_units()), "Vertical Speed", green) { public void gotTimeData(double time, AltosDataPoint d) { - double speed; - if (d.state() < Altos.ao_flight_drogue && d.has_accel()) { - speed = d.accel_speed(); - } else { - speed = d.baro_speed(); - } + double speed = d.speed(); if (speed != AltosRecord.MISSING) series.add(time, AltosConvert.speed.value(speed)); } diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 86e02ab1..11d1b0c1 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -114,8 +114,8 @@ public class AltosInfoTable extends JTable { info_add_row(0, "Max height", "%6.0f m", state.max_height); info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration); info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration); - info_add_row(0, "Speed", "%8.1f m/s", state.ascent ? state.speed : state.baro_speed); - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); + info_add_row(0, "Speed", "%8.1f m/s", state.speed()); + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_accel_speed); info_add_row(0, "Temperature", "%9.2f °C", state.temperature); info_add_row(0, "Battery", "%9.2f V", state.battery); if (state.drogue_sense != AltosRecord.MISSING) diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 57339b19..281638bf 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -109,7 +109,7 @@ public class AltosKML implements AltosWriter { AltosGPS gps = record.gps; out.printf(kml_coord_fmt, gps.lon, gps.lat, - record.filtered_altitude(), (double) gps.alt, + record.altitude(), (double) gps.alt, record.time, gps.nsat); } diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 57c2d476..0111a08a 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -173,7 +173,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Speed extends LandedValue { void show (AltosState state, int crc_errors) { - show(AltosConvert.speed, state.max_speed); + show(AltosConvert.speed, state.max_speed()); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Maximum Speed"); -- cgit v1.2.3 From 89c621be35e1a6d3394b0e143391fcf2d94d7b41 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 16:53:23 -0700 Subject: altoslib: Parse GPS .mega file entries for reply/graphing The .mega file parsing had a pile of leftovers from when it was cloned from the .eeprom file parsing code. Replace all of that with the right parsing bits so that GPS data will be presented correctly. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 52 +++++++++++------ altoslib/AltosEepromMegaIterable.java | 102 ++++++++++++++-------------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 25a29fb2..af4f8aca 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -24,7 +24,7 @@ public class AltosEepromMega { public int tick; public boolean valid; public String data; - public int a, b; + public int config_a, config_b; public int data8[]; @@ -74,6 +74,22 @@ public class AltosEepromMega { public int nsense() { return data16(4); } public int sense(int i) { return data16(6 + i * 2); } + /* AO_LOG_GPS_TIME elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + public int hour() { return data8(10); } + public int minute() { return data8(11); } + public int second() { return data8(12); } + public int flags() { return data8(13); } + public int year() { return data8(14); } + public int month() { return data8(15); } + public int day() { return data8(16); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data16(0); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException { cmd = chunk.data(start); @@ -121,26 +137,26 @@ public class AltosEepromMega { data = tokens[2]; } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Callsign:")) { cmd = AltosLib.AO_LOG_CALLSIGN; data = tokens[1].replaceAll("\"",""); } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); + config_a = Integer.parseInt(tokens[3]); } else if (tokens[0].equals("manufacturer")) { cmd = AltosLib.AO_LOG_MANUFACTURER; data = tokens[1]; @@ -149,38 +165,38 @@ public class AltosEepromMega { data = tokens[1]; } else if (tokens[0].equals("serial-number")) { cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); + config_a = Integer.parseInt(tokens[1]); } else if (tokens[0].equals("log-format")) { cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); + config_a = Integer.parseInt(tokens[1]); } else if (tokens[0].equals("software-version")) { cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; data = tokens[1]; } else if (tokens[0].equals("ms5607")) { if (tokens[1].equals("reserved:")) { cmd = AltosLib.AO_LOG_BARO_RESERVED; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("sens:")) { cmd = AltosLib.AO_LOG_BARO_SENS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("off:")) { cmd = AltosLib.AO_LOG_BARO_OFF; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tcs:")) { cmd = AltosLib.AO_LOG_BARO_TCS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tco:")) { cmd = AltosLib.AO_LOG_BARO_TCO; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tref:")) { cmd = AltosLib.AO_LOG_BARO_TREF; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tempsens:")) { cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("crc:")) { cmd = AltosLib.AO_LOG_BARO_CRC; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else { cmd = AltosLib.AO_LOG_INVALID; data = line; diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 50f9d33d..16809089 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -109,7 +109,7 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { case AltosLib.AO_LOG_TEMP_VOLT: state.v_batt = record.v_batt(); state.v_pyro = record.v_pbatt(); - for (int i = 0; i < AltosRecordMM.num_sense; i++) + for (int i = 0; i < record.nsense(); i++) state.sense[i] = record.sense(i); eeprom.seen |= seen_temp_volt; break; @@ -118,51 +118,35 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { break; case AltosLib.AO_LOG_GPS_TIME: eeprom.gps_tick = state.tick; - AltosGPS old = state.gps; state.gps = new AltosGPS(); - /* GPS date doesn't get repeated through the file */ - if (old != null) { - state.gps.year = old.year; - state.gps.month = old.month; - state.gps.day = old.day; - } - state.gps.hour = (record.a & 0xff); - state.gps.minute = (record.a >> 8); - state.gps.second = (record.b & 0xff); + state.gps.lat = record.latitude() / 1e7; + state.gps.lon = record.longitude() / 1e7; + state.gps.alt = record.altitude(); + state.gps.year = record.year() + 2000; + state.gps.month = record.month(); + state.gps.day = record.day(); + + state.gps.hour = record.hour(); + state.gps.minute = record.minute(); + state.gps.second = record.second(); - int flags = (record.b >> 8); + int flags = record.flags(); state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT; state.new_gps = true; has_gps = true; - break; - case AltosLib.AO_LOG_GPS_LAT: - int lat32 = record.a | (record.b << 16); - state.gps.lat = (double) lat32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_LON: - int lon32 = record.a | (record.b << 16); - state.gps.lon = (double) lon32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_ALT: - state.gps.alt = record.a; + eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; break; case AltosLib.AO_LOG_GPS_SAT: if (state.tick == eeprom.gps_tick) { - int svid = record.a; - int c_n0 = record.b >> 8; - state.gps.add_sat(svid, c_n0); + int nsat = record.nsat(); + for (int i = 0; i < nsat; i++) + state.gps.add_sat(record.svid(i), record.c_n(i)); } break; - case AltosLib.AO_LOG_GPS_DATE: - state.gps.year = (record.a & 0xff) + 2000; - state.gps.month = record.a >> 8; - state.gps.day = record.b & 0xff; - break; - case AltosLib.AO_LOG_CONFIG_VERSION: break; case AltosLib.AO_LOG_MAIN_DEPLOY: @@ -175,8 +159,8 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { state.callsign = record.data; break; case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.a; - state.accel_minus_g = record.b; + state.accel_plus_g = record.config_a; + state.accel_minus_g = record.config_b; break; case AltosLib.AO_LOG_RADIO_CAL: break; @@ -185,33 +169,33 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { case AltosLib.AO_LOG_PRODUCT: break; case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.a; + state.serial = record.config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: break; case AltosLib.AO_LOG_BARO_RESERVED: - baro.reserved = record.a; + baro.reserved = record.config_a; break; case AltosLib.AO_LOG_BARO_SENS: - baro.sens =record.a; + baro.sens =record.config_a; break; case AltosLib.AO_LOG_BARO_OFF: - baro.off =record.a; + baro.off =record.config_a; break; case AltosLib.AO_LOG_BARO_TCS: - baro.tcs =record.a; + baro.tcs =record.config_a; break; case AltosLib.AO_LOG_BARO_TCO: - baro.tco =record.a; + baro.tco =record.config_a; break; case AltosLib.AO_LOG_BARO_TREF: - baro.tref =record.a; + baro.tref =record.config_a; break; case AltosLib.AO_LOG_BARO_TEMPSENS: - baro.tempsens =record.a; + baro.tempsens =record.config_a; break; case AltosLib.AO_LOG_BARO_CRC: - baro.crc =record.a; + baro.crc =record.config_a; break; } state.seen |= eeprom.seen; @@ -270,25 +254,25 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { out.printf("# Config version: %s\n", record.data); break; case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.a); + out.printf("# Main deploy: %s\n", record.config_a); break; case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.a); + out.printf("# Apogee delay: %s\n", record.config_a); break; case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.a); + out.printf("# Radio channel: %s\n", record.config_a); break; case AltosLib.AO_LOG_CALLSIGN: out.printf("# Callsign: %s\n", record.data); break; case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.a, record.b); + out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); break; case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.a); + out.printf ("# Radio cal: %d\n", record.config_a); break; case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.a); + out.printf ("# Max flight log: %d\n", record.config_a); break; case AltosLib.AO_LOG_MANUFACTURER: out.printf ("# Manufacturer: %s\n", record.data); @@ -297,34 +281,34 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { out.printf ("# Product: %s\n", record.data); break; case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.a); + out.printf ("# Serial number: %d\n", record.config_a); break; case AltosLib.AO_LOG_SOFTWARE_VERSION: out.printf ("# Software version: %s\n", record.data); break; case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.a); + out.printf ("# Baro reserved: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.a); + out.printf ("# Baro sens: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.a); + out.printf ("# Baro off: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.a); + out.printf ("# Baro tcs: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.a); + out.printf ("# Baro tco: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.a); + out.printf ("# Baro tref: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.a); + out.printf ("# Baro tempsens: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.a); + out.printf ("# Baro crc: %d\n", record.config_a); break; } } @@ -369,7 +353,7 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { /* Bail after reading the 'landed' record; we're all done */ if (record.cmd == AltosLib.AO_LOG_STATE && - record.a == AltosLib.ao_flight_landed) + record.state() == AltosLib.ao_flight_landed) break; } } catch (IOException io) { -- cgit v1.2.3 From 6a1a1dae3e00bfcddf31c447f915245a7d42e566 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 16:55:00 -0700 Subject: altos: Document mega log packet types Just add comments to ao_log.h so it's easy to remember which labels go with each record. Signed-off-by: Keith Packard --- src/core/ao_log.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/ao_log.h b/src/core/ao_log.h index eaaca444..4eaed420 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -197,15 +197,18 @@ struct ao_log_mega { uint8_t csum; /* 1 */ uint16_t tick; /* 2 */ union { /* 4 */ + /* AO_LOG_FLIGHT */ struct { uint16_t flight; /* 4 */ int16_t ground_accel; /* 6 */ uint32_t ground_pres; /* 8 */ } flight; /* 12 */ + /* AO_LOG_STATE */ struct { uint16_t state; uint16_t reason; } state; + /* AO_LOG_SENSOR */ struct { uint32_t pres; /* 4 */ uint32_t temp; /* 8 */ @@ -220,12 +223,14 @@ struct ao_log_mega { int16_t mag_z; /* 28 */ int16_t accel; /* 30 */ } sensor; /* 32 */ + /* AO_LOG_TEMP_VOLT */ struct { int16_t v_batt; /* 4 */ int16_t v_pbatt; /* 6 */ int16_t n_sense; /* 8 */ int16_t sense[10]; /* 10 */ } volt; /* 30 */ + /* AO_LOG_GPS_TIME */ struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ @@ -239,6 +244,7 @@ struct ao_log_mega { uint8_t day; /* 20 */ uint8_t pad; /* 21 */ } gps; /* 22 */ + /* AO_LOG_GPS_SAT */ struct { uint16_t channels; /* 4 */ struct { -- cgit v1.2.3 From f789b0b94eb01e3875f7711ce053658c31e75fad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 17:00:08 -0700 Subject: altosui: Handle .mega files in Landed tab 'Graph Flight' button Need to check for .mega files here too. Signed-off-by: Keith Packard --- altosui/AltosLanded.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 0111a08a..5e073f7d 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -250,6 +250,9 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); records = new AltosTelemetryIterable(in); + } else if (filename.endsWith("mega")) { + FileInputStream in = new FileInputStream(file); + records = new AltosEepromMegaIterable(in); } else { throw new FileNotFoundException(filename); } -- cgit v1.2.3 From e16c33545640f745cec8dc595b2343359efced57 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 17:26:16 -0700 Subject: altos/test: Use MMA655X in ao_flight_test_mm. Add run-mm to plot mm data Pull MMA655X data out of eeprom file when available. Switch build to using MMA655x by default. Clone run-one to plot a single mm flight Signed-off-by: Keith Packard --- src/test/ao_flight_test.c | 5 ++++- src/test/run-mm | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100755 src/test/run-mm diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 0df9a5d7..7180f02d 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -39,7 +39,7 @@ #define AO_ADC_NUM_SENSE 6 #define HAS_MS5607 1 #define HAS_MPU6000 1 -#define HAS_MMA655X 0 +#define HAS_MMA655X 1 struct ao_adc { int16_t sense[AO_ADC_NUM_SENSE]; @@ -622,6 +622,9 @@ ao_sleep(void *wchan) ao_data_static.mpu6000.gyro_x = int16(bytes, 14); ao_data_static.mpu6000.gyro_y = -int16(bytes, 16); ao_data_static.mpu6000.gyro_z = int16(bytes, 18); +#if HAS_MMA655X + ao_data_static.mma655x = int16(bytes, 26); +#endif if (ao_records_read == 0) ao_ground_mpu6000 = ao_data_static.mpu6000; else if (ao_records_read < 10) { diff --git a/src/test/run-mm b/src/test/run-mm new file mode 100755 index 00000000..6f3d97a2 --- /dev/null +++ b/src/test/run-mm @@ -0,0 +1,41 @@ +#!/bin/sh + +DIR=~/misc/rockets/flights + +for i in "$@"; do +case "$i" in + */*) + file="$i" + ;; + *) + file="$DIR/$i" + ;; +esac +./ao_flight_test_mm "$file" > run-out.mm + +#./ao_flight_test_accel "$file" > run-out.accel +#"run-out.accel" using 1:9 with lines lt 4 axes x1y1 title "accel height",\ +#"run-out.accel" using 1:11 with lines lt 4 axes x1y2 title "accel speed",\ +#"run-out.accel" using 1:13 with lines lt 4 axes x1y2 title "accel accel",\ +#"run-out.accel" using 1:15 with lines lt 4 axes x1y1 title "accel drogue",\ +#"run-out.accel" using 1:17 with lines lt 4 axes x1y1 title "accel main",\ +# + +gnuplot << EOF +set ylabel "altitude (m)" +set y2label "velocity (m/s), acceleration(m/s²)" +set xlabel "time (s)" +set xtics border out nomirror +set ytics border out nomirror +set y2tics border out nomirror +set title "$i" +plot "run-out.mm" using 1:3 with lines lw 2 lt 1 axes x1y1 title "raw height",\ +"run-out.mm" using 1:5 with lines lw 2 lt 1 axes x1y2 title "raw accel",\ +"run-out.mm" using 1:21 with lines lt 2 axes x1y1 title "mm height",\ +"run-out.mm" using 1:23 with lines lt 2 axes x1y2 title "mm speed",\ +"run-out.mm" using 1:25 with lines lt 2 axes x1y2 title "mm accel",\ +"run-out.mm" using 1:29 with lines lt 2 axes x1y1 title "mm drogue",\ +"run-out.mm" using 1:31 with lines lt 2 axes x1y1 title "mm main" +pause mouse close +EOF +done \ No newline at end of file -- cgit v1.2.3 From e4ee3a35dbb1586f65adada0eaf34b7b4e5432eb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 19:51:02 -0700 Subject: altoslib: Add AltosRecordNone.java oops. forgot a file. Signed-off-by: Keith Packard --- altoslib/AltosRecordNone.java | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 altoslib/AltosRecordNone.java diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java new file mode 100644 index 00000000..ca0a5fe3 --- /dev/null +++ b/altoslib/AltosRecordNone.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +public class AltosRecordNone extends AltosRecord { + + public double pressure() { return MISSING; } + public double ground_pressure() { return MISSING; } + public double temperature() { return MISSING; } + public double acceleration() { return MISSING; } + + public AltosRecordNone(AltosRecord old) { + super.copy(old); + } + + public AltosRecordNone() { + super(); + } +} -- cgit v1.2.3 From 8cb09f8a3e2dae5f7f3d2d3dbbc81ba40b491e75 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 20:57:21 -0700 Subject: altosdroid: AltosState now has speed and max_speed funcs These pull out the appropriate baro/accel speed values and may use some fancier values in future. Signed-off-by: Keith Packard --- altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java | 5 +---- altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 3396f77e..b1fc8d30 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -189,10 +189,7 @@ public class AltosDroid extends Activity { mSerialView.setText(String.format("%d", state.data.serial)); mFlightView.setText(String.format("%d", state.data.flight)); mStateView.setText(state.data.state()); - double speed = state.speed; - if (!state.ascent) - speed = state.baro_speed; - mSpeedView.setText(String.format("%6.0f m/s", speed)); + mSpeedView.setText(String.format("%6.0f m/s", state.speed())); mAccelView.setText(String.format("%6.0f m/s²", state.acceleration)); mRangeView.setText(String.format("%6.0f m", state.range)); mHeightView.setText(String.format("%6.0f m", state.height)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index 3382d551..264e35c6 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -67,7 +67,7 @@ public class AltosVoice { speak(state.data.state()); if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) && state.state > AltosLib.ao_flight_boost) { - speak(String.format("max speed: %d meters per second.", (int) (state.max_speed + 0.5))); + speak(String.format("max speed: %d meters per second.", (int) (state.max_speed() + 0.5))); spoke = true; } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) && state.state >= AltosLib.ao_flight_drogue) { -- cgit v1.2.3 From 4b41561abf9144e73995ccc18eadad7936d1dd15 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Mon, 22 Oct 2012 11:55:07 +1300 Subject: altosdroid: add autogenerated BuildInfo.java * Generated by shell script that parses git describe * Makefile rule to call script on every run * also includes eclipse hooks to call shell script on build Signed-off-by: Mike Beattie --- .../Generate BuildInfo.java.launch | 11 ++++++++ altosdroid/.gitignore | 1 + altosdroid/.project | 10 +++++++ altosdroid/Makefile.am | 5 ++++ altosdroid/buildinfo.sh | 31 ++++++++++++++++++++++ .../org/altusmetrum/AltosDroid/BuildInfo.java.in | 28 +++++++++++++++++++ 6 files changed, 86 insertions(+) create mode 100644 altosdroid/.externalToolBuilders/Generate BuildInfo.java.launch create mode 100755 altosdroid/buildinfo.sh create mode 100644 altosdroid/src/org/altusmetrum/AltosDroid/BuildInfo.java.in diff --git a/altosdroid/.externalToolBuilders/Generate BuildInfo.java.launch b/altosdroid/.externalToolBuilders/Generate BuildInfo.java.launch new file mode 100644 index 00000000..3b8eff45 --- /dev/null +++ b/altosdroid/.externalToolBuilders/Generate BuildInfo.java.launch @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/altosdroid/.gitignore b/altosdroid/.gitignore index c0bb8dd4..e3acba40 100644 --- a/altosdroid/.gitignore +++ b/altosdroid/.gitignore @@ -1,3 +1,4 @@ local.properties bin gen +src/org/altusmetrum/AltosDroid/BuildInfo.java diff --git a/altosdroid/.project b/altosdroid/.project index 7b56596a..ebe4a4bb 100644 --- a/altosdroid/.project +++ b/altosdroid/.project @@ -5,6 +5,16 @@ + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/Generate BuildInfo.java.launch + + + com.android.ide.eclipse.adt.ResourceManagerBuilder diff --git a/altosdroid/Makefile.am b/altosdroid/Makefile.am index 96831b72..3860e110 100644 --- a/altosdroid/Makefile.am +++ b/altosdroid/Makefile.am @@ -30,6 +30,7 @@ SRC=\ $(SRC_DIR)/TelemetryLogger.java \ $(SRC_DIR)/AltosBluetooth.java \ $(SRC_DIR)/DeviceListActivity.java \ + $(SRC_DIR)/BuildInfo.java \ $(SRC_DIR)/Dumper.java all: $(all_target) @@ -38,6 +39,9 @@ $(ALTOSLIB): $(ALTOSLIB_SRCDIR)/$(ALTOSLIB_JAR) mkdir -p $(EXT_LIBDIR) cd $(EXT_LIBDIR) && ln -s $(shell echo $(EXT_LIBDIR) | sed 's|[^/]\+|..|g')/$(ALTOSLIB_SRCDIR)/$(ALTOSLIB_JAR) . +$(SRC_DIR)/BuildInfo.java: + ./buildinfo.sh + if ANDROID install-release: bin/AltosDroid-release.apk $(ADB) install -r bin/AltosDroid-release.apk @@ -55,3 +59,4 @@ endif clean: $(clean_command) +.PHONY: $(SRC_DIR)/BuildInfo.java diff --git a/altosdroid/buildinfo.sh b/altosdroid/buildinfo.sh new file mode 100755 index 00000000..f620c4a0 --- /dev/null +++ b/altosdroid/buildinfo.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# + +describe=$(git describe --always 2>/dev/null || echo '') +if [ -n "$describe" ]; then + version=$(echo $describe | cut -d- -f1) + commitnum=$(echo $describe | cut -d- -f2) + commithash=$(echo $describe | cut -d- -f3) +else + . ../src/Version + version=$VERSION + commitnum='' + commithash='' +fi + +builddate=$(date "+%Y-%m-%d") +buildtime=$(date "+%H:%M") + + +infile=src/org/altusmetrum/AltosDroid/BuildInfo.java.in +outfile=src/org/altusmetrum/AltosDroid/BuildInfo.java + +echo "Version $describe, built on $builddate, $buildtime" + +sed -e "s/@DESCRIBE@/$describe/" \ + -e "s/@VERSION@/$version/" \ + -e "s/@COMMITNUM@/$commitnum/" \ + -e "s/@COMMITHASH@/$commithash/" \ + -e "s/@BUILDDATE@/$builddate/" \ + -e "s/@BUILDTIME@/$buildtime/" \ + $infile > $outfile diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/BuildInfo.java.in b/altosdroid/src/org/altusmetrum/AltosDroid/BuildInfo.java.in new file mode 100644 index 00000000..763f814e --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/BuildInfo.java.in @@ -0,0 +1,28 @@ +/* + * Copyright © 2012 Mike Beattie + * + * 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.AltosDroid; + +public class BuildInfo { + public static final String git_describe = "@DESCRIBE@"; + public static final String version = "@VERSION@"; + public static final String commitnum = "@COMMITNUM@"; + public static final String commithash = "@COMMITHASH@"; + public static final String builddate = "@BUILDDATE@"; + public static final String buildtime = "@BUILDTIME@"; +} + -- cgit v1.2.3 From fd619a01bf3489b1df017aca20362757b087ec11 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 08:52:08 -0700 Subject: altos: Add state comparisons to pyro channel conditions Let pyro channels block waiting for flight state changes. This allows for pyro channels to be synchronized with the main iginiter channels. Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 16 +++++++++++++++- src/core/ao_pyro.h | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 4f37e979..b1cfd9d8 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -113,6 +113,15 @@ ao_pyro_ready(struct ao_pyro *pyro) /* handled separately */ continue; + case ao_pyro_state_less: + if (ao_flight_state < pyro->state_less) + continue; + break; + case ao_pyro_state_greater_or_equal: + if (ao_flight_state >= pyro->state_greater_or_equal) + continue; + break; + default: continue; } @@ -166,7 +175,7 @@ uint8_t ao_pyro_wakeup; static void ao_pyro(void) { - uint8_t p; + uint8_t p, any_waiting; struct ao_pyro *pyro; ao_config_get(); @@ -177,6 +186,7 @@ ao_pyro(void) ao_alarm(AO_MS_TO_TICKS(100)); ao_sleep(&ao_pyro_wakeup); ao_clear_alarm(); + any_waiting = 0; for (p = 0; p < AO_PYRO_NUM; p++) { pyro = &ao_config.pyro[p]; @@ -190,6 +200,7 @@ ao_pyro(void) if (!pyro->flags) continue; + any_waiting = 1; /* Check pyro state to see if it shoule fire */ if (!pyro->delay_done) { @@ -213,7 +224,10 @@ ao_pyro(void) ao_pyro_fire(p); } + if (!any_waiting) + break; } + ao_exit(); } __xdata struct ao_task ao_pyro_task; diff --git a/src/core/ao_pyro.h b/src/core/ao_pyro.h index 5deb69d0..cde850ad 100644 --- a/src/core/ao_pyro.h +++ b/src/core/ao_pyro.h @@ -42,6 +42,9 @@ enum ao_pyro_flag { ao_pyro_after_motor = 0x00001000, ao_pyro_delay = 0x00002000, + + ao_pyro_state_less = 0x00004000, + ao_pyro_state_greater_or_equal = 0x00008000, }; struct ao_pyro { @@ -52,6 +55,7 @@ struct ao_pyro { int16_t orient_less, orient_greater; int16_t time_less, time_greater; int16_t delay; + uint8_t state_less, state_greater_or_equal; int16_t motor; uint16_t delay_done; uint8_t fired; -- cgit v1.2.3 From fe00d1169c65cb289f77093cf281efbd0a5d4e64 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:35:06 -0700 Subject: altosui/altoslib: Add support for configuring pyro channels This provides a UI on devices which have pyro channels other than main/apogee. Signed-off-by: Keith Packard --- altoslib/AltosConfigData.java | 17 +++ altoslib/AltosPyro.java | 293 +++++++++++++++++++++++++++++++++++++++++ altoslib/Makefile.am | 3 +- altosui/AltosConfig.java | 32 +++++ altosui/AltosConfigPyroUI.java | 288 ++++++++++++++++++++++++++++++++++++++++ altosui/AltosConfigUI.java | 68 ++++++++-- altosui/AltosDialog.java | 6 + altosui/Makefile.am | 1 + 8 files changed, 697 insertions(+), 11 deletions(-) create mode 100644 altoslib/AltosPyro.java create mode 100644 altosui/AltosConfigPyroUI.java diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index a962b105..45a88783 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -50,6 +50,8 @@ public class AltosConfigData implements Iterable { public int storage_size; public int storage_erase_unit; + public AltosPyro[] pyros; + public static String get_string(String line, String label) throws ParseException { if (line.startsWith(label)) { String quoted = line.substring(label.length()).trim(); @@ -135,6 +137,10 @@ public class AltosConfigData implements Iterable { radio_frequency = 0; stored_flight = 0; serial = -1; + pyros = null; + + int npyro = 0; + int pyro = 0; for (;;) { String line = link.get_reply(); if (line == null) @@ -142,6 +148,16 @@ public class AltosConfigData implements Iterable { if (line.contains("Syntax error")) continue; lines.add(line); + if (pyro < npyro - 1) { + if (pyros == null) + pyros = new AltosPyro[npyro]; + try { + pyros[pyro] = new AltosPyro(pyro, line); + } catch (ParseException e) { + } + ++pyro; + continue; + } try { serial = get_int(line, "serial-number"); } catch (Exception e) {} try { log_format = get_int(line, "log-format"); } catch (Exception e) {} try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {} @@ -173,6 +189,7 @@ public class AltosConfigData implements Iterable { try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {} try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {} try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} + try { npyro = get_int(line, "Pyro-count:"); pyro = 0; } catch (Exception e) {} /* signals the end of the version info */ if (line.startsWith("software-version")) diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java new file mode 100644 index 00000000..14051169 --- /dev/null +++ b/altoslib/AltosPyro.java @@ -0,0 +1,293 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosLib; + +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosPyro { + public static final int pyro_none = 0x00000000; + + public static final int pyro_accel_less = 0x00000001; + public static final int pyro_accel_greater = 0x00000002; + public static final String pyro_accel_less_string = "a<"; + public static final String pyro_accel_greater_string = "a>"; + public static final String pyro_accel_less_name = "Acceleration less than (m/s²)"; + public static final String pyro_accel_greater_name = "Acceleration greater than (m/s²)"; + public static final double pyro_accel_scale = 16.0; + + public static final int pyro_speed_less = 0x00000004; + public static final int pyro_speed_greater = 0x00000008; + public static final String pyro_speed_less_string = "s<"; + public static final String pyro_speed_greater_string = "s>"; + public static final String pyro_speed_less_name = "Speed less than (m/s)"; + public static final String pyro_speed_greater_name = "Speed greater than (m/s)"; + public static final double pyro_speed_scale = 16.0; + + public static final int pyro_height_less = 0x00000010; + public static final int pyro_height_greater = 0x00000020; + public static final String pyro_height_less_string = "h<"; + public static final String pyro_height_greater_string = "h>"; + public static final String pyro_height_less_name = "Height less than (m)"; + public static final String pyro_height_greater_name = "Height greater than (m)"; + public static final double pyro_height_scale = 1.0; + + public static final int pyro_orient_less = 0x00000040; + public static final int pyro_orient_greater = 0x00000080; + public static final String pyro_orient_less_string = "o<"; + public static final String pyro_orient_greater_string = "o>"; + public static final String pyro_orient_less_name = "Angle from vertical less than (degrees)"; + public static final String pyro_orient_greater_name = "Angle from vertical greater than (degrees)"; + public static final double pyro_orient_scale = 1.0; + + public static final int pyro_time_less = 0x00000100; + public static final int pyro_time_greater = 0x00000200; + public static final String pyro_time_less_string = "t<"; + public static final String pyro_time_greater_string = "t>"; + public static final String pyro_time_less_name = "Time since boost less than (s)"; + public static final String pyro_time_greater_name = "Time since boost greater than (s)"; + public static final double pyro_time_scale = 100.0; + + public static final int pyro_ascending = 0x00000400; + public static final int pyro_descending = 0x00000800; + public static final String pyro_ascending_string = "A"; + public static final String pyro_descending_string = "D"; + public static final String pyro_ascending_name = "Ascending"; + public static final String pyro_descending_name = "Descending"; + + public static final int pyro_after_motor = 0x00001000; + public static final String pyro_after_motor_string = "m"; + public static final String pyro_after_motor_name = "After motor number"; + public static final double pyro_after_motor_scale = 1.0; + + public static final int pyro_delay = 0x00002000; + public static final String pyro_delay_string = "d"; + public static final String pyro_delay_name = "Delay after other conditions (s)"; + public static final double pyro_delay_scale = 100.0; + + public static final int pyro_state_less = 0x00004000; + public static final int pyro_state_greater_or_equal = 0x00008000; + public static final String pyro_state_less_string = "f<"; + public static final String pyro_state_greater_or_equal_string = "f>="; + public static final String pyro_state_less_name = "Flight state before"; + public static final String pyro_state_greater_or_equal_name = "Flight state after"; + public static final double pyro_state_scale = 1.0; + + public static final int pyro_all = 0x0000ffff; + + public static final int pyro_no_value = (pyro_ascending | + pyro_descending); + + public static final int pyro_state_value = pyro_state_less | pyro_state_greater_or_equal; + + private static HashMap string_to_pyro = new HashMap(); + + private static HashMap pyro_to_string = new HashMap(); + + private static HashMap pyro_to_name = new HashMap(); + + private static HashMap pyro_to_scale = new HashMap(); + + private static void insert_map(int flag, String string, String name, double scale) { + string_to_pyro.put(string, flag); + pyro_to_string.put(flag, string); + pyro_to_name.put(flag, name); + pyro_to_scale.put(flag, scale); + } + + public static int string_to_pyro(String name) { + if (string_to_pyro.containsKey(name)) + return string_to_pyro.get(name); + return pyro_none; + } + + public static String pyro_to_string(int flag) { + if (pyro_to_string.containsKey(flag)) + return pyro_to_string.get(flag); + return null; + } + + public static String pyro_to_name(int flag) { + if (pyro_to_name.containsKey(flag)) + return pyro_to_name.get(flag); + return null; + } + + public static double pyro_to_scale(int flag) { + if (pyro_to_scale.containsKey(flag)) + return pyro_to_scale.get(flag); + return 1.0; + } + + private static void initialize_maps() { + insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale); + insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale); + + insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale); + insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale); + + insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale); + insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale); + + insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale); + insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale); + + insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale); + insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale); + + insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0); + insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0); + + insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0); + insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale); + + insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0); + insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0); + } + + { + initialize_maps(); + } + + public int channel; + public int flags; + public int accel_less, accel_greater; + public int speed_less, speed_greater; + public int height_less, height_greater; + public int orient_less, orient_greater; + public int time_less, time_greater; + public int delay; + public int state_less, state_greater_or_equal; + public int motor; + + public AltosPyro(int in_channel) { + channel = in_channel; + flags = 0; + } + + private boolean set_ivalue(int flag, int value) { + switch (flag) { + case pyro_accel_less: accel_less = value; break; + case pyro_accel_greater: accel_greater = value; break; + case pyro_speed_less: speed_less = value; break; + case pyro_speed_greater: speed_greater = value; break; + case pyro_height_less: height_less = value; break; + case pyro_height_greater: height_greater = value; break; + case pyro_orient_less: orient_less = value; break; + case pyro_orient_greater: orient_greater = value; break; + case pyro_time_less: time_less = value; break; + case pyro_time_greater: time_greater = value; break; + case pyro_after_motor: motor = value; break; + case pyro_delay: delay = value; break; + case pyro_state_less: state_less = value; break; + case pyro_state_greater_or_equal: state_greater_or_equal = value; break; + default: + return false; + } + return true; + } + + public boolean set_value(int flag, double dvalue) { + return set_ivalue(flag, (int) (dvalue * pyro_to_scale(flag))); + } + + private int get_ivalue (int flag) { + int value; + + switch (flag) { + case pyro_accel_less: value = accel_less; break; + case pyro_accel_greater: value = accel_greater; break; + case pyro_speed_less: value = speed_less; break; + case pyro_speed_greater: value = speed_greater; break; + case pyro_height_less: value = height_less; break; + case pyro_height_greater: value = height_greater; break; + case pyro_orient_less: value = orient_less; break; + case pyro_orient_greater: value = orient_greater; break; + case pyro_time_less: value = time_less; break; + case pyro_time_greater: value = time_greater; break; + case pyro_after_motor: value = motor; break; + case pyro_delay: value = delay; break; + case pyro_state_less: value = state_less; break; + case pyro_state_greater_or_equal: value = state_greater_or_equal; break; + default: value = 0; break; + } + return value; + } + + public double get_value(int flag) { + return get_ivalue(flag) / pyro_to_scale(flag); + } + + public AltosPyro(int in_channel, String line) throws ParseException { + String[] tokens = line.split("\\s+"); + + channel = in_channel; + flags = 0; + + int i = 0; + if (tokens[i].equals("Pyro")) + i += 2; + + for (; i < tokens.length; i++) { + + if (tokens[i].equals("")) + break; + + int flag = string_to_pyro(tokens[i]); + if (flag == pyro_none) + throw new ParseException(String.format("Invalid pyro token \"%s\"", + tokens[i]), i); + flags |= flag; + + if ((flag & pyro_no_value) == 0) { + int value = 0; + ++i; + try { + value = AltosLib.fromdec(tokens[i]); + } catch (NumberFormatException n) { + throw new ParseException(String.format("Invalid pyro value \"%s\"", + tokens[i]), i); + } + if (!set_ivalue(flag, value)) + throw new ParseException(String.format("Internal parser error \"%s\" \"%s\"", + tokens[i-1], tokens[i]), i-1); + } + } + } + + public String toString() { + String ret = String.format("%d", channel); + + for (int flag = 1; flag <= flags; flag <<= 1) { + if ((flags & flag) != 0) { + String add; + if ((flag & pyro_no_value) == 0) { + add = String.format(" %s %d", + pyro_to_string.get(flag), + get_ivalue(flag)); + } else { + add = String.format(" %s", + pyro_to_string.get(flag)); + } + ret = ret.concat(add); + } + } + return ret; + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index f04c10c6..2579a650 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -75,7 +75,8 @@ AltosLib_JAVA = \ $(SRC)/AltosDistance.java \ $(SRC)/AltosHeight.java \ $(SRC)/AltosSpeed.java \ - $(SRC)/AltosAccel.java + $(SRC)/AltosAccel.java \ + $(SRC)/AltosPyro.java JAR=AltosLib.jar diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 44e5a3fa..be9ab8bf 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,6 +22,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import org.altusmetrum.AltosLib.*; +import java.text.*; public class AltosConfig implements ActionListener { @@ -78,6 +79,8 @@ public class AltosConfig implements ActionListener { string_ref version; string_ref product; string_ref callsign; + int_ref npyro; + AltosPyro[] pyros; AltosConfigUI config_ui; boolean serial_started; boolean made_visible; @@ -162,6 +165,8 @@ public class AltosConfig implements ActionListener { config_ui.set_ignite_mode(ignite_mode.get()); config_ui.set_pad_orientation(pad_orientation.get()); config_ui.set_callsign(callsign.get()); + config_ui.set_pyros(pyros); + config_ui.set_has_pyro(npyro.get() > 0); config_ui.set_clean(); if (!made_visible) { made_visible = true; @@ -169,6 +174,8 @@ public class AltosConfig implements ActionListener { } } + int pyro; + void process_line(String line) { if (line == null) { abort(); @@ -179,6 +186,18 @@ public class AltosConfig implements ActionListener { update_ui(); return; } + if (pyro < npyro.get()) { + if (pyros == null) + pyros = new AltosPyro[npyro.get()]; + + try { + pyros[pyro] = new AltosPyro(pyro, line); + } catch (ParseException e) { + System.out.printf ("pyro parse failed %s\n", line); + } + ++pyro; + return; + } get_int(line, "serial-number", serial); get_int(line, "log-format", log_format); get_int(line, "Main deploy:", main_deploy); @@ -200,6 +219,7 @@ public class AltosConfig implements ActionListener { get_string(line, "Callsign:", callsign); get_string(line,"software-version", version); get_string(line,"product", product); + get_int(line, "Pyro-count:", npyro); } final static int serial_mode_read = 0; @@ -243,6 +263,8 @@ public class AltosConfig implements ActionListener { callsign.set("N0CALL"); version.set("unknown"); product.set("unknown"); + pyro = 0; + npyro.set(0); } void get_data() { @@ -304,6 +326,12 @@ public class AltosConfig implements ActionListener { serial_line.printf("c i %d\n", ignite_mode.get()); if (pad_orientation.get() >= 0) serial_line.printf("c o %d\n", pad_orientation.get()); + if (pyros.length > 0) { + for (int p = 0; p < pyros.length; p++) { + serial_line.printf("c P %s\n", + pyros[p].toString()); + } + } serial_line.printf("c w\n"); } catch (InterruptedException ie) { } catch (TimeoutException te) { @@ -431,6 +459,9 @@ public class AltosConfig implements ActionListener { if (pad_orientation.get() >= 0) pad_orientation.set(config_ui.pad_orientation()); callsign.set(config_ui.callsign()); + if (npyro.get() > 0) { + pyros = config_ui.pyros(); + } run_serial_thread(serial_mode_save); } @@ -477,6 +508,7 @@ public class AltosConfig implements ActionListener { callsign = new string_ref("N0CALL"); version = new string_ref("unknown"); product = new string_ref("unknown"); + npyro = new int_ref(0); device = AltosDeviceDialog.show(owner, Altos.product_any); if (device != null) { diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java new file mode 100644 index 00000000..17adb15f --- /dev/null +++ b/altosui/AltosConfigPyroUI.java @@ -0,0 +1,288 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import org.altusmetrum.AltosLib.*; + +public class AltosConfigPyroUI + extends AltosDialog + implements ItemListener, DocumentListener +{ + AltosConfigUI owner; + Container pane; + + static Insets il = new Insets(4,4,4,4); + static Insets ir = new Insets(4,4,4,4); + + static String[] state_names; + + static void make_state_names() { + if (state_names == null) { + + state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1]; + for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++) + state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state); + } + } + + class PyroItem implements ItemListener, DocumentListener + { + public int flag; + public JRadioButton enable; + public JTextField value; + public JComboBox combo; + AltosConfigPyroUI ui; + + public void set_enable(boolean enable) { + if (value != null) + value.setEnabled(enable); + if (combo != null) + combo.setEnabled(enable); + } + + public void itemStateChanged(ItemEvent e) { + set_enable(enable.isSelected()); + ui.set_dirty(); + } + + public void changedUpdate(DocumentEvent e) { + ui.set_dirty(); + } + + public void insertUpdate(DocumentEvent e) { + ui.set_dirty(); + } + + public void removeUpdate(DocumentEvent e) { + ui.set_dirty(); + } + + public void set(boolean new_enable, double new_value) { + enable.setSelected(new_enable); + set_enable(new_enable); + if (value != null) { + double scale = AltosPyro.pyro_to_scale(flag); + String format = "%6.0f"; + if (scale >= 10) + format = "%6.1f"; + else if (scale >= 100) + format = "%6.2f"; + value.setText(String.format(format, new_value)); + } + if (combo != null) + if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed) + combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost); + } + + public boolean enabled() { + return enable.isSelected(); + } + + public double value() { + if (value != null) + return Double.parseDouble(value.getText()); + if (combo != null) + return combo.getSelectedIndex() + AltosLib.ao_flight_boost; + return 0; + } + + public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) { + + ui = in_ui; + flag = in_flag; + + GridBagConstraints c; + c = new GridBagConstraints(); + c.gridx = x; c.gridy = y; + c.gridwidth = 1; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + enable = new JRadioButton(); + enable.addItemListener(this); + pane.add(enable, c); + + if ((flag & AltosPyro.pyro_no_value) == 0) { + c = new GridBagConstraints(); + c.gridx = x+1; c.gridy = y; + c.gridwidth = 1; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + if ((flag & AltosPyro.pyro_state_value) != 0) { + make_state_names(); + combo = new JComboBox(state_names); + combo.addItemListener(this); + pane.add(combo, c); + } else { + value = new JTextField(10); + value.getDocument().addDocumentListener(this); + pane.add(value, c); + } + } + } + } + + class PyroColumn { + public PyroItem[] items; + public JLabel label; + int channel; + + public void set(AltosPyro pyro) { + int row = 0; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all & flag) != 0) { + items[row].set((pyro.flags & flag) != 0, + pyro.get_value(flag)); + row++; + } + } + } + + public AltosPyro get() { + AltosPyro p = new AltosPyro(channel); + + int row = 0; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { + if ((AltosPyro.pyro_all & flag) != 0) { + if (items[row].enabled()) { + System.out.printf ("Flag %x enabled\n", flag); + p.flags |= flag; + p.set_value(flag, items[row].value()); + } + row++; + } + } + System.out.printf ("Pyro %x %s\n", p.flags, p.toString()); + return p; + } + + public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) { + + channel = in_channel; + + int nrow = 0; + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) + if ((flag & AltosPyro.pyro_all) != 0) + nrow++; + + items = new PyroItem[nrow]; + int row = 0; + + GridBagConstraints c; + c = new GridBagConstraints(); + c.gridx = x; c.gridy = y; + c.gridwidth = 2; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.CENTER; + c.insets = il; + label = new JLabel(String.format("Pyro Channel %d", channel)); + pane.add(label, c); + y++; + + for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) + if ((flag & AltosPyro.pyro_all) != 0) { + items[row] = new PyroItem(ui, flag, x, y + row); + row++; + } + } + } + + PyroColumn[] columns; + + public void set_pyros(AltosPyro[] pyros) { + for (int i = 0; i < pyros.length; i++) { + if (pyros[i].channel < columns.length) + columns[pyros[i].channel].set(pyros[i]); + } + } + + public AltosPyro[] get_pyros() { + AltosPyro[] pyros = new AltosPyro[columns.length]; + for (int c = 0; c < columns.length; c++) + pyros[c] = columns[c].get(); + return pyros; + } + + public void set_dirty() { + owner.set_dirty(); + } + + public void itemStateChanged(ItemEvent e) { + owner.set_dirty(); + } + + public void changedUpdate(DocumentEvent e) { + owner.set_dirty(); + } + + public void insertUpdate(DocumentEvent e) { + owner.set_dirty(); + } + + public void removeUpdate(DocumentEvent e) { + owner.set_dirty(); + } + + public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) { + + super(in_owner, "Configure Pyro Channels", false); + + owner = in_owner; + + GridBagConstraints c; + + pane = getContentPane(); + pane.setLayout(new GridBagLayout()); + + int row = 1; + + for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) { + String n; + + n = AltosPyro.pyro_to_name(flag); + if (n != null) { + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = row; + c.gridwidth = 1; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + JLabel label = new JLabel(n); + pane.add(label, c); + row++; + } + } + + columns = new PyroColumn[pyros.length]; + + for (int i = 0; i < pyros.length; i++) { + columns[i] = new PyroColumn(this, i*2 + 1, 0, i); + columns[i].set(pyros[i]); + } + } + + public void make_visible() { + pack(); + setVisible(true); + } +} diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index dd34a9cf..feac053b 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -29,7 +29,6 @@ public class AltosConfigUI { Container pane; - Box box; JLabel product_label; JLabel version_label; JLabel serial_label; @@ -62,11 +61,15 @@ public class AltosConfigUI JComboBox pad_orientation_value; JTextField callsign_value; + JButton pyro; + JButton save; JButton reset; JButton reboot; JButton close; + AltosPyro[] pyros; + ActionListener listener; static String[] main_deploy_values = { @@ -510,6 +513,20 @@ public class AltosConfigUI set_pad_orientation_tool_tip(); row++; + /* Pyro channels */ + c = new GridBagConstraints(); + c.gridx = 4; c.gridy = row; + c.gridwidth = 4; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + c.ipady = 5; + pyro = new JButton("Configure Pyro Channels"); + pane.add(pyro, c); + pyro.addActionListener(this); + pyro.setActionCommand("Pyro"); + row++; + /* Buttons */ c = new GridBagConstraints(); c.gridx = 0; c.gridy = row; @@ -582,10 +599,30 @@ public class AltosConfigUI return true; } + void set_dirty() { + dirty = true; + save.setEnabled(true); + } + + public void set_clean() { + dirty = false; + save.setEnabled(false); + } + + AltosConfigPyroUI pyro_ui; + /* Listen for events from our buttons */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); + if (cmd.equals("Pyro")) { + if (pyro_ui == null && pyros != null) { + pyro_ui = new AltosConfigPyroUI(this, pyros); + pyro_ui.make_visible(); + } + return; + } + if (cmd.equals("Close") || cmd.equals("Reboot")) if (!check_dirty(cmd)) return; @@ -594,25 +631,25 @@ public class AltosConfigUI setVisible(false); dispose(); } - dirty = false; + set_clean(); } /* ItemListener interface method */ public void itemStateChanged(ItemEvent e) { - dirty = true; + set_dirty(); } /* DocumentListener interface methods */ public void changedUpdate(DocumentEvent e) { - dirty = true; + set_dirty(); } public void insertUpdate(DocumentEvent e) { - dirty = true; + set_dirty(); } public void removeUpdate(DocumentEvent e) { - dirty = true; + set_dirty(); } /* Let the config code hook on a listener */ @@ -725,8 +762,7 @@ public class AltosConfigUI } public void set_flight_log_max(int new_flight_log_max) { - if (new_flight_log_max == 0) - flight_log_max_value.setEnabled(false); + flight_log_max_value.setEnabled(new_flight_log_max > 0); flight_log_max_value.setSelectedItem(Integer.toString(new_flight_log_max)); set_flight_log_max_tool_tip(); } @@ -793,7 +829,19 @@ public class AltosConfigUI return -1; } - public void set_clean() { - dirty = false; + public void set_has_pyro(boolean has_pyro) { + pyro.setEnabled(has_pyro); + } + + public void set_pyros(AltosPyro[] new_pyros) { + pyros = new_pyros; + if (pyro_ui != null) + pyro_ui.set_pyros(pyros); + } + + public AltosPyro[] pyros() { + if (pyro_ui != null) + pyros = pyro_ui.get_pyros(); + return pyros; } } diff --git a/altosui/AltosDialog.java b/altosui/AltosDialog.java index eac371aa..c2a9d6e6 100644 --- a/altosui/AltosDialog.java +++ b/altosui/AltosDialog.java @@ -45,6 +45,12 @@ public class AltosDialog extends JDialog implements AltosUIListener { addWindowListener(new AltosDialogListener()); } + public AltosDialog(Dialog dialog, String label, boolean modal) { + super(dialog, label, modal); + AltosUIPreferences.register_ui_listener(this); + addWindowListener(new AltosDialogListener()); + } + public AltosDialog(Frame frame, boolean modal) { super(frame, modal); AltosUIPreferences.register_ui_listener(this); diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 9f03ceb6..2c46da4a 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -24,6 +24,7 @@ altosui_JAVA = \ AltosConfig.java \ AltosConfigFreqUI.java \ AltosConfigUI.java \ + AltosConfigPyroUI.java \ AltosConfigureUI.java \ AltosConfigTD.java \ AltosConfigTDUI.java \ -- cgit v1.2.3 From 20496608ca287e65302193ee1afe9f0cad3a36e1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:36:12 -0700 Subject: altoslib: capitalize 'Invalid' state name appropriately It shouldn't ever appear, but it seemed wrong to have it not match the rest of the strings. Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 192c445e..07516aeb 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -199,7 +199,7 @@ public class AltosLib { public static String state_name_capital(int state) { if (state < 0 || state_to_string.length <= state) - return "invalid"; + return "Invalid"; return state_to_string_capital[state]; } -- cgit v1.2.3 From e80d7cd18fa4dac98d941e86b5956403a7170966 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:37:25 -0700 Subject: altos: Let AVR products override the stack size. Set telepyro to 104 Otherwise, telepyro doesn't have enough ram... Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 2 ++ src/avr/ao_pins.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index a14d0ade..96659aaf 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -37,7 +37,9 @@ * AVR definitions and code fragments for AltOS */ +#ifndef AO_STACK_SIZE #define AO_STACK_SIZE 116 +#endif /* Various definitions to make GCC look more like SDCC */ diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 0aa978e9..a08e87fa 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -69,6 +69,7 @@ #endif #ifdef TELEPYRO + #define AO_STACK_SIZE 104 #define LEDS_AVAILABLE 0 #define HAS_USB 1 #define HAS_LOG 0 -- cgit v1.2.3 From d4ea2e7c3ed84fb6f4e880da6c5ddf2a83d3ef61 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:38:18 -0700 Subject: altos: Allow pyro flight state config to be set Without these lines, flight state compares can't be shown or set. Signed-off-by: Keith Packard --- src/core/ao_pyro.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index b1cfd9d8..aac8fda5 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -271,6 +271,9 @@ const struct { { "t<", ao_pyro_time_less, offsetof(struct ao_pyro, time_less), HELP("time less (s * 100)") }, { "t>", ao_pyro_time_greater, offsetof(struct ao_pyro, time_greater), HELP("time greater (s * 100)") }, + { "f<", ao_pyro_state_less, offsetof(struct ao_pyro, state_less), HELP("state less") }, + { "f>=",ao_pyro_state_greater_or_equal, offsetof(struct ao_pyro, state_greater_or_equal), HELP("state greater or equal") }, + { "A", ao_pyro_ascending, NO_VALUE, HELP("ascending") }, { "D", ao_pyro_descending, NO_VALUE, HELP("descending") }, -- cgit v1.2.3 From 79f4e684713cff6bf999cac52f5d9525a6f7d278 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:39:12 -0700 Subject: altos: make check-avr-mem utility executable Signed-off-by: Keith Packard --- src/util/check-avr-mem | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/util/check-avr-mem diff --git a/src/util/check-avr-mem b/src/util/check-avr-mem old mode 100644 new mode 100755 -- cgit v1.2.3 From 27c31572f4f63c2282e1cc583f4402337fcb548a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 22:38:46 -0700 Subject: altosui: Allow any non-basestation to be configured TelePyro has some configuration bits. Signed-off-by: Keith Packard --- altosui/AltosConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index be9ab8bf..44c6239a 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -515,7 +515,7 @@ public class AltosConfig implements ActionListener { try { serial_line = new AltosSerial(device); try { - if (!device.matchProduct(Altos.product_altimeter)) + if (device.matchProduct(Altos.product_basestation)) remote = true; init_ui(); } catch (InterruptedException ie) { -- cgit v1.2.3