altos: Fix BT link status pin for real TBT hardware
[fw/altos] / altosui / AltosGPS.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 altosui;
19
20 import java.lang.*;
21 import java.text.*;
22
23 public class AltosGPS {
24         public class AltosGPSSat {
25                 int     svid;
26                 int     c_n0;
27         }
28
29         final static int MISSING = AltosRecord.MISSING;
30
31         int     nsat;
32         boolean locked;
33         boolean connected;
34         double  lat;            /* degrees (+N -S) */
35         double  lon;            /* degrees (+E -W) */
36         int     alt;            /* m */
37         int     year;
38         int     month;
39         int     day;
40         int     hour;
41         int     minute;
42         int     second;
43
44         double  ground_speed;   /* m/s */
45         int     course;         /* degrees */
46         double  climb_rate;     /* m/s */
47         double  hdop;           /* unitless */
48         double  vdop;           /* unitless */
49         int     h_error;        /* m */
50         int     v_error;        /* m */
51
52         AltosGPSSat[] cc_gps_sat;       /* tracking data */
53
54         void ParseGPSDate(String date) throws ParseException {
55                 String[] ymd = date.split("-");
56                 if (ymd.length != 3)
57                         throw new ParseException("error parsing GPS date " + date + " got " + ymd.length, 0);
58                 year = AltosParse.parse_int(ymd[0]);
59                 month = AltosParse.parse_int(ymd[1]);
60                 day = AltosParse.parse_int(ymd[2]);
61         }
62
63         void ParseGPSTime(String time) throws ParseException {
64                 String[] hms = time.split(":");
65                 if (hms.length != 3)
66                         throw new ParseException("Error parsing GPS time " + time + " got " + hms.length, 0);
67                 hour = AltosParse.parse_int(hms[0]);
68                 minute = AltosParse.parse_int(hms[1]);
69                 second = AltosParse.parse_int(hms[2]);
70         }
71
72         void ClearGPSTime() {
73                 year = month = day = 0;
74                 hour = minute = second = 0;
75         }
76
77         public AltosGPS(AltosTelemetryMap map) throws ParseException {
78                 String  state = map.get_string(AltosTelemetry.AO_TELEM_GPS_STATE,
79                                                AltosTelemetry.AO_TELEM_GPS_STATE_ERROR);
80
81                 nsat = map.get_int(AltosTelemetry.AO_TELEM_GPS_NUM_SAT, 0);
82                 if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_LOCKED)) {
83                         connected = true;
84                         locked = true;
85                         lat = map.get_double(AltosTelemetry.AO_TELEM_GPS_LATITUDE, MISSING, 1.0e-7);
86                         lon = map.get_double(AltosTelemetry.AO_TELEM_GPS_LONGITUDE, MISSING, 1.0e-7);
87                         alt = map.get_int(AltosTelemetry.AO_TELEM_GPS_ALTITUDE, MISSING);
88                         year = map.get_int(AltosTelemetry.AO_TELEM_GPS_YEAR, MISSING);
89                         if (year != MISSING)
90                                 year += 2000;
91                         month = map.get_int(AltosTelemetry.AO_TELEM_GPS_MONTH, MISSING);
92                         day = map.get_int(AltosTelemetry.AO_TELEM_GPS_DAY, MISSING);
93
94                         hour = map.get_int(AltosTelemetry.AO_TELEM_GPS_HOUR, 0);
95                         minute = map.get_int(AltosTelemetry.AO_TELEM_GPS_MINUTE, 0);
96                         second = map.get_int(AltosTelemetry.AO_TELEM_GPS_SECOND, 0);
97
98                         ground_speed = map.get_double(AltosTelemetry.AO_TELEM_GPS_HORIZONTAL_SPEED,
99                                                       AltosRecord.MISSING, 1/100.0);
100                         course = map.get_int(AltosTelemetry.AO_TELEM_GPS_COURSE,
101                                              AltosRecord.MISSING);
102                         hdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_HDOP, MISSING, 1.0);
103                         vdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_VDOP, MISSING, 1.0);
104                         h_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_HERROR, MISSING);
105                         v_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_VERROR, MISSING);
106                 } else if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_UNLOCKED)) {
107                         connected = true;
108                         locked = false;
109                 } else {
110                         connected = false;
111                         locked = false;
112                 }
113         }
114
115         public AltosGPS(String[] words, int i, int version) throws ParseException {
116                 AltosParse.word(words[i++], "GPS");
117                 nsat = AltosParse.parse_int(words[i++]);
118                 AltosParse.word(words[i++], "sat");
119
120                 connected = false;
121                 locked = false;
122                 lat = lon = 0;
123                 alt = 0;
124                 ClearGPSTime();
125                 if ((words[i]).equals("unlocked")) {
126                         connected = true;
127                         i++;
128                 } else if ((words[i]).equals("not-connected")) {
129                         i++;
130                 } else if (words.length >= 40) {
131                         locked = true;
132                         connected = true;
133
134                         if (version > 1)
135                                 ParseGPSDate(words[i++]);
136                         else
137                                 year = month = day = 0;
138                         ParseGPSTime(words[i++]);
139                         lat = AltosParse.parse_coord(words[i++]);
140                         lon = AltosParse.parse_coord(words[i++]);
141                         alt = AltosParse.parse_int(words[i++]);
142                         if (version > 1 || (i < words.length && !words[i].equals("SAT"))) {
143                                 ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)"));
144                                 course = AltosParse.parse_int(words[i++]);
145                                 climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)"));
146                                 hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)"));
147                                 h_error = AltosParse.parse_int(words[i++]);
148                                 v_error = AltosParse.parse_int(words[i++]);
149                         }
150                 } else {
151                         i++;
152                 }
153                 if (i < words.length) {
154                         AltosParse.word(words[i++], "SAT");
155                         int tracking_channels = 0;
156                         if (words[i].equals("not-connected"))
157                                 tracking_channels = 0;
158                         else
159                                 tracking_channels = AltosParse.parse_int(words[i]);
160                         i++;
161                         cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels];
162                         for (int chan = 0; chan < tracking_channels; chan++) {
163                                 cc_gps_sat[chan] = new AltosGPS.AltosGPSSat();
164                                 cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]);
165                                 /* Older versions included SiRF status bits */
166                                 if (version < 2)
167                                         i++;
168                                 cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]);
169                         }
170                 } else
171                         cc_gps_sat = new AltosGPS.AltosGPSSat[0];
172         }
173
174         public void set_latitude(int in_lat) {
175                 lat = in_lat / 10.0e7;
176         }
177
178         public void set_longitude(int in_lon) {
179                 lon = in_lon / 10.0e7;
180         }
181
182         public void set_time(int hour, int minute, int second) {
183                 hour = hour;
184                 minute = minute;
185                 second = second;
186         }
187
188         public void set_date(int year, int month, int day) {
189                 year = year;
190                 month = month;
191                 day = day;
192         }
193
194         public void set_flags(int flags) {
195                 flags = flags;
196         }
197
198         public void set_altitude(int altitude) {
199                 altitude = altitude;
200         }
201
202         public void add_sat(int svid, int c_n0) {
203                 if (cc_gps_sat == null) {
204                         cc_gps_sat = new AltosGPS.AltosGPSSat[1];
205                 } else {
206                         AltosGPSSat[] new_gps_sat = new AltosGPS.AltosGPSSat[cc_gps_sat.length + 1];
207                         for (int i = 0; i < cc_gps_sat.length; i++)
208                                 new_gps_sat[i] = cc_gps_sat[i];
209                         cc_gps_sat = new_gps_sat;
210                 }
211                 AltosGPS.AltosGPSSat    sat = new AltosGPS.AltosGPSSat();
212                 sat.svid = svid;
213                 sat.c_n0 = c_n0;
214                 cc_gps_sat[cc_gps_sat.length - 1] = sat;
215         }
216
217         public AltosGPS() {
218                 ClearGPSTime();
219                 cc_gps_sat = null;
220         }
221
222         public AltosGPS(AltosGPS old) {
223                 nsat = old.nsat;
224                 locked = old.locked;
225                 connected = old.connected;
226                 lat = old.lat;          /* degrees (+N -S) */
227                 lon = old.lon;          /* degrees (+E -W) */
228                 alt = old.alt;          /* m */
229                 year = old.year;
230                 month = old.month;
231                 day = old.day;
232                 hour = old.hour;
233                 minute = old.minute;
234                 second = old.second;
235
236                 ground_speed = old.ground_speed;        /* m/s */
237                 course = old.course;            /* degrees */
238                 climb_rate = old.climb_rate;    /* m/s */
239                 hdop = old.hdop;                /* unitless? */
240                 h_error = old.h_error;  /* m */
241                 v_error = old.v_error;  /* m */
242
243                 if (old.cc_gps_sat != null) {
244                         cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length];
245                         for (int i = 0; i < old.cc_gps_sat.length; i++) {
246                                 cc_gps_sat[i] = new AltosGPSSat();
247                                 cc_gps_sat[i].svid = old.cc_gps_sat[i].svid;
248                                 cc_gps_sat[i].c_n0 = old.cc_gps_sat[i].c_n0;
249                         }
250                 }
251         }
252 }