0a80ca6b83270e69e1bc3b58b309f9d3046b56dd
[fw/altos] / altoslib / AltosIdleMonitor.java
1 /*
2  * Copyright © 2010 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 package org.altusmetrum.altoslib;
19
20 import java.io.*;
21 import java.util.concurrent.*;
22
23
24 public class AltosIdleMonitor extends Thread {
25         AltosLink               link;
26         AltosIdleMonitorListener        listener;
27         AltosState              state;
28         boolean                 remote;
29         double                  frequency;
30         AltosState              previous_state;
31         AltosConfigData         config_data;
32         AltosGPS                gps;
33
34         int AltosRSSI() throws TimeoutException, InterruptedException {
35                 link.printf("s\n");
36                 String line = link.get_reply_no_dialog(5000);
37                 if (line == null)
38                         throw new TimeoutException();
39                 String[] items = line.split("\\s+");
40                 if (items.length < 2)
41                         return 0;
42                 if (!items[0].equals("RSSI:"))
43                         return 0;
44                 int rssi = Integer.parseInt(items[1]);
45                 return rssi;
46         }
47
48         boolean has_sensor_tm(AltosConfigData config_data) {
49                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMini");
50         }
51
52         boolean has_sensor_mm(AltosConfigData config_data) {
53                 return config_data.product.startsWith("MegaMetrum");
54         }
55
56         boolean has_gps(AltosConfigData config_data) {
57                 return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("MegaMetrum");
58         }
59
60         AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException {
61                 AltosRecordMM record_mm = new AltosRecordMM();
62                 AltosSensorMM sensor = new AltosSensorMM(link);
63                 AltosMs5607 ms5607 = new AltosMs5607Query(link);
64                 AltosIMU imu = new AltosIMUQuery(link);
65
66                 record_mm.accel_plus_g = config_data.accel_cal_plus;
67                 record_mm.accel_minus_g = config_data.accel_cal_minus;
68
69                 record_mm.ground_accel = sensor.accel;
70                 record_mm.accel = sensor.accel;
71                 record_mm.ground_pres = ms5607.pa;
72                 record_mm.pres = ms5607.pa;
73                 record_mm.temp = ms5607.cc;
74
75                 record_mm.v_batt = sensor.v_batt;
76                 record_mm.v_pyro = sensor.v_pyro;
77                 record_mm.sense = sensor.sense;
78
79                 record_mm.imu = imu;
80
81                 return record_mm;
82         }
83
84         void update_state() throws InterruptedException, TimeoutException {
85                 AltosRecord     record = null;
86
87                 try {
88                         if (remote) {
89                                 link.set_radio_frequency(frequency);
90                                 link.start_remote();
91                         } else
92                                 link.flush_input();
93                         config_data = new AltosConfigData(link);
94
95                         if (has_sensor_tm(config_data))
96                                 record = new AltosSensorTM(link, config_data);
97                         else if (has_sensor_mm(config_data))
98                                 record = sensor_mm(config_data);
99                         else
100                                 record = new AltosRecordNone();
101
102                         if (has_gps(config_data))
103                                 gps = new AltosGPSQuery(link, config_data);
104
105                         record.version = 0;
106                         record.callsign = config_data.callsign;
107                         record.serial = config_data.serial;
108                         record.flight = config_data.log_available() > 0 ? 255 : 0;
109                         record.status = 0;
110                         record.state = AltosLib.ao_flight_idle;
111                         record.gps = gps;
112                         record.new_gps = true;
113                         state = new AltosState (record, state);
114                 } finally {
115                         if (remote) {
116                                 link.stop_remote();
117                                 if (record != null)
118                                         record.rssi = AltosRSSI();
119                         } else {
120                                 if (record != null)
121                                         record.rssi = 0;
122                         }
123                 }
124
125         }
126
127         public void set_frequency(double in_frequency) {
128                 frequency = in_frequency;
129         }
130
131         public void post_state() {
132                 listener.update(state);
133         }
134
135         public void run() {
136                 try {
137                         for (;;) {
138                                 try {
139                                         update_state();
140                                         post_state();
141                                 } catch (TimeoutException te) {
142                                 }
143                                 Thread.sleep(1000);
144                         }
145                 } catch (InterruptedException ie) {
146                         link.close();
147                 }
148         }
149
150         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
151                 throws FileNotFoundException, InterruptedException, TimeoutException {
152                 listener = in_listener;
153                 link = in_link;
154                 remote = in_remote;
155                 state = null;
156         }
157 }