altos: Simplify tracker logic, removing boost detect
[fw/altos] / src / kernel / ao_tracker.c
1 /*
2  * Copyright © 2014 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 #include <ao.h>
19 #include <ao_flight.h>
20 #include <ao_log.h>
21 #include <ao_log_gps.h>
22 #include <ao_distance.h>
23 #include <ao_tracker.h>
24 #include <ao_exti.h>
25
26 static uint8_t          ao_tracker_force_telem;
27
28 #if HAS_USB_CONNECT
29 static inline uint8_t
30 ao_usb_connected(void)
31 {
32         return ao_gpio_get(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, AO_USB_CONNECT) != 0;
33 }
34 #else
35 #define ao_usb_connected()      1
36 #endif
37
38 static int32_t  last_log_latitude, last_log_longitude;
39 static int16_t  last_log_altitude;
40 static uint8_t  unmoving;
41 static uint8_t  log_started;
42 static struct ao_telemetry_location gps_data;
43 static uint8_t  tracker_running;
44 static uint16_t tracker_interval;
45
46 static void
47 ao_tracker(void)
48 {
49         uint8_t new;
50         int32_t ground_distance;
51         int16_t height;
52         uint16_t gps_tick;
53         uint8_t new_tracker_running;
54
55 #if HAS_ADC
56         ao_timer_set_adc_interval(100);
57 #endif
58
59 #if !HAS_USB_CONNECT
60         ao_tracker_force_telem = 1;
61 #endif
62         ao_log_scan();
63         ao_log_start();
64
65         ao_rdf_set(1);
66
67         tracker_interval = ao_config.tracker_interval;
68         ao_gps_set_rate(tracker_interval);
69
70         for (;;) {
71
72                 /** Wait for new GPS data
73                  */
74                 while (!(new = ao_gps_new))
75                         ao_sleep(&ao_gps_new);
76                 ao_mutex_get(&ao_gps_mutex);
77                 gps_data = ao_gps_data;
78                 gps_tick = ao_gps_tick;
79                 ao_gps_new = 0;
80                 ao_mutex_put(&ao_gps_mutex);
81
82                 new_tracker_running = ao_tracker_force_telem || !ao_usb_connected();
83
84                 if (ao_config.tracker_interval != tracker_interval) {
85                         tracker_interval = ao_config.tracker_interval;
86                         ao_gps_set_rate(tracker_interval);
87
88                         /* force telemetry interval to be reset */
89                         tracker_running = 0;
90                 }
91
92                 if (new_tracker_running && !tracker_running) {
93                         ao_telemetry_set_interval(AO_SEC_TO_TICKS(tracker_interval));
94                 } else if (!new_tracker_running && tracker_running) {
95                         ao_telemetry_set_interval(0);
96                 }
97
98                 tracker_running = new_tracker_running;
99
100                 if (!tracker_running)
101                         continue;
102
103                 if (new & AO_GPS_NEW_DATA) {
104                         if ((gps_data.flags & (AO_GPS_VALID|AO_GPS_COURSE_VALID)) ==
105                             (AO_GPS_VALID|AO_GPS_COURSE_VALID))
106                         {
107                                 if (log_started) {
108                                         ground_distance = ao_distance(gps_data.latitude, gps_data.longitude,
109                                                                       last_log_latitude, last_log_longitude);
110                                         height = last_log_altitude - gps_data.altitude;
111                                         if (height < 0)
112                                                 height = -height;
113                                         if (ground_distance <= ao_config.tracker_motion &&
114                                             height <= ao_config.tracker_motion)
115                                         {
116                                                 if (unmoving < AO_TRACKER_MOTION_COUNT)
117                                                         unmoving++;
118                                         } else
119                                                 unmoving = 0;
120                                 }
121                         } else {
122                                 if (!log_started)
123                                         continue;
124                                 if (unmoving < AO_TRACKER_MOTION_COUNT)
125                                         unmoving++;
126                         }
127
128                         if (unmoving < AO_TRACKER_MOTION_COUNT) {
129                                 if (!log_started) {
130                                         ao_log_gps_flight();
131                                         log_started = 1;
132                                 }
133                                 ao_log_gps_data(gps_tick, &gps_data);
134                                 last_log_latitude = gps_data.latitude;
135                                 last_log_longitude = gps_data.longitude;
136                                 last_log_altitude = gps_data.altitude;
137                         }
138                 }
139         }
140 }
141
142 static struct ao_task ao_tracker_task;
143
144 static void
145 ao_tracker_set_telem(void)
146 {
147         uint8_t telem;
148         ao_cmd_hex();
149         telem = ao_cmd_lex_i;
150         if (ao_cmd_status == ao_cmd_success)
151                 ao_tracker_force_telem = telem;
152         ao_cmd_status = ao_cmd_success;
153         printf ("flight: %d\n", ao_flight_number);
154         printf ("force_telem: %d\n", ao_tracker_force_telem);
155         printf ("log_started: %d\n", log_started);
156         printf ("unmoving: %d\n", unmoving);
157         printf ("latitude: %ld\n", (long) gps_data.latitude);
158         printf ("longitude: %ld\n", (long) gps_data.longitude);
159         printf ("altitude: %d\n", gps_data.altitude);
160         printf ("log_running: %d\n", ao_log_running);
161         printf ("log_start_pos: %ld\n", (long) ao_log_start_pos);
162         printf ("log_cur_pos: %ld\n", (long) ao_log_current_pos);
163         printf ("log_end_pos: %ld\n", (long) ao_log_end_pos);
164 }
165
166 static const struct ao_cmds ao_tracker_cmds[] = {
167         { ao_tracker_set_telem, "t <d>\0Set telem on USB" },
168         { 0, NULL },
169 };
170
171 void
172 ao_tracker_init(void)
173 {
174 #if HAS_USB_CONNECT
175         ao_enable_input(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, 0);
176 #endif
177         ao_cmd_register(&ao_tracker_cmds[0]);
178         ao_add_task(&ao_tracker_task, ao_tracker, "tracker");
179 }