Merge branch 'master' of git://git.gag.com/fw/altos
[fw/altos] / ao-tools / 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 import altosui.AltosParse;
23
24
25 public class AltosGPS {
26         public class AltosGPSSat {
27                 int     svid;
28                 int     c_n0;
29         }
30
31         int     nsat;
32         boolean locked;
33         boolean connected;
34         boolean date_valid;
35         double  lat;            /* degrees (+N -S) */
36         double  lon;            /* degrees (+E -W) */
37         int     alt;            /* m */
38         int     year;
39         int     month;
40         int     day;
41         int     hour;
42         int     minute;
43         int     second;
44
45         int     gps_extended;   /* has extra data */
46         double  ground_speed;   /* m/s */
47         int     course;         /* degrees */
48         double  climb_rate;     /* m/s */
49         double  hdop;           /* unitless? */
50         int     h_error;        /* m */
51         int     v_error;        /* m */
52
53         AltosGPSSat[] cc_gps_sat;       /* tracking data */
54
55         void ParseGPSDate(String date) throws ParseException {
56                 String[] ymd = date.split("-");
57                 if (ymd.length != 3)
58                         throw new ParseException("error parsing GPS date " + date + " got " + ymd.length, 0);
59                 year = AltosParse.parse_int(ymd[0]);
60                 month = AltosParse.parse_int(ymd[1]);
61                 day = AltosParse.parse_int(ymd[2]);
62         }
63
64         void ParseGPSTime(String time) throws ParseException {
65                 String[] hms = time.split(":");
66                 if (hms.length != 3)
67                         throw new ParseException("Error parsing GPS time " + time + " got " + hms.length, 0);
68                 hour = AltosParse.parse_int(hms[0]);
69                 minute = AltosParse.parse_int(hms[1]);
70                 second = AltosParse.parse_int(hms[2]);
71         }
72
73         void ClearGPSTime() {
74                 year = month = day = 0;
75                 hour = minute = second = 0;
76         }
77
78         public AltosGPS(String[] words, int i, int version) throws ParseException {
79                 AltosParse.word(words[i++], "GPS");
80                 nsat = AltosParse.parse_int(words[i++]);
81                 AltosParse.word(words[i++], "sat");
82
83                 connected = false;
84                 locked = false;
85                 lat = lon = 0;
86                 alt = 0;
87                 ClearGPSTime();
88                 if ((words[i]).equals("unlocked")) {
89                         connected = true;
90                         i++;
91                 } else if ((words[i]).equals("not-connected")) {
92                         i++;
93                 } else if (words.length >= 40) {
94                         locked = true;
95                         connected = true;
96
97                         if (version > 1)
98                                 ParseGPSDate(words[i++]);
99                         else
100                                 year = month = day = 0;
101                         ParseGPSTime(words[i++]);
102                         lat = AltosParse.parse_coord(words[i++]);
103                         lon = AltosParse.parse_coord(words[i++]);
104                         alt = AltosParse.parse_int(words[i++]);
105                         if (version > 1 || (i < words.length && !words[i].equals("SAT"))) {
106                                 ground_speed = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(H)"));
107                                 course = AltosParse.parse_int(words[i++]);
108                                 climb_rate = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "m/s(V)"));
109                                 hdop = AltosParse.parse_double(AltosParse.strip_suffix(words[i++], "(hdop)"));
110                                 h_error = AltosParse.parse_int(words[i++]);
111                                 v_error = AltosParse.parse_int(words[i++]);
112                         }
113                 } else {
114                         i++;
115                 }
116                 if (i < words.length) {
117                         AltosParse.word(words[i++], "SAT");
118                         int tracking_channels = 0;
119                         if (words[i].equals("not-connected"))
120                                 tracking_channels = 0;
121                         else
122                                 tracking_channels = AltosParse.parse_int(words[i]);
123                         i++;
124                         cc_gps_sat = new AltosGPS.AltosGPSSat[tracking_channels];
125                         for (int chan = 0; chan < tracking_channels; chan++) {
126                                 cc_gps_sat[chan] = new AltosGPS.AltosGPSSat();
127                                 cc_gps_sat[chan].svid = AltosParse.parse_int(words[i++]);
128                                 /* Older versions included SiRF status bits */
129                                 if (version < 2)
130                                         i++;
131                                 cc_gps_sat[chan].c_n0 = AltosParse.parse_int(words[i++]);
132                         }
133                 } else
134                         cc_gps_sat = new AltosGPS.AltosGPSSat[0];
135         }
136
137         public void set_latitude(int in_lat) {
138                 lat = in_lat / 10.0e7;
139         }
140
141         public void set_longitude(int in_lon) {
142                 lon = in_lon / 10.0e7;
143         }
144
145         public void set_time(int hour, int minute, int second) {
146                 hour = hour;
147                 minute = minute;
148                 second = second;
149         }
150
151         public void set_date(int year, int month, int day) {
152                 year = year;
153                 month = month;
154                 day = day;
155         }
156
157         public void set_flags(int flags) {
158                 flags = flags;
159         }
160
161         public void set_altitude(int altitude) {
162                 altitude = altitude;
163         }
164
165         public void add_sat(int svid, int c_n0) {
166                 if (cc_gps_sat == null) {
167                         cc_gps_sat = new AltosGPS.AltosGPSSat[1];
168                 } else {
169                         AltosGPSSat[] new_gps_sat = new AltosGPS.AltosGPSSat[cc_gps_sat.length + 1];
170                         for (int i = 0; i < cc_gps_sat.length; i++)
171                                 new_gps_sat[i] = cc_gps_sat[i];
172                         cc_gps_sat = new_gps_sat;
173                 }
174                 AltosGPS.AltosGPSSat    sat = new AltosGPS.AltosGPSSat();
175                 sat.svid = svid;
176                 sat.c_n0 = c_n0;
177                 cc_gps_sat[cc_gps_sat.length - 1] = sat;
178         }
179
180         public AltosGPS() {
181                 ClearGPSTime();
182                 cc_gps_sat = null;
183         }
184
185         public AltosGPS(AltosGPS old) {
186                 nsat = old.nsat;
187                 locked = old.locked;
188                 connected = old.connected;
189                 date_valid = old.date_valid;
190                 lat = old.lat;          /* degrees (+N -S) */
191                 lon = old.lon;          /* degrees (+E -W) */
192                 alt = old.alt;          /* m */
193                 year = old.year;
194                 month = old.month;
195                 day = old.day;
196                 hour = old.hour;
197                 minute = old.minute;
198                 second = old.second;
199
200                 gps_extended = old.gps_extended;        /* has extra data */
201                 ground_speed = old.ground_speed;        /* m/s */
202                 course = old.course;            /* degrees */
203                 climb_rate = old.climb_rate;    /* m/s */
204                 hdop = old.hdop;                /* unitless? */
205                 h_error = old.h_error;  /* m */
206                 v_error = old.v_error;  /* m */
207
208                 if (old.cc_gps_sat != null) {
209                         cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length];
210                         for (int i = 0; i < old.cc_gps_sat.length; i++) {
211                                 cc_gps_sat[i] = new AltosGPSSat();
212                                 cc_gps_sat[i].svid = old.cc_gps_sat[i].svid;
213                                 cc_gps_sat[i].c_n0 = old.cc_gps_sat[i].c_n0;
214                         }
215                 }
216         }
217 }