- void show(AltosState state, int crc_errors) {
- if (state != null) {
- flightStatus.set(state);
- flightInfo.show(state, crc_errors);
- }
- }
-
- class IdleThread extends Thread {
-
- boolean started;
- private AltosState state;
- int reported_landing;
- int report_interval;
- long report_time;
-
- public synchronized void report(boolean last) {
- if (state == null)
- return;
-
- /* reset the landing count once we hear about a new flight */
- if (state.state < Altos.ao_flight_drogue)
- reported_landing = 0;
-
- /* Shut up once the rocket is on the ground */
- if (reported_landing > 2) {
- return;
- }
-
- /* If the rocket isn't on the pad, then report height */
- if (Altos.ao_flight_drogue <= state.state &&
- state.state < Altos.ao_flight_landed &&
- state.range >= 0)
- {
- voice.speak("Height %d, bearing %d, elevation %d, range %d.\n",
- (int) (state.height + 0.5),
- (int) (state.from_pad.bearing + 0.5),
- (int) (state.elevation + 0.5),
- (int) (state.range + 0.5));
- } else if (state.state > Altos.ao_flight_pad) {
- voice.speak("%d meters", (int) (state.height + 0.5));
- } else {
- reported_landing = 0;
- }
-
- /* If the rocket is coming down, check to see if it has landed;
- * either we've got a landed report or we haven't heard from it in
- * a long time
- */
- if (state.state >= Altos.ao_flight_drogue &&
- (last ||
- System.currentTimeMillis() - state.report_time >= 15000 ||
- state.state == Altos.ao_flight_landed))
- {
- if (Math.abs(state.baro_speed) < 20 && state.height < 100)
- voice.speak("rocket landed safely");
- else
- voice.speak("rocket may have crashed");
- if (state.from_pad != null)
- voice.speak("Bearing %d degrees, range %d meters.",
- (int) (state.from_pad.bearing + 0.5),
- (int) (state.from_pad.distance + 0.5));
- ++reported_landing;
- }
- }
-
- long now () {
- return System.currentTimeMillis();
- }
-
- void set_report_time() {
- report_time = now() + report_interval;
- }
-
- public void run () {
-
- reported_landing = 0;
- state = null;
- report_interval = 10000;
- try {
- for (;;) {
- set_report_time();
- for (;;) {
- voice.drain();
- synchronized (this) {
- long sleep_time = report_time - now();
- if (sleep_time <= 0)
- break;
- wait(sleep_time);
- }
- }
- report(false);
- }
- } catch (InterruptedException ie) {
- try {
- voice.drain();
- } catch (InterruptedException iie) { }
- }
- }
-
- public synchronized void notice(AltosState new_state, boolean spoken) {
- AltosState old_state = state;
- state = new_state;
- if (!started && state.state > Altos.ao_flight_pad) {
- started = true;
- start();
- }
-
- if (state.state < Altos.ao_flight_drogue)
- report_interval = 10000;
- else
- report_interval = 20000;
- if (old_state != null && old_state.state != state.state) {
- report_time = now();
- this.notify();
- } else if (spoken)
- set_report_time();
- }
- }
-
- private boolean tell(AltosState state, AltosState old_state) {
- boolean ret = false;
- if (old_state == null || old_state.state != state.state) {
- voice.speak(state.data.state());
- if ((old_state == null || old_state.state <= Altos.ao_flight_boost) &&
- state.state > Altos.ao_flight_boost) {
- voice.speak("max speed: %d meters per second.",
- (int) (state.max_speed + 0.5));
- ret = true;
- } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) &&
- state.state >= Altos.ao_flight_drogue) {
- voice.speak("max height: %d meters.",
- (int) (state.max_height + 0.5));
- ret = true;
- }
- }
- if (old_state == null || old_state.gps_ready != state.gps_ready) {
- if (state.gps_ready) {
- voice.speak("GPS ready");
- ret = true;
- }
- else if (old_state != null) {
- voice.speak("GPS lost");
- ret = true;
- }
- }
- old_state = state;
- return ret;
- }
-
- class DisplayThread extends Thread {
- IdleThread idle_thread;
-
- String name;
-
- int crc_errors;
-
- void init() { }
-
- AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; }
-
- void close(boolean interrupted) { }
-
- void update(AltosState state) throws InterruptedException { }
-
- public void run() {
- boolean interrupted = false;
- String line;
- AltosState state = null;
- AltosState old_state = null;
- boolean told;
-
- idle_thread = new IdleThread();
-
- flightInfo.clear();
- try {
- for (;;) {
- try {
- AltosRecord record = read();
- if (record == null)
- break;
- old_state = state;
- state = new AltosState(record, state);
- update(state);
- show(state, crc_errors);
- told = tell(state, old_state);
- idle_thread.notice(state, told);
- } catch (ParseException pp) {
- System.out.printf("Parse error: %d \"%s\"\n", pp.getErrorOffset(), pp.getMessage());
- } catch (AltosCRCException ce) {
- ++crc_errors;
- show(state, crc_errors);
- }
- }
- } catch (InterruptedException ee) {
- interrupted = true;
- } catch (IOException ie) {
- JOptionPane.showMessageDialog(AltosUI.this,
- String.format("Error reading from \"%s\"", name),
- "Telemetry Read Error",
- JOptionPane.ERROR_MESSAGE);
- } finally {
- close(interrupted);
- idle_thread.interrupt();
- try {
- idle_thread.join();
- } catch (InterruptedException ie) {}
- }
- }
-
- public void report() {
- if (idle_thread != null)
- idle_thread.report(true);
- }
- }
-
- class DeviceThread extends DisplayThread {