altos/micropeak: Increase boost detect to 30m
[fw/altos] / src / core / ao_microflight.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #ifndef AO_FLIGHT_TEST
19 #include <ao.h>
20 #endif
21 #include <ao_micropeak.h>
22 #include <ao_log_micro.h>
23
24 uint32_t        pa;
25 uint32_t        pa_ground;
26 uint32_t        pa_min;
27
28 static void
29 ao_microsample(void)
30 {
31         ao_pa_get();
32         ao_microkalman_predict();
33         ao_microkalman_correct();
34 }
35
36 #define NUM_PA_HIST     (GROUND_AVG)
37
38 #define SKIP_PA_HIST(i,j)       (((i) + (j)) & (NUM_PA_HIST - 1))
39
40 static uint32_t pa_hist[NUM_PA_HIST];
41
42 void
43 ao_microflight(void)
44 {
45         int16_t         sample_count;
46         uint16_t        time;
47         uint32_t        pa_interval_min, pa_interval_max;
48         int32_t         pa_diff;
49         uint8_t         h, i;
50         uint8_t         accel_lock = 0;
51         uint32_t        pa_sum = 0;
52
53         /* Wait for motion, averaging values to get ground pressure */
54
55         time = ao_time();
56         ao_pa_get();
57         ao_microkalman_init();
58         pa_ground = pa;
59         sample_count = 0;
60         h = 0;
61         for (;;) {
62                 time += SAMPLE_SLEEP;
63                 if ((sample_count & 0x1f) == 0)
64                         ao_led_on(AO_LED_REPORT);
65                 ao_delay_until(time);
66                 ao_microsample();
67                 if ((sample_count & 0x1f) == 0)
68                         ao_led_off(AO_LED_REPORT);
69                 pa_hist[h] = pa;
70                 h = SKIP_PA_HIST(h,1);
71                 pa_diff = pa_ground - ao_pa;
72
73                 /* Check for a significant pressure change */
74                 if (pa_diff > BOOST_DETECT)
75                         break;
76
77                 if (sample_count < GROUND_AVG * 2) {
78                         if (sample_count < GROUND_AVG)
79                                 pa_sum += pa;
80                         ++sample_count;
81                 } else {
82                         pa_ground = pa_sum >> GROUND_AVG_SHIFT;
83                         pa_sum = 0;
84                         sample_count = 0;
85                 }
86         }
87
88         /* Go back and find the last sample close to the ground */
89         pa_min = pa_ground - LAND_DETECT;
90         for (i = SKIP_PA_HIST(h,-2); i != SKIP_PA_HIST(h,2); i = SKIP_PA_HIST(i,-2)) {
91                 if (pa_hist[i] >= pa_min)
92                         break;
93         }
94
95         /* Log the remaining samples so we get a complete history since leaving the ground */
96         for (; i != h; i = SKIP_PA_HIST(i,2)) {
97                 pa = pa_hist[i];
98                 ao_log_micro_data();
99         }
100
101         /* Now sit around until the pressure is stable again and record the max */
102
103         sample_count = 0;
104         pa_min = ao_pa;
105         pa_interval_min = ao_pa;
106         pa_interval_max = ao_pa;
107         for (;;) {
108                 time += SAMPLE_SLEEP;
109                 ao_delay_until(time);
110                 if ((sample_count & 3) == 0)
111                         ao_led_on(AO_LED_REPORT);
112                 ao_microsample();
113                 if ((sample_count & 3) == 0)
114                         ao_led_off(AO_LED_REPORT);
115                 if (sample_count & 1)
116                         ao_log_micro_data();
117
118                 /* If accelerating upwards, don't look for min pressure */
119                 if (ao_pa_accel < ACCEL_LOCK_PA)
120                         accel_lock = ACCEL_LOCK_TIME;
121                 else if (accel_lock)
122                         --accel_lock;
123                 else if (ao_pa < pa_min)
124                         pa_min = ao_pa;
125
126                 if (sample_count == (GROUND_AVG - 1)) {
127                         pa_diff = pa_interval_max - pa_interval_min;
128
129                         /* Check to see if the pressure is now stable */
130                         if (pa_diff < LAND_DETECT)
131                                 break;
132                         sample_count = 0;
133                         pa_interval_min = ao_pa;
134                         pa_interval_max = ao_pa;
135                 } else {
136                         if (ao_pa < pa_interval_min)
137                                 pa_interval_min = ao_pa;
138                         if (ao_pa > pa_interval_max)
139                                 pa_interval_max = ao_pa;
140                         ++sample_count;
141                 }
142         }
143 }