</RelativeLayout>
<RelativeLayout
- android:id="@+id/state_container"
+ android:id="@+id/rssi_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_toRightOf="@+id/strut" >
+ android:layout_toRightOf="@id/strut"
+ android:layout_alignParentRight="true" >
+
+ <TextView
+ android:id="@+id/rssi_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rssi_label" />
+
+ <TextView
+ android:id="@+id/rssi_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@+id/rssi_label"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/serial_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/callsign_container"
+ android:layout_toLeftOf="@+id/strut" >
+
+ <TextView
+ android:id="@+id/serial_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/serial_label" />
+
+ <TextView
+ android:id="@+id/serial_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@+id/serial_label"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/flight_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/callsign_container"
+ android:layout_toRightOf="@+id/strut"
+ android:layout_alignParentRight="true" >
+
+ <TextView
+ android:id="@+id/flight_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/flight_label" />
+
+ <TextView
+ android:id="@+id/flight_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@+id/flight_label"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/state_container"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/serial_container" >
<TextView
android:id="@+id/state_label"
android:id="@+id/state_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
android:layout_below="@+id/state_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:layout_centerInParent="true"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textSize="50dip" />
</RelativeLayout>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
- android:layout_below="@+id/callsign_container"
+ android:layout_below="@+id/state_container"
android:layout_toLeftOf="@+id/strut" >
<TextView
android:id="@+id/speed_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
android:layout_below="@id/speed_label"
- android:layout_toLeftOf="@+id/speed_units"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
- <TextView
- android:id="@+id/speed_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@id/speed_value"
- android:layout_alignParentRight="true"
- android:layout_below="@id/speed_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/speed_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
</RelativeLayout>
<RelativeLayout
android:id="@+id/accel_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
android:layout_below="@+id/accel_label"
- android:layout_toLeftOf="@+id/accel_units"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
- <TextView
- android:id="@+id/accel_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/accel_value"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/accel_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/accel_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/range_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
android:layout_below="@+id/range_label"
- android:layout_toLeftOf="@+id/range_units"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
- <TextView
- android:id="@+id/range_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/range_value"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/range_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/range_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
</RelativeLayout>
<RelativeLayout
- android:id="@+id/altitude_container"
+ android:id="@+id/height_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:layout_below="@id/accel_container"
+ android:layout_below="@id/speed_container"
android:layout_toRightOf="@id/strut" >
<TextView
- android:id="@+id/altitude_label"
+ android:id="@+id/height_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/altitude_label" />
+ android:text="@string/height_label" />
<TextView
- android:id="@+id/altitude_value"
+ android:id="@+id/height_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_below="@+id/altitude_label"
- android:layout_toLeftOf="@+id/altitude_units"
+ android:layout_alignParentRight="true"
+ android:layout_below="@+id/height_label"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <TextView
- android:id="@+id/altitude_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/altitude_value"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/altitude_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/altitude_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<RelativeLayout
- android:id="@+id/azimuth_container"
+ android:id="@+id/elevation_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@id/strut" >
<TextView
- android:id="@+id/azimuth_label"
+ android:id="@+id/elevation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/azimuth_label" />
+ android:text="@string/elevation_label" />
<TextView
- android:id="@+id/azimuth_value"
+ android:id="@+id/elevation_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_below="@+id/azimuth_label"
- android:layout_toLeftOf="@+id/azimuth_units"
+ android:layout_alignParentRight="true"
+ android:layout_below="@+id/elevation_label"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <TextView
- android:id="@+id/azimuth_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/azimuth_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/azimuth_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:layout_below="@+id/altitude_container"
+ android:layout_below="@+id/range_container"
android:layout_toRightOf="@+id/strut" >
<TextView
android:id="@+id/bearing_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
android:layout_below="@+id/bearing_label"
- android:layout_toLeftOf="@+id/bearing_units"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
- <TextView
- android:id="@+id/bearing_units"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/bearing_label"
- android:gravity="right"
- android:paddingLeft="10dip"
- android:text="@string/bearing_units"
- android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/latitude_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_below="@+id/azimuth_container" >
+ android:layout_below="@+id/elevation_container" >
<TextView
android:id="@+id/latitude_label"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
-
- <TextView
+
+
+ <TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_alignParentBottom="true"
- android:layout_below="@id/longitude_container"
+ android:layout_below="@+id/longitude_container"
android:gravity="bottom"
android:scrollbars="vertical"
android:textSize="7dp"
<!-- UI fields -->
<string name="callsign_label">Callsign</string>
+ <string name="serial_label">Serial no.</string>
+ <string name="flight_label">Flight no.</string>
+ <string name="rssi_label">RSSI</string>
<string name="state_label">State</string>
<string name="speed_label">Speed</string>
- <string name="speed_units">m/s</string>
<string name="accel_label">Acceleration</string>
- <string name="accel_units">m/s²</string>
<string name="range_label">Range</string>
- <string name="range_units">m</string>
- <string name="altitude_label">Altitude</string>
- <string name="altitude_units">m</string>
- <string name="azimuth_label">Azimuth</string>
- <string name="azimuth_units">°</string>
+ <string name="height_label">Height</string>
+ <string name="elevation_label">Elevation</string>
<string name="bearing_label">Bearing</string>
- <string name="bearing_units">°</string>
<string name="latitude_label">Latitude</string>
<string name="longitude_label">Longitude</string>
-
</resources>
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.speech.tts.TextToSpeech;
-import android.speech.tts.TextToSpeech.OnInitListener;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
// Layout Views
private TextView mTitle;
- private TextView mSerialView;
+
+ // Flight state values
private TextView mCallsignView;
+ private TextView mRSSIView;
+ private TextView mSerialView;
+ private TextView mFlightView;
private TextView mStateView;
private TextView mSpeedView;
private TextView mAccelView;
private TextView mRangeView;
- private TextView mAltitudeView;
- private TextView mAzimuthView;
+ private TextView mHeightView;
+ private TextView mElevationView;
private TextView mBearingView;
private TextView mLatitudeView;
private TextView mLongitudeView;
+ // Generic field for extras at the bottom
+ private TextView mTextView;
+
// Service
private boolean mIsBound = false;
private Messenger mService = null;
private BluetoothAdapter mBluetoothAdapter = null;
// Text to Speech
- private TextToSpeech tts = null;
- private boolean tts_enabled = false;
+ private AltosVoice mAltosVoice = null;
// The Handler that gets information back from the Telemetry Service
static class IncomingHandler extends Handler {
ad.mTitle.setText(R.string.title_connected_to);
ad.mTitle.append(str);
Toast.makeText(ad.getApplicationContext(), "Connected to " + str, Toast.LENGTH_SHORT).show();
+ ad.mAltosVoice.speak("Connected");
//TEST!
- ad.mSerialView.setText(Dumper.dump(ad.mConfigData));
+ ad.mTextView.setText(Dumper.dump(ad.mConfigData));
break;
case TelemetryService.STATE_CONNECTING:
ad.mTitle.setText(R.string.title_connecting);
case TelemetryService.STATE_NONE:
ad.mConfigData = null;
ad.mTitle.setText(R.string.title_not_connected);
- ad.mSerialView.setText("");
+ ad.mTextView.setText("");
break;
}
break;
case MSG_TELEMETRY:
ad.update_ui((AltosState) msg.obj);
// TEST!
- ad.mSerialView.setText(Dumper.dump(msg.obj));
+ ad.mTextView.setText(Dumper.dump(msg.obj));
break;
}
}
void update_ui(AltosState state) {
mCallsignView.setText(state.data.callsign);
+ mRSSIView.setText(String.format("%d", state.data.rssi));
+ mSerialView.setText(String.format("%d", state.data.serial));
+ mFlightView.setText(String.format("%d", state.data.flight));
mStateView.setText(state.data.state());
double speed = state.speed;
if (!state.ascent)
speed = state.baro_speed;
- mSpeedView.setText(String.format("%6.0f", speed));
- mAccelView.setText(String.format("%6.0f", state.acceleration));
- mRangeView.setText(String.format("%6.0f", state.range));
- mAltitudeView.setText(String.format("%6.0f", state.height));
- mAzimuthView.setText(String.format("%3.0f", state.elevation));
+ mSpeedView.setText(String.format("%6.0f m/s", speed));
+ mAccelView.setText(String.format("%6.0f m/s²", state.acceleration));
+ mRangeView.setText(String.format("%6.0f m", state.range));
+ mHeightView.setText(String.format("%6.0f m", state.height));
+ mElevationView.setText(String.format("%3.0f°", state.elevation));
if (state.from_pad != null)
- mBearingView.setText(String.format("%3.0f", state.from_pad.bearing));
+ mBearingView.setText(String.format("%3.0f°", state.from_pad.bearing));
mLatitudeView.setText(pos(state.gps.lat, "N", "S"));
mLongitudeView.setText(pos(state.gps.lon, "W", "E"));
+
+ mAltosVoice.tell(state);
}
String pos(double p, String pos, String neg) {
}
int deg = (int) Math.floor(p);
double min = (p - Math.floor(p)) * 60.0;
- return String.format("%s %d° %9.6f", h, deg, min);
+ return String.format("%d° %9.6f\" %s", deg, min, h);
}
@Override
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
+ // Get local Bluetooth adapter
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ // If the adapter is null, then Bluetooth is not supported
+ if (mBluetoothAdapter == null) {
+ Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
//setContentView(R.layout.main);
mTitle = (TextView) findViewById(R.id.title_right_text);
// Set up the temporary Text View
- mSerialView = (TextView) findViewById(R.id.text);
- mSerialView.setMovementMethod(new ScrollingMovementMethod());
- mSerialView.setClickable(false);
- mSerialView.setLongClickable(false);
+ mTextView = (TextView) findViewById(R.id.text);
+ mTextView.setMovementMethod(new ScrollingMovementMethod());
+ mTextView.setClickable(false);
+ mTextView.setLongClickable(false);
mCallsignView = (TextView) findViewById(R.id.callsign_value);
+ mRSSIView = (TextView) findViewById(R.id.rssi_value);
+ mSerialView = (TextView) findViewById(R.id.serial_value);
+ mFlightView = (TextView) findViewById(R.id.flight_value);
mStateView = (TextView) findViewById(R.id.state_value);
mSpeedView = (TextView) findViewById(R.id.speed_value);
mAccelView = (TextView) findViewById(R.id.accel_value);
mRangeView = (TextView) findViewById(R.id.range_value);
- mAltitudeView = (TextView) findViewById(R.id.altitude_value);
- mAzimuthView = (TextView) findViewById(R.id.azimuth_value);
+ mHeightView = (TextView) findViewById(R.id.height_value);
+ mElevationView = (TextView) findViewById(R.id.elevation_value);
mBearingView = (TextView) findViewById(R.id.bearing_value);
mLatitudeView = (TextView) findViewById(R.id.latitude_value);
mLongitudeView = (TextView) findViewById(R.id.longitude_value);
- // Get local Bluetooth adapter
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
- // If the adapter is null, then Bluetooth is not supported
- if (mBluetoothAdapter == null) {
- Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
- finish();
- return;
- }
-
- // Enable Text to Speech
- tts = new TextToSpeech(this, new OnInitListener() {
- public void onInit(int status) {
- if (status == TextToSpeech.SUCCESS) tts_enabled = true;
- if (tts_enabled) tts.speak("AltosDroid ready", TextToSpeech.QUEUE_ADD, null );
- }
- });
-
+ mAltosVoice = new AltosVoice(this);
}
@Override
super.onDestroy();
if(D) Log.e(TAG, "--- ON DESTROY ---");
- if (tts != null) tts.shutdown();
+ mAltosVoice.stop();
}
--- /dev/null
+/*\r
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>\r
+ * Copyright © 2012 Mike Beattie <mike@ethernal.org>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; version 2 of the License.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.\r
+ */\r
+\r
+package org.altusmetrum.AltosDroid;\r
+\r
+import android.speech.tts.TextToSpeech;\r
+import android.speech.tts.TextToSpeech.OnInitListener;\r
+\r
+import org.altusmetrum.AltosLib.*;\r
+\r
+public class AltosVoice {\r
+\r
+ private TextToSpeech tts = null;\r
+ private boolean tts_enabled = false;\r
+\r
+ private IdleThread idle_thread = null;\r
+\r
+ private AltosState old_state = null;\r
+\r
+ public AltosVoice(AltosDroid a) {\r
+\r
+ tts = new TextToSpeech(a, new OnInitListener() {\r
+ public void onInit(int status) {\r
+ if (status == TextToSpeech.SUCCESS) tts_enabled = true;\r
+ if (tts_enabled) {\r
+ speak("AltosDroid ready");\r
+ idle_thread = new IdleThread();\r
+ }\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ public void speak(String s) {\r
+ if (!tts_enabled) return;\r
+ tts.speak(s, TextToSpeech.QUEUE_ADD, null);\r
+ }\r
+\r
+ public void stop() {\r
+ if (tts != null) tts.shutdown();\r
+ if (idle_thread != null) {\r
+ idle_thread.interrupt();\r
+ idle_thread = null;\r
+ }\r
+ }\r
+\r
+ public void tell(AltosState state) {\r
+ if (!tts_enabled) return;\r
+\r
+ boolean spoke = false;\r
+ if (old_state == null || old_state.state != state.state) {\r
+ speak(state.data.state());\r
+ if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) &&\r
+ state.state > AltosLib.ao_flight_boost) {\r
+ speak(String.format("max speed: %d meters per second.", (int) (state.max_speed + 0.5)));\r
+ spoke = true;\r
+ } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) &&\r
+ state.state >= AltosLib.ao_flight_drogue) {\r
+ speak(String.format("max height: %d meters.", (int) (state.max_height + 0.5)));\r
+ spoke = true;\r
+ }\r
+ }\r
+ if (old_state == null || old_state.gps_ready != state.gps_ready) {\r
+ if (state.gps_ready) {\r
+ speak("GPS ready");\r
+ spoke = true;\r
+ } else if (old_state != null) {\r
+ speak("GPS lost");\r
+ spoke = true;\r
+ }\r
+ }\r
+ old_state = state;\r
+ idle_thread.notice(state, spoke);\r
+ }\r
+\r
+\r
+ class IdleThread extends Thread {\r
+ boolean started;\r
+ private AltosState state;\r
+ int reported_landing;\r
+ int report_interval;\r
+ long report_time;\r
+\r
+ public synchronized void report(boolean last) {\r
+ if (state == null)\r
+ return;\r
+\r
+ /* reset the landing count once we hear about a new flight */\r
+ if (state.state < AltosLib.ao_flight_drogue)\r
+ reported_landing = 0;\r
+\r
+ /* Shut up once the rocket is on the ground */\r
+ if (reported_landing > 2) {\r
+ return;\r
+ }\r
+\r
+ /* If the rocket isn't on the pad, then report height */\r
+ if (AltosLib.ao_flight_drogue <= state.state &&\r
+ state.state < AltosLib.ao_flight_landed &&\r
+ state.range >= 0)\r
+ {\r
+ speak(String.format("Height %d, bearing %s %d, elevation %d, range %d.\n",\r
+ (int) (state.height + 0.5),\r
+ state.from_pad.bearing_words(\r
+ AltosGreatCircle.BEARING_VOICE),\r
+ (int) (state.from_pad.bearing + 0.5),\r
+ (int) (state.elevation + 0.5),\r
+ (int) (state.range + 0.5)));\r
+ } else if (state.state > AltosLib.ao_flight_pad) {\r
+ speak(String.format("%d meters", (int) (state.height + 0.5)));\r
+ } else {\r
+ reported_landing = 0;\r
+ }\r
+\r
+ /* If the rocket is coming down, check to see if it has landed;\r
+ * either we've got a landed report or we haven't heard from it in\r
+ * a long time\r
+ */\r
+ if (state.state >= AltosLib.ao_flight_drogue &&\r
+ (last ||\r
+ System.currentTimeMillis() - state.report_time >= 15000 ||\r
+ state.state == AltosLib.ao_flight_landed))\r
+ {\r
+ if (Math.abs(state.baro_speed) < 20 && state.height < 100)\r
+ speak("rocket landed safely");\r
+ else\r
+ speak("rocket may have crashed");\r
+ if (state.from_pad != null)\r
+ speak(String.format("Bearing %d degrees, range %d meters.",\r
+ (int) (state.from_pad.bearing + 0.5),\r
+ (int) (state.from_pad.distance + 0.5)));\r
+ ++reported_landing;\r
+ }\r
+ }\r
+\r
+ long now () {\r
+ return System.currentTimeMillis();\r
+ }\r
+\r
+ void set_report_time() {\r
+ report_time = now() + report_interval;\r
+ }\r
+\r
+ public void run () {\r
+ try {\r
+ for (;;) {\r
+ set_report_time();\r
+ for (;;) {\r
+ synchronized (this) {\r
+ long sleep_time = report_time - now();\r
+ if (sleep_time <= 0)\r
+ break;\r
+ wait(sleep_time);\r
+ }\r
+ }\r
+ report(false);\r
+ }\r
+ } catch (InterruptedException ie) {\r
+ }\r
+ }\r
+\r
+ public synchronized void notice(AltosState new_state, boolean spoken) {\r
+ AltosState old_state = state;\r
+ state = new_state;\r
+ if (!started && state.state > AltosLib.ao_flight_pad) {\r
+ started = true;\r
+ start();\r
+ }\r
+\r
+ if (state.state < AltosLib.ao_flight_drogue)\r
+ report_interval = 10000;\r
+ else\r
+ report_interval = 20000;\r
+ if (old_state != null && old_state.state != state.state) {\r
+ report_time = now();\r
+ this.notify();\r
+ } else if (spoken)\r
+ set_report_time();\r
+ }\r
+\r
+ public IdleThread() {\r
+ state = null;\r
+ reported_landing = 0;\r
+ report_interval = 10000;\r
+ }\r
+ }\r
+\r
+}\r