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