altoslib: Report whether GPS data contains new location/sat info
[fw/altos] / altoslib / AltosReplayReader.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; 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  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 package org.altusmetrum.altoslib_13;
20
21 import java.io.*;
22 import java.util.*;
23 import java.util.concurrent.*;
24
25 /*
26  * Open an existing telemetry file and replay it in realtime
27  */
28
29 class AltosReplay extends AltosDataListener implements Runnable {
30
31         AltosState      state;
32         AltosRecordSet  record_set;
33         double          last_time = AltosLib.MISSING;
34         Semaphore       semaphore = new Semaphore(1);
35         boolean         done = false;
36
37         public void set_time(double time) {
38                 if (last_time != AltosLib.MISSING) {
39                         semaphore.release();
40                         double  delay = Math.min(time - last_time,10);
41                         if (delay > 0) {
42                                 try {
43                                         Thread.sleep((int) (delay * 1000));
44                                 } catch (InterruptedException ie) {
45                                 }
46                         }
47                 }
48                 last_time = time;
49                 super.set_time(time);
50                 state.set_time(time);
51         }
52
53         public void set_state(int state) {
54                 super.set_state(state);
55                 this.state.set_state(state);
56         }
57
58         public void set_rssi(int rssi, int status) { state.set_rssi(rssi, status); }
59         public void set_received_time(long received_time) { }
60
61         public void set_acceleration(double accel) { state.set_acceleration(accel); }
62         public void set_pressure(double pa) { state.set_pressure(pa); }
63         public void set_thrust(double N) { state.set_thrust(N); }
64
65         public void set_kalman(double height, double speed, double accel) { state.set_kalman(height, speed, accel); }
66
67         public void set_temperature(double deg_c) { state.set_temperature(deg_c); }
68         public void set_battery_voltage(double volts) { state.set_battery_voltage(volts); }
69
70         public void set_apogee_voltage(double volts) { state.set_apogee_voltage(volts); }
71         public void set_main_voltage(double volts) { state.set_main_voltage(volts); }
72
73         public void set_gps(AltosGPS gps, boolean set_location, boolean set_sats) {
74                 super.set_gps(gps, set_location, set_sats);
75                 state.set_gps(gps, set_location, set_sats);
76         }
77
78         public void set_orient(double orient) { state.set_orient(orient); }
79         public void set_gyro(double roll, double pitch, double yaw) { state.set_gyro(roll, pitch, yaw); }
80         public void set_accel_ground(double along, double across, double through) { state.set_accel_ground(along, across, through); }
81         public void set_accel(double along, double across, double through) { state.set_accel(along, across, through); }
82         public void set_mag(double along, double across, double through) { state.set_mag(along, across, through); }
83         public void set_pyro_voltage(double volts) { state.set_pyro_voltage(volts); }
84         public void set_igniter_voltage(double[] voltage) { state.set_igniter_voltage(voltage); }
85         public void set_pyro_fired(int pyro_mask) { state.set_pyro_fired(pyro_mask); }
86         public void set_companion(AltosCompanion companion) { state.set_companion(companion); }
87
88         public void run () {
89                 /* Run the flight */
90                 record_set.capture_series(this);
91                 /* All done, signal that it's over */
92                 done = true;
93                 semaphore.release();
94         }
95
96         public AltosReplay(AltosRecordSet record_set) {
97                 super(record_set.cal_data());
98                 state = new AltosState(record_set.cal_data());
99                 this.record_set = record_set;
100                 try {
101                         semaphore.acquire();
102                 } catch (InterruptedException ie) {
103                 }
104         }
105 }
106
107 public class AltosReplayReader extends AltosFlightReader {
108         File            file;
109         AltosReplay     replay;
110         Thread          t;
111         int             reads;
112
113         public AltosCalData cal_data() {
114                 return replay.state.cal_data();
115         }
116
117         public AltosState read() {
118                 switch (reads) {
119                 case 0:
120                         /* Tell the display that we're in pad mode */
121                         replay.state.set_state(AltosLib.ao_flight_pad);
122                         break;
123                 case 1:
124                         t = new Thread(replay);
125                         t.start();
126                         /* fall through */
127                 default:
128                         /* Wait for something to change */
129                         try {
130                                 replay.semaphore.acquire();
131                         } catch (InterruptedException ie) {
132                         }
133                         break;
134                 }
135                 reads++;
136
137                 /* When done, let the display know */
138                 if (replay.done)
139                         return null;
140
141                 /* Fake out the received time */
142                 replay.state.set_received_time(System.currentTimeMillis());
143                 return replay.state;
144         }
145
146         public void close (boolean interrupted) {
147         }
148
149         public File backing_file() { return file; }
150
151         public AltosReplayReader(AltosRecordSet record_set, File in_file) {
152                 reads = 0;
153                 file = in_file;
154                 name = file.getName();
155                 replay = new AltosReplay(record_set);
156         }
157 }