summaryrefslogtreecommitdiff
path: root/altosdroid/src
diff options
context:
space:
mode:
authorMike Beattie <mike@ethernal.org>2013-04-21 14:51:07 +1200
committerMike Beattie <mike@ethernal.org>2013-04-21 14:51:07 +1200
commit49caac78786014d443d9c05f47b5eb3070ec9bd3 (patch)
treed00d60c1d16e6468545d6d5077369d3e5715292b /altosdroid/src
parent5b7bbf183e558330d27702aa1bebf205f0e094aa (diff)
parentcbf38c557a2046b6d6af3a9aebc0cef8e0dc5f11 (diff)
Merge branch 'altosdroid'
Diffstat (limited to 'altosdroid/src')
-rw-r--r--altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java96
-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/DeviceListActivity.java10
-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.java72
12 files changed, 322 insertions, 160 deletions
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
index c9ce46a0..e10982f7 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
@@ -37,7 +37,7 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.FragmentActivity;
-import android.support.v4.view.ViewPager;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -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;
@@ -79,14 +82,16 @@ public class AltosDroid extends FragmentActivity {
private TextView mVersion;
// Tabs
- TabHost mTabHost;
- AltosViewPager mViewPager;
- TabsAdapter mTabsAdapter;
+ TabHost mTabHost;
+ AltosViewPager mViewPager;
+ TabsAdapter mTabsAdapter;
ArrayList<AltosDroidTab> mTabs = new ArrayList<AltosDroidTab>();
+ int tabHeight;
// 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 +127,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 +141,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 +204,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 +228,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 +266,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
@@ -269,6 +313,7 @@ public class AltosDroid extends FragmentActivity {
setContentView(R.layout.altosdroid);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
+ // Create the Tabs and ViewPager
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
@@ -284,6 +329,27 @@ public class AltosDroid extends FragmentActivity {
mTabsAdapter.addTab(mTabHost.newTabSpec("map").setIndicator("Map"), TabMap.class, null);
+ // Scale the size of the Tab bar for different screen densities
+ // This probably won't be needed when we start supporting ICS+ tabs.
+ DisplayMetrics metrics = new DisplayMetrics();
+ getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ int density = metrics.densityDpi;
+
+ if (density==DisplayMetrics.DENSITY_XHIGH)
+ tabHeight = 65;
+ else if (density==DisplayMetrics.DENSITY_HIGH)
+ tabHeight = 45;
+ else if (density==DisplayMetrics.DENSITY_MEDIUM)
+ tabHeight = 35;
+ else if (density==DisplayMetrics.DENSITY_LOW)
+ tabHeight = 25;
+ else
+ tabHeight = 65;
+
+ for (int i = 0; i < 5; i++)
+ mTabHost.getTabWidget().getChildAt(i).getLayoutParams().height = tabHeight;
+
+
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
@@ -348,7 +414,7 @@ public class AltosDroid extends FragmentActivity {
super.onDestroy();
if(D) Log.e(TAG, "--- ON DESTROY ---");
- mAltosVoice.stop();
+ if (mAltosVoice != null) mAltosVoice.stop();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
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/DeviceListActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java
index 7b9cbde7..71692122 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/DeviceListActivity.java
@@ -109,9 +109,10 @@ public class DeviceListActivity extends Activity {
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
- for (BluetoothDevice device : pairedDevices) {
- mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
- }
+ for (BluetoothDevice device : pairedDevices)
+ if (device.getName().startsWith("TeleBT"))
+ mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
+
} else {
String noDevices = getResources().getText(R.string.none_paired).toString();
mPairedDevicesArrayAdapter.add(noDevices);
@@ -185,7 +186,8 @@ public class DeviceListActivity extends Activity {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
- if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
+ if ( device.getBondState() != BluetoothDevice.BOND_BONDED
+ && device.getName().startsWith("TeleBT") ) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
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..d831f117 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
@@ -35,11 +35,12 @@ import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
+//import android.support.v4.app.FragmentTransaction;
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,54 @@ 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;
}
- 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);
+ 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));
+ }
- 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 != null) {
+ if (mapLoaded) {
+ if (state.gps != null) {
+ mRocketMarker.setPosition(new LatLng(state.gps.lat, state.gps.lon));
+ mRocketMarker.setVisible(true);
- if (state.state == AltosLib.ao_flight_pad) {
- mPadMarker.setPosition(new LatLng(state.pad_lat, state.pad_lon));
- mPadMarker.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);
}
}
+
+ if (receiver != null) {
+ double accuracy;
+
+ 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..0236b537 100644
--- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
+++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
@@ -44,27 +44,8 @@ import android.location.LocationListener;
import org.altusmetrum.altoslib_1.*;
-class AltosLocationListener implements LocationListener {
- boolean fine;
- public void onLocationChanged(Location location) {
- }
-
- public void onStatusChanged(String provider, int status, Bundle extras) {
- }
-
- public void onProviderEnabled(String provider) {
- }
-
- public void onProviderDisabled(String provider) {
- }
-
- public AltosLocationListener(boolean fine) {
- this.fine = fine;
- }
-}
-
-public class TelemetryService extends Service {
+public class TelemetryService extends Service implements LocationListener {
private static final String TAG = "TelemetryService";
private static final boolean D = true;
@@ -77,6 +58,7 @@ 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_CRC_ERROR = 9;
public static final int STATE_NONE = 0;
public static final int STATE_READY = 1;
@@ -105,11 +87,12 @@ public class TelemetryService extends Service {
// internally track state of bluetooth connection
private int state = STATE_NONE;
- // location listeners
+ // Last data seen; send to UI when it starts
+
+ private AltosState last_state;
+ private Location last_location;
+ private int last_crc_errors;
- private AltosLocationListener gpsListener;
- private AltosLocationListener netListener;
-
// Handler of incoming messages from clients.
static class IncomingHandler extends Handler {
private final WeakReference<TelemetryService> service;
@@ -125,6 +108,10 @@ public class TelemetryService extends Service {
// Now we try to send the freshly connected UI any relavant information about what
// we're talking to - Basically state and Config Data.
msg.replyTo.send(Message.obtain(null, AltosDroid.MSG_STATE_CHANGE, s.state, -1, s.mConfigData));
+ // We also send any recent telemetry or location data that's cached
+ if (s.last_state != null) msg.replyTo.send(Message.obtain(null, AltosDroid.MSG_TELEMETRY, s.last_state ));
+ if (s.last_location != null) msg.replyTo.send(Message.obtain(null, AltosDroid.MSG_LOCATION , s.last_location ));
+ if (s.last_crc_errors != 0 ) msg.replyTo.send(Message.obtain(null, AltosDroid.MSG_CRC_ERROR, s.last_crc_errors));
} catch (RemoteException e) {
s.mClients.remove(msg.replyTo);
}
@@ -155,8 +142,15 @@ 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_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 {
@@ -209,6 +203,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 +235,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 +278,10 @@ 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);
-
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, this);
+ locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
@Override
@@ -319,9 +315,7 @@ public class TelemetryService extends Service {
public void onDestroy() {
// Stop listening for location updates
- LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
- locationManager.removeUpdates(gpsListener);
- locationManager.removeUpdates(netListener);
+ ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
// Stop the bluetooth Comms threads
stopAltosBluetooth();
@@ -342,4 +336,18 @@ public class TelemetryService extends Service {
}
+ public void onLocationChanged(Location location) {
+ last_location = location;
+ sendMessageToClients(Message.obtain(null, AltosDroid.MSG_LOCATION, location));
+ }
+
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+
+ public void onProviderEnabled(String provider) {
+ }
+
+ public void onProviderDisabled(String provider) {
+ }
+
}