58d34abeb0e738dca8bcc0964fef69f650f41604
[fw/altos] / altoslib / AltosCalData.java
1 /*
2  * Copyright © 2017 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, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 package org.altusmetrum.altoslib_11;
16
17 /*
18  * Calibration and other data needed to construct 'real' values from various data
19  * sources.
20  */
21
22 public class AltosCalData {
23         public int              flight = AltosLib.MISSING;
24
25         public void set_flight(int flight) {
26                 if (flight != AltosLib.MISSING)
27                         this.flight = flight;
28         }
29
30         public String           callsign = null;
31
32         public void set_callsign(String callsign) {
33                 if (callsign != null)
34                         this.callsign = callsign;
35         }
36
37         public String           firmware_version = null;
38
39         public void set_firmware_version(String firmware_version) {
40                 if (firmware_version != null)
41                         this.firmware_version = firmware_version;
42         }
43
44         public String           product = null;
45
46         public void set_product(String product) {
47                 if (product != null)
48                         this.product = product;
49         }
50
51         public int              serial = AltosLib.MISSING;
52
53         public void set_serial(int serial) {
54                 if (serial != AltosLib.MISSING)
55                         this.serial = serial;
56         }
57
58         public int              receiver_serial = AltosLib.MISSING;
59
60         public void set_receiver_serial(int receiver_serial) {
61                 if (receiver_serial != AltosLib.MISSING)
62                         this.receiver_serial = receiver_serial;
63         }
64
65         public int              device_type = AltosLib.MISSING;
66
67         public void set_device_type(int device_type) {
68                 if (device_type != AltosLib.MISSING)
69                         this.device_type = device_type;
70         }
71
72         public int              config_major = AltosLib.MISSING;
73         public int              config_minor = AltosLib.MISSING;
74         public int              flight_log_max = AltosLib.MISSING;
75
76         public void set_config(int major, int minor, int log_max) {
77                 if (major != AltosLib.MISSING)
78                         config_major = major;
79                 if (minor != AltosLib.MISSING)
80                         config_minor = minor;
81                 if (log_max != AltosLib.MISSING)
82                         flight_log_max = log_max;
83         }
84
85         public double           apogee_delay = AltosLib.MISSING;
86         public double           main_deploy = AltosLib.MISSING;
87
88         public void set_flight_params(double apogee_delay, double main_deploy) {
89                 if (apogee_delay != AltosLib.MISSING)
90                         this.apogee_delay = apogee_delay;
91                 if (main_deploy != AltosLib.MISSING)
92                         this.main_deploy = main_deploy;
93         }
94
95         public double           accel_plus_g = AltosLib.MISSING;
96         public double           accel_minus_g = AltosLib.MISSING;
97         public double           ground_accel = AltosLib.MISSING;
98
99         public void set_accel_plus_minus(double plus, double minus) {
100                 if (plus != AltosLib.MISSING && minus != AltosLib.MISSING) {
101                         accel_plus_g = plus;
102                         accel_minus_g = minus;
103                 }
104         }
105
106         public void set_ground_accel(double ground_accel) {
107                 if (ground_accel != AltosLib.MISSING)
108                         this.ground_accel = ground_accel;
109         }
110
111         /* Raw acceleration value */
112         public double           accel = AltosLib.MISSING;
113
114         public void set_accel(double accel) {
115                 this.accel = accel;
116         }
117
118         public boolean mma655x_inverted = false;
119
120         public void set_mma655x_inverted(boolean inverted) {
121                 mma655x_inverted = inverted;
122         }
123
124         public int pad_orientation = AltosLib.MISSING;
125
126         public void set_pad_orientation(int orientation) {
127                 if (orientation != AltosLib.MISSING)
128                         pad_orientation = orientation;
129         }
130
131         /* Compute acceleration */
132         public double acceleration(double sensor) {
133                 return AltosConvert.acceleration_from_sensor(sensor, accel_plus_g, accel_minus_g, ground_accel);
134         }
135
136         public AltosMs5607      ms5607 = null;
137
138         public void set_ms5607(AltosMs5607 ms5607) {
139                 this.ms5607 = ms5607;
140         }
141
142         public double           ground_pressure = AltosLib.MISSING;
143         public double           ground_altitude = AltosLib.MISSING;
144
145         public void set_ground_pressure(double ground_pressure) {
146                 if (ground_pressure != AltosLib.MISSING) {
147                         this.ground_pressure = ground_pressure;
148                         this.ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure);
149                 }
150         }
151
152         public void set_ground_altitude(double ground_altitude) {
153                 if (ground_altitude != AltosLib.MISSING)
154                         this.ground_altitude = ground_altitude;
155         }
156
157         /* Compute pressure */
158
159         public AltosPresTemp pressure_ms5607(int raw_pres, int raw_temp) {
160                 if (ms5607 == null)
161                         return new AltosPresTemp(AltosLib.MISSING, AltosLib.MISSING);
162                 return ms5607.pres_temp(raw_pres, raw_temp);
163         }
164
165         public int              tick = AltosLib.MISSING;
166         private int             prev_tick = AltosLib.MISSING;
167
168         public void set_tick(int tick) {
169                 if (tick != AltosLib.MISSING) {
170                         if (prev_tick != AltosLib.MISSING) {
171                                 while (tick < prev_tick - 1000) {
172                                         tick += 65536;
173                                 }
174                         }
175                         this.tick = tick;
176                 }
177         }
178
179         public int              boost_tick = AltosLib.MISSING;
180
181         public void set_boost_tick() {
182                 boost_tick = tick;
183         }
184
185         public double time() {
186                 if (tick == AltosLib.MISSING)
187                         return AltosLib.MISSING;
188                 if (boost_tick == AltosLib.MISSING)
189                         return AltosLib.MISSING;
190                 return (tick - boost_tick) / 100.0;
191         }
192
193         public double boost_time() {
194                 if (boost_tick == AltosLib.MISSING)
195                         return AltosLib.MISSING;
196                 return boost_tick / 100.0;
197         }
198
199         public int              state = AltosLib.MISSING;
200
201         public void set_state(int state) {
202                 if (state >= AltosLib.ao_flight_boost && boost_tick == AltosLib.MISSING)
203                         set_boost_tick();
204                 this.state = state;
205         }
206
207         public double           gps_ground_altitude = AltosLib.MISSING;
208
209         public void set_gps_altitude(double altitude) {
210                 if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) ||
211                     gps_ground_altitude == AltosLib.MISSING)
212                         gps_ground_altitude = altitude;
213         }
214
215         /*
216          * While receiving GPS data, we construct a temporary GPS state
217          * object and then deliver the result atomically to the listener
218          */
219         AltosGPS                temp_gps = null;
220         int                     temp_gps_sat_tick = AltosLib.MISSING;
221
222         public AltosGPS temp_gps() {
223                 return temp_gps;
224         }
225
226         public void reset_temp_gps() {
227                 if (temp_gps != null) {
228                         if (temp_gps.locked && temp_gps.nsat >= 4)
229                                 set_gps_altitude(temp_gps.alt);
230                 }
231                 temp_gps = null;
232         }
233
234         public boolean gps_pending() {
235                 return temp_gps != null;
236         }
237
238         public AltosGPS make_temp_gps(int tick, boolean sats) {
239                 if (temp_gps == null) {
240                         temp_gps = new AltosGPS();
241                 }
242                 if (sats) {
243                         if (tick != temp_gps_sat_tick)
244                                 temp_gps.cc_gps_sat = null;
245                         temp_gps_sat_tick = tick;
246                 }
247                 return temp_gps;
248         }
249
250         public double   accel_zero_along, accel_zero_across, accel_zero_through;
251
252         public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
253                 if (zero_along != AltosLib.MISSING) {
254                         accel_zero_along = zero_along;
255                         accel_zero_across = zero_across;
256                         accel_zero_through = zero_through;
257                 }
258         }
259
260         public double accel_along(double counts) {
261                 return AltosIMU.convert_accel(counts - accel_zero_along);
262         }
263
264         public double accel_across(double counts) {
265                 return AltosIMU.convert_accel(counts - accel_zero_across);
266         }
267
268         public double accel_through(double counts) {
269                 return AltosIMU.convert_accel(counts - accel_zero_through);
270         }
271
272         public double   gyro_zero_roll, gyro_zero_pitch, gyro_zero_yaw;
273
274         public void set_gyro_zero(double roll, double pitch, double yaw) {
275                 if (roll != AltosLib.MISSING) {
276                         gyro_zero_roll = roll;
277                         gyro_zero_pitch = pitch;
278                         gyro_zero_yaw = yaw;
279                 }
280         }
281
282         public double gyro_roll(double counts) {
283                 if (gyro_zero_roll == AltosLib.MISSING || counts == AltosLib.MISSING)
284                         return AltosLib.MISSING;
285                 return AltosIMU.convert_gyro(counts - gyro_zero_roll);
286         }
287
288         public double gyro_pitch(double counts) {
289                 if (gyro_zero_pitch == AltosLib.MISSING || counts == AltosLib.MISSING)
290                         return AltosLib.MISSING;
291                 return AltosIMU.convert_gyro(counts - gyro_zero_pitch);
292         }
293
294         public double gyro_yaw(double counts) {
295                 if (gyro_zero_yaw == AltosLib.MISSING || counts == AltosLib.MISSING)
296                         return AltosLib.MISSING;
297                 return AltosIMU.convert_gyro(counts - gyro_zero_yaw);
298         }
299
300         private double gyro_zero_overflow(double first) {
301                 double v = first / 128.0;
302                 if (v < 0)
303                         v = Math.ceil(v);
304                 else
305                         v = Math.floor(v);
306                 return v * 128.0;
307         }
308
309         public void check_imu_wrap(double roll, double pitch, double yaw) {
310                 gyro_zero_roll += gyro_zero_overflow(roll);
311                 gyro_zero_pitch += gyro_zero_overflow(pitch);
312                 gyro_zero_yaw += gyro_zero_overflow(yaw);
313         }
314
315         public double mag_along(double along) {
316                 if (along == AltosLib.MISSING)
317                         return AltosLib.MISSING;
318                 return AltosMag.convert_gauss(along);
319         }
320
321         public double mag_across(double across) {
322                 if (across == AltosLib.MISSING)
323                         return AltosLib.MISSING;
324                 return AltosMag.convert_gauss(across);
325         }
326
327         public double mag_through(double through) {
328                 if (through == AltosLib.MISSING)
329                         return AltosLib.MISSING;
330                 return AltosMag.convert_gauss(through);
331         }
332
333         public AltosCalData() {
334         }
335
336         public AltosCalData(AltosConfigData config_data) {
337                 set_serial(config_data.serial);
338                 set_flight(config_data.flight);
339                 set_callsign(config_data.callsign);
340                 set_accel_plus_minus(config_data.accel_cal_plus, config_data.accel_cal_minus);
341                 set_ms5607(config_data.ms5607);
342                 try {
343                         set_mma655x_inverted(config_data.mma655x_inverted());
344                 } catch (AltosUnknownProduct up) {
345                 }
346                 set_pad_orientation(config_data.pad_orientation);
347         }
348 }