summaryrefslogtreecommitdiff
path: root/altosdroid/src
diff options
context:
space:
mode:
Diffstat (limited to 'altosdroid/src')
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java65
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java5
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java1
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/GoNoGoLights.java15
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java42
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java48
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java43
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java74
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java74
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java2
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java61
11 files changed, 299 insertions, 131 deletions
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
index c9ce46a0..18f364fa 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
@@ -47,6 +47,7 @@ import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
import android.app.AlertDialog;
+import android.location.Location;
import org.altusmetrum.altoslib_1.*;
@@ -59,6 +60,8 @@ public class AltosDroid extends FragmentActivity {
public static final int MSG_STATE_CHANGE = 1;
public static final int MSG_TELEMETRY = 2;
public static final int MSG_UPDATE_AGE = 3;
+ public static final int MSG_LOCATION = 4;
+ public static final int MSG_CRC_ERROR = 5;
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
@@ -87,6 +90,7 @@ public class AltosDroid extends FragmentActivity {
// Timer and Saved flight state for Age calculation
private Timer timer = new Timer();
AltosState saved_state;
+ Location saved_location;
// Service
private boolean mIsBound = false;
@@ -122,7 +126,6 @@ public class AltosDroid extends FragmentActivity {
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");
break;
case TelemetryService.STATE_CONNECTING:
ad.mTitle.setText(R.string.title_connecting);
@@ -137,6 +140,10 @@ public class AltosDroid extends FragmentActivity {
case MSG_TELEMETRY:
ad.update_ui((AltosState) msg.obj);
break;
+ case MSG_LOCATION:
+ ad.set_location((Location) msg.obj);
+ break;
+ case MSG_CRC_ERROR:
case MSG_UPDATE_AGE:
if (ad.saved_state != null) {
ad.mAgeView.setText(String.format("%d", (System.currentTimeMillis() - ad.saved_state.report_time + 500) / 1000));
@@ -196,8 +203,13 @@ public class AltosDroid extends FragmentActivity {
mTabs.remove(mTab);
}
+ void set_location(Location location) {
+ saved_location = location;
+ update_ui(saved_state);
+ }
+
void update_ui(AltosState state) {
- if (saved_state != null) {
+ if (state != null && saved_state != null) {
if (saved_state.state != state.state) {
String currentTab = mTabHost.getCurrentTabTag();
switch (state.state) {
@@ -215,16 +227,33 @@ public class AltosDroid extends FragmentActivity {
}
saved_state = state;
- mCallsignView.setText(state.data.callsign);
- mSerialView.setText(String.format("%d", state.data.serial));
- mFlightView.setText(String.format("%d", state.data.flight));
- mStateView.setText(state.data.state());
- mRSSIView.setText(String.format("%d", state.data.rssi));
+ AltosGreatCircle from_receiver = null;
+
+ if (state != null && saved_location != null && state.gps != null && state.gps.locked) {
+ double altitude = 0;
+ if (saved_location.hasAltitude())
+ altitude = saved_location.getAltitude();
+ from_receiver = new AltosGreatCircle(saved_location.getLatitude(),
+ saved_location.getLongitude(),
+ altitude,
+ state.gps.lat,
+ state.gps.lon,
+ state.gps.alt);
+ }
+
+ if (state != null) {
+ mCallsignView.setText(state.data.callsign);
+ mSerialView.setText(String.format("%d", state.data.serial));
+ mFlightView.setText(String.format("%d", state.data.flight));
+ mStateView.setText(state.data.state());
+ mRSSIView.setText(String.format("%d", state.data.rssi));
+ }
for (AltosDroidTab mTab : mTabs)
- mTab.update_ui(state);
+ mTab.update_ui(state, from_receiver, saved_location);
- mAltosVoice.tell(state);
+ if (state != null)
+ mAltosVoice.tell(state);
}
private void onTimerTick() {
@@ -236,13 +265,27 @@ public class AltosDroid extends FragmentActivity {
static String pos(double p, String pos, String neg) {
String h = pos;
+ if (p == AltosRecord.MISSING)
+ return "";
if (p < 0) {
h = neg;
p = -p;
}
int deg = (int) Math.floor(p);
double min = (p - Math.floor(p)) * 60.0;
- return String.format("%d° %9.6f\" %s", deg, min, h);
+ return String.format("%d°%9.4f\" %s", deg, min, h);
+ }
+
+ static String number(String format, double value) {
+ if (value == AltosRecord.MISSING)
+ return "";
+ return String.format(format, value);
+ }
+
+ static String integer(String format, int value) {
+ if (value == AltosRecord.MISSING)
+ return "";
+ return String.format(format, value);
}
@Override
@@ -283,6 +326,8 @@ public class AltosDroid extends FragmentActivity {
mTabsAdapter.addTab(mTabHost.newTabSpec("landed").setIndicator("Landed"), TabLanded.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("map").setIndicator("Map"), TabMap.class, null);
+ for (int i = 0; i < 5; i++)
+ mTabHost.getTabWidget().getChildAt(i).getLayoutParams().height = 45;
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
index 68bbe593..6ebb47f7 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
@@ -17,8 +17,9 @@
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_1.AltosState;
+import org.altusmetrum.altoslib_1.*;
+import android.location.Location;
public interface AltosDroidTab {
- public void update_ui(AltosState state);
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver);
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
index 7da5c4a9..b3dba626 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java
@@ -38,7 +38,6 @@ public class AltosVoice {
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) tts_enabled = true;
if (tts_enabled) {
- speak("AltosDroid ready");
idle_thread = new IdleThread();
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/GoNoGoLights.java b/altosdroid/src/org/altusmetrum/AltosDroid/GoNoGoLights.java
index 0f95bc22..8e8d9c03 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/GoNoGoLights.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/GoNoGoLights.java
@@ -23,6 +23,8 @@ import android.widget.ImageView;
public class GoNoGoLights {
private Boolean state;
+ private Boolean missing;
+ private Boolean set;
private ImageView red;
private ImageView green;
@@ -35,16 +37,23 @@ public class GoNoGoLights {
red = in_red;
green = in_green;
state = false;
+ missing = true;
+ set = false;
dRed = r.getDrawable(R.drawable.redled);
dGreen = r.getDrawable(R.drawable.greenled);
dGray = r.getDrawable(R.drawable.grayled);
}
- public void set(Boolean s) {
- if (s == state) return;
+ public void set(Boolean s, Boolean m) {
+ if (set && s == state && m == missing) return;
state = s;
- if (state) {
+ missing = m;
+ set = true;
+ if (missing) {
+ red.setImageDrawable(dGray);
+ green.setImageDrawable(dGray);
+ } else if (state) {
red.setImageDrawable(dGray);
green.setImageDrawable(dGreen);
} else {
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java
index bda6b1fd..0e141ae4 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java
@@ -17,7 +17,7 @@
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_1.AltosState;
+import org.altusmetrum.altoslib_1.*;
import android.app.Activity;
import android.os.Bundle;
@@ -27,6 +27,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import android.location.Location;
public class TabAscent extends Fragment implements AltosDroidTab {
AltosDroid mAltosDroid;
@@ -84,21 +85,28 @@ public class TabAscent extends Fragment implements AltosDroidTab {
mAltosDroid = null;
}
- public void update_ui(AltosState state) {
- mHeightView.setText(String.format("%6.0f m", state.height));
- mMaxHeightView.setText(String.format("%6.0f m", state.max_height));
- mSpeedView.setText(String.format("%6.0f m/s", state.speed()));
- mMaxSpeedView.setText(String.format("%6.0f m/s", state.max_speed()));
- mAccelView.setText(String.format("%6.0f m/s²", state.acceleration));
- mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration));
-
- mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
- mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
-
- mApogeeVoltageView.setText(String.format("%4.2f V", state.drogue_sense));
- mApogeeLights.set(state.drogue_sense > 3.2);
-
- mMainVoltageView.setText(String.format("%4.2f V", state.main_sense));
- mMainLights.set(state.main_sense > 3.2);
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+ if (state != null) {
+ mHeightView.setText(AltosDroid.number("%6.0f m", state.height));
+ mMaxHeightView.setText(AltosDroid.number("%6.0f m", state.max_height));
+ mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed()));
+ mMaxSpeedView.setText(AltosDroid.number("%6.0f m/s", state.max_speed()));
+ mAccelView.setText(AltosDroid.number("%6.0f m/s²", state.acceleration));
+ mMaxAccelView.setText(AltosDroid.number("%6.0f m/s²", state.max_acceleration));
+
+ if (state.gps != null) {
+ mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+ mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
+ } else {
+ mLatitudeView.setText("");
+ mLongitudeView.setText("");
+ }
+
+ mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense));
+ mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING);
+
+ mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense));
+ mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING);
+ }
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java
index 3805b7e7..09e7169b 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java
@@ -17,8 +17,7 @@
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_1.AltosGreatCircle;
-import org.altusmetrum.altoslib_1.AltosState;
+import org.altusmetrum.altoslib_1.*;
import android.app.Activity;
import android.os.Bundle;
@@ -28,6 +27,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import android.location.Location;
public class TabDescent extends Fragment implements AltosDroidTab {
AltosDroid mAltosDroid;
@@ -89,24 +89,34 @@ public class TabDescent extends Fragment implements AltosDroidTab {
mAltosDroid = null;
}
- public void update_ui(AltosState state) {
- mSpeedView.setText(String.format("%6.0f m/s", state.speed()));
- mHeightView.setText(String.format("%6.0f m", state.height));
- mElevationView.setText(String.format("%3.0f°", state.elevation));
- mRangeView.setText(String.format("%6.0f m", state.range));
- if (state.from_pad != null) {
- mBearingView.setText(String.format("%3.0f°", state.from_pad.bearing));
- mCompassView.setText(state.from_pad.bearing_words(AltosGreatCircle.BEARING_LONG));
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+ if (state != null) {
+ mSpeedView.setText(AltosDroid.number("%6.0f m/s", state.speed()));
+ mHeightView.setText(AltosDroid.number("%6.0f m", state.height));
+ if (from_receiver != null) {
+ mElevationView.setText(AltosDroid.number("%3.0f°", from_receiver.elevation));
+ mRangeView.setText(AltosDroid.number("%6.0f m", from_receiver.range));
+ mBearingView.setText(AltosDroid.number("%3.0f°", from_receiver.bearing));
+ mCompassView.setText(from_receiver.bearing_words(AltosGreatCircle.BEARING_LONG));
+ mDistanceView.setText(AltosDroid.number("%6.0f m", from_receiver.distance));
+ } else {
+ mElevationView.setText("<unknown>");
+ mRangeView.setText("<unknown>");
+ mBearingView.setText("<unknown>");
+ mCompassView.setText("<unknown>");
+ mDistanceView.setText("<unknown>");
+ }
+ if (state.gps != null) {
+ mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+ mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
+ }
+
+ mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense));
+ mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING);
+
+ mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense));
+ mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING);
}
- mDistanceView.setText(String.format("%6.0f m", state.range));
- mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
- mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
-
- mApogeeVoltageView.setText(String.format("%4.2f V", state.drogue_sense));
- mApogeeLights.set(state.drogue_sense > 3.2);
-
- mMainVoltageView.setText(String.format("%4.2f V", state.main_sense));
- mMainLights.set(state.main_sense > 3.2);
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java
index a95e9145..f42b46b5 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java
@@ -17,7 +17,7 @@
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_1.AltosState;
+import org.altusmetrum.altoslib_1.*;
import android.app.Activity;
import android.os.Bundle;
@@ -26,14 +26,17 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import android.location.Location;
public class TabLanded extends Fragment implements AltosDroidTab {
AltosDroid mAltosDroid;
private TextView mBearingView;
private TextView mDistanceView;
- private TextView mLatitudeView;
- private TextView mLongitudeView;
+ private TextView mTargetLatitudeView;
+ private TextView mTargetLongitudeView;
+ private TextView mReceiverLatitudeView;
+ private TextView mReceiverLongitudeView;
private TextView mMaxHeightView;
private TextView mMaxSpeedView;
private TextView mMaxAccelView;
@@ -52,8 +55,10 @@ public class TabLanded extends Fragment implements AltosDroidTab {
mBearingView = (TextView) v.findViewById(R.id.bearing_value);
mDistanceView = (TextView) v.findViewById(R.id.distance_value);
- mLatitudeView = (TextView) v.findViewById(R.id.lat_value);
- mLongitudeView = (TextView) v.findViewById(R.id.lon_value);
+ mTargetLatitudeView = (TextView) v.findViewById(R.id.target_lat_value);
+ mTargetLongitudeView = (TextView) v.findViewById(R.id.target_lon_value);
+ mReceiverLatitudeView = (TextView) v.findViewById(R.id.receiver_lat_value);
+ mReceiverLongitudeView = (TextView) v.findViewById(R.id.receiver_lon_value);
mMaxHeightView = (TextView) v.findViewById(R.id.max_height_value);
mMaxSpeedView = (TextView) v.findViewById(R.id.max_speed_value);
mMaxAccelView = (TextView) v.findViewById(R.id.max_accel_value);
@@ -68,16 +73,26 @@ public class TabLanded extends Fragment implements AltosDroidTab {
mAltosDroid = null;
}
- public void update_ui(AltosState state) {
- if (state.from_pad != null) {
- mBearingView.setText(String.format("%3.0f°", state.from_pad.bearing));
- mDistanceView.setText(String.format("%6.0f m", state.from_pad.distance));
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+ if (from_receiver != null) {
+ mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
+ mDistanceView.setText(String.format("%6.0f m", from_receiver.distance));
+ }
+ if (state != null && state.gps != null) {
+ mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+ mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
+ }
+
+ if (receiver != null) {
+ mReceiverLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
+ mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E"));
+ }
+
+ if (state != null) {
+ mMaxHeightView.setText(String.format("%6.0f m", state.max_height));
+ mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration));
+ mMaxSpeedView.setText(String.format("%6.0f m/s", state.max_speed()));
}
- mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
- mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
- mMaxHeightView.setText(String.format("%6.0f m", state.max_height));
- mMaxAccelView.setText(String.format("%6.0f m/s²", state.max_acceleration));
- mMaxSpeedView.setText(String.format("%6.0f m/s", state.max_speed()));
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
index 8fc8f592..66669ad0 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
@@ -40,6 +40,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import android.location.Location;
public class TabMap extends Fragment implements AltosDroidTab {
AltosDroid mAltosDroid;
@@ -54,8 +55,12 @@ public class TabMap extends Fragment implements AltosDroidTab {
private TextView mDistanceView;
private TextView mBearingView;
- private TextView mLatitudeView;
- private TextView mLongitudeView;
+ private TextView mTargetLatitudeView;
+ private TextView mTargetLongitudeView;
+ private TextView mReceiverLatitudeView;
+ private TextView mReceiverLongitudeView;
+
+ private double mapAccuracy = -1;
@Override
public void onAttach(Activity activity) {
@@ -83,8 +88,10 @@ public class TabMap extends Fragment implements AltosDroidTab {
View v = inflater.inflate(R.layout.tab_map, container, false);
mDistanceView = (TextView)v.findViewById(R.id.distance_value);
mBearingView = (TextView)v.findViewById(R.id.bearing_value);
- mLatitudeView = (TextView)v.findViewById(R.id.lat_value);
- mLongitudeView = (TextView)v.findViewById(R.id.lon_value);
+ mTargetLatitudeView = (TextView)v.findViewById(R.id.target_lat_value);
+ mTargetLongitudeView = (TextView)v.findViewById(R.id.target_lon_value);
+ mReceiverLatitudeView = (TextView)v.findViewById(R.id.receiver_lat_value);
+ mReceiverLongitudeView = (TextView)v.findViewById(R.id.receiver_lon_value);
return v;
}
@@ -113,7 +120,6 @@ public class TabMap extends Fragment implements AltosDroidTab {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setTiltGesturesEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(false);
- mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(40.8,-104.7),8));
mRocketMarker = mMap.addMarker(
// From: http://mapicons.nicolasmollet.com/markers/industry/military/missile-2/
@@ -139,26 +145,52 @@ public class TabMap extends Fragment implements AltosDroidTab {
}
}
- public void update_ui(AltosState state) {
- if (state.from_pad != null) {
- mDistanceView.setText(String.format("%6.0f m", state.from_pad.distance));
- mBearingView.setText(String.format("%3.0f°", state.from_pad.bearing));
+ private void center(double lat, double lon, double accuracy) {
+ if (mapAccuracy < 0 || accuracy < mapAccuracy/10) {
+ mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lon),14));
+ mapAccuracy = accuracy;
+ }
+ }
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+ if (state != null) {
+ if (state.from_pad != null) {
+ mDistanceView.setText(String.format("%6.0f m", state.from_pad.distance));
+ mBearingView.setText(String.format("%3.0f°", state.from_pad.bearing));
+ }
+ if (mapLoaded) {
+ if (state.gps != null) {
+ mRocketMarker.setPosition(new LatLng(state.gps.lat, state.gps.lon));
+ mRocketMarker.setVisible(true);
+
+ mPolyline.setPoints(Arrays.asList(new LatLng(state.pad_lat, state.pad_lon), new LatLng(state.gps.lat, state.gps.lon)));
+ mPolyline.setVisible(true);
+ }
+
+ if (state.state == AltosLib.ao_flight_pad) {
+ mPadMarker.setPosition(new LatLng(state.pad_lat, state.pad_lon));
+ mPadMarker.setVisible(true);
+ }
+ }
+ if (state.gps != null) {
+ mTargetLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+ mTargetLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
+ if (state.gps.locked && state.gps.nsat >= 4)
+ center (state.gps.lat, state.gps.lon, 10);
+ }
}
- mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
- mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
-
- if (mapLoaded) {
- mRocketMarker.setPosition(new LatLng(state.gps.lat, state.gps.lon));
- mRocketMarker.setVisible(true);
- mPolyline.setPoints(Arrays.asList(new LatLng(state.pad_lat, state.pad_lon), new LatLng(state.gps.lat, state.gps.lon)));
- mPolyline.setVisible(true);
+ if (receiver != null) {
+ double accuracy;
- if (state.state == AltosLib.ao_flight_pad) {
- mPadMarker.setPosition(new LatLng(state.pad_lat, state.pad_lon));
- mPadMarker.setVisible(true);
- }
+ if (receiver.hasAccuracy())
+ accuracy = receiver.getAccuracy();
+ else
+ accuracy = 1000;
+ mReceiverLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
+ mReceiverLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E"));
+ center (receiver.getLatitude(), receiver.getLongitude(), accuracy);
}
+
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
index 41776c10..066c1353 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
@@ -27,6 +27,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import android.location.Location;
public class TabPad extends Fragment implements AltosDroidTab {
AltosDroid mAltosDroid;
@@ -100,40 +101,49 @@ public class TabPad extends Fragment implements AltosDroidTab {
mAltosDroid = null;
}
- public void update_ui(AltosState state) {
- mBatteryVoltageView.setText(String.format("%4.2f V", state.battery));
- mBatteryLights.set(state.battery > 3.7);
-
- mApogeeVoltageView.setText(String.format("%4.2f V", state.drogue_sense));
- mApogeeLights.set(state.drogue_sense > 3.2);
-
- mMainVoltageView.setText(String.format("%4.2f V", state.main_sense));
- mMainLights.set(state.main_sense > 3.2);
-
- if (state.data.flight != 0) {
- if (state.data.state <= AltosLib.ao_flight_pad)
- mDataLoggingView.setText("Ready to record");
- else if (state.data.state < AltosLib.ao_flight_landed)
- mDataLoggingView.setText("Recording data");
- else
- mDataLoggingView.setText("Recorded data");
- } else {
- mDataLoggingView.setText("Storage full");
+ public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+ if (state != null) {
+ mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery));
+ mBatteryLights.set(state.battery > 3.7, state.battery == AltosRecord.MISSING);
+
+ mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense));
+ mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING);
+
+ mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense));
+ mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING);
+
+ if (state.data.flight != 0) {
+ if (state.data.state <= AltosLib.ao_flight_pad)
+ mDataLoggingView.setText("Ready to record");
+ else if (state.data.state < AltosLib.ao_flight_landed)
+ mDataLoggingView.setText("Recording data");
+ else
+ mDataLoggingView.setText("Recorded data");
+ } else {
+ mDataLoggingView.setText("Storage full");
+ }
+ mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosRecord.MISSING);
+
+ if (state.gps != null) {
+ mGPSLockedView.setText(AltosDroid.integer("%4d sats", state.gps.nsat));
+ mGPSLockedLights.set(state.gps.locked && state.gps.nsat >= 4, false);
+ if (state.gps_ready)
+ mGPSReadyView.setText("Ready");
+ else
+ mGPSReadyView.setText(AltosDroid.integer("Waiting %d", state.gps_waiting));
+ } else
+ mGPSLockedLights.set(false, true);
+ mGPSReadyLights.set(state.gps_ready, state.gps == null);
}
- mDataLoggingLights.set(state.data.flight != 0);
- mGPSLockedView.setText(String.format("%4d sats", state.gps.nsat));
- mGPSLockedLights.set(state.gps.locked && state.gps.nsat >= 4);
-
- if (state.gps_ready)
- mGPSReadyView.setText("Ready");
- else
- mGPSReadyView.setText(String.format("Waiting %d", state.gps_waiting));
- mGPSReadyLights.set(state.gps_ready);
-
- mPadLatitudeView.setText(AltosDroid.pos(state.pad_lat, "N", "S"));
- mPadLongitudeView.setText(AltosDroid.pos(state.pad_lon, "W", "E"));
- mPadAltitudeView.setText(String.format("%4.0f m", state.pad_alt));
+ if (receiver != null) {
+ double altitude = 0;
+ if (receiver.hasAltitude())
+ altitude = receiver.getAltitude();
+ mPadLatitudeView.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
+ mPadLongitudeView.setText(AltosDroid.pos(receiver.getLongitude(), "W", "E"));
+ mPadAltitudeView.setText(AltosDroid.number("%4.0f m", altitude));
+ }
}
}
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
index 9460bdbc..716ec589 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
@@ -68,12 +68,12 @@ public class TelemetryReader extends Thread {
if (record == null)
break;
state = new AltosState(record, state);
-
handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget();
} catch (ParseException pp) {
Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage()));
} catch (AltosCRCException ce) {
++crc_errors;
+ handler.obtainMessage(TelemetryService.MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget();
}
}
} catch (InterruptedException ee) {
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
index e1a5ada8..f1304a95 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
@@ -45,9 +45,10 @@ import android.location.LocationListener;
import org.altusmetrum.altoslib_1.*;
class AltosLocationListener implements LocationListener {
- boolean fine;
+ Handler handler;
public void onLocationChanged(Location location) {
+ handler.obtainMessage(TelemetryService.MSG_LOCATION, location).sendToTarget();
}
public void onStatusChanged(String provider, int status, Bundle extras) {
@@ -59,8 +60,8 @@ class AltosLocationListener implements LocationListener {
public void onProviderDisabled(String provider) {
}
- public AltosLocationListener(boolean fine) {
- this.fine = fine;
+ public AltosLocationListener(Handler handler) {
+ this.handler = handler;
}
}
@@ -77,6 +78,8 @@ public class TelemetryService extends Service {
static final int MSG_DISCONNECTED = 6;
static final int MSG_TELEMETRY = 7;
static final int MSG_SETFREQUENCY = 8;
+ static final int MSG_LOCATION = 9;
+ static final int MSG_CRC_ERROR = 10;
public static final int STATE_NONE = 0;
public static final int STATE_READY = 1;
@@ -107,9 +110,14 @@ public class TelemetryService extends Service {
// location listeners
- private AltosLocationListener gpsListener;
- private AltosLocationListener netListener;
+ private AltosLocationListener locationListener;
+ // Last data seen; send to UI when it starts
+
+ private AltosState last_state;
+ private Location last_location;
+ private int last_crc_errors;
+
// Handler of incoming messages from clients.
static class IncomingHandler extends Handler {
private final WeakReference<TelemetryService> service;
@@ -129,6 +137,12 @@ public class TelemetryService extends Service {
s.mClients.remove(msg.replyTo);
}
if (D) Log.d(TAG, "Client bound to service");
+ if (s.last_state != null)
+ s.sendTelemetry(s.last_state);
+ if (s.last_location != null)
+ s.sendLocation(s.last_location);
+ if (s.last_crc_errors != 0)
+ s.sendCrcErrors(s.last_crc_errors);
break;
case MSG_UNREGISTER_CLIENT:
s.mClients.remove(msg.replyTo);
@@ -155,8 +169,20 @@ public class TelemetryService extends Service {
}
break;
case MSG_TELEMETRY:
+ // forward telemetry messages
+ s.last_state = (AltosState) msg.obj;
s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_TELEMETRY, msg.obj));
break;
+ case MSG_LOCATION:
+ // forward location messages
+ s.last_location = (Location) msg.obj;
+ s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_LOCATION, msg.obj));
+ break;
+ case MSG_CRC_ERROR:
+ // forward crc error messages
+ s.last_crc_errors = (Integer) msg.obj;
+ s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_CRC_ERROR, msg.obj));
+ break;
case MSG_SETFREQUENCY:
if (s.state == STATE_CONNECTED) {
try {
@@ -172,6 +198,16 @@ public class TelemetryService extends Service {
}
}
+ public void sendTelemetry(AltosState state) {
+ }
+
+ public void sendLocation(Location location) {
+ mHandler.obtainMessage(MSG_LOCATION, location).sendToTarget();
+ }
+
+ public void sendCrcErrors(int crc_errors) {
+ }
+
private void sendMessageToClients(Message m) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
@@ -209,6 +245,9 @@ public class TelemetryService extends Service {
}
private void startAltosBluetooth() {
+ if (device == null) {
+ return;
+ }
if (mAltosBluetooth == null) {
if (D) Log.d(TAG, String.format("startAltosBluetooth(): Connecting to %s (%s)", device.getName(), device.getAddress()));
mAltosBluetooth = new AltosBluetooth(device, mHandler);
@@ -238,6 +277,8 @@ public class TelemetryService extends Service {
private void connected() {
try {
+ if (mAltosBluetooth == null)
+ throw new InterruptedException("no bluetooth");
mConfigData = mAltosBluetooth.config_data();
} catch (InterruptedException e) {
} catch (TimeoutException e) {
@@ -279,13 +320,12 @@ public class TelemetryService extends Service {
timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 10000L, 10000L);
// Listen for GPS and Network position updates
- gpsListener = new AltosLocationListener(true);
- netListener = new AltosLocationListener(false);
+ locationListener = new AltosLocationListener(mHandler);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
- locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
- locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, netListener);
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
+ locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
@Override
@@ -320,8 +360,7 @@ public class TelemetryService extends Service {
// Stop listening for location updates
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
- locationManager.removeUpdates(gpsListener);
- locationManager.removeUpdates(netListener);
+ locationManager.removeUpdates(locationListener);
// Stop the bluetooth Comms threads
stopAltosBluetooth();