altosdroid: Compute course from android device to rocket, display it
authorKeith Packard <keithp@keithp.com>
Fri, 12 Apr 2013 07:19:24 +0000 (00:19 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 12 Apr 2013 07:19:24 +0000 (00:19 -0700)
Signed-off-by: Keith Packard <keithp@keithp.com>
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java
altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java
altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java
altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java
altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java
altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java

index c9ce46a0d0c8487c075d6c95e6a8b6a845e32657..b1d080dbb9d67aee5eb986d1e3e4b4d894dab943 100644 (file)
@@ -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;
@@ -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,6 +204,13 @@ public class AltosDroid extends FragmentActivity {
                mTabs.remove(mTab);
        }
 
+       void set_location(Location location) {
+               saved_location = location;
+               if (saved_state != null) {
+                       update_ui(saved_state);
+               }
+       }
+
        void update_ui(AltosState state) {
                if (saved_state != null) {
                        if (saved_state.state != state.state) {
@@ -215,6 +230,17 @@ public class AltosDroid extends FragmentActivity {
                }
                saved_state = state;
 
+               AltosGreatCircle from_receiver = null;
+
+               if (saved_location != null && state.gps != null && state.gps.locked) {
+                       from_receiver = new AltosGreatCircle(saved_location.getLatitude(),
+                                                            saved_location.getLongitude(),
+                                                            saved_location.getAltitude(),
+                                                            state.gps.lat,
+                                                            state.gps.lon,
+                                                            state.gps.alt);
+               }
+
                mCallsignView.setText(state.data.callsign);
                mSerialView.setText(String.format("%d", state.data.serial));
                mFlightView.setText(String.format("%d", state.data.flight));
@@ -222,7 +248,7 @@ public class AltosDroid extends FragmentActivity {
                mRSSIView.setText(String.format("%d", state.data.rssi));
 
                for (AltosDroidTab mTab : mTabs)
-                       mTab.update_ui(state);
+                       mTab.update_ui(state, from_receiver);
 
                mAltosVoice.tell(state);
        }
index 68bbe5935489b5875c94e21ca3273684104dce17..2b5cdae77b885cf94010839d0fb31187488ef86e 100644 (file)
@@ -17,8 +17,8 @@
 
 package org.altusmetrum.AltosDroid;
 
-import org.altusmetrum.altoslib_1.AltosState;
+import org.altusmetrum.altoslib_1.*;
 
 public interface AltosDroidTab {
-       public void update_ui(AltosState state);
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver);
 }
index bda6b1fd3b5dfdb4fe63b0b8d3ff8f919a7f1926..ce677c57b49545b5af2c300b37f94f5914a64c86 100644 (file)
@@ -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;
@@ -84,7 +84,7 @@ public class TabAscent extends Fragment implements AltosDroidTab {
                mAltosDroid = null;
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver) {
                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()));
index 3805b7e77b98757a3e518deacc6cbdb18f8630c4..b0c6539cf48a29673b36b5c68b5ec6ef75d16ce2 100644 (file)
@@ -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;
@@ -89,16 +88,22 @@ public class TabDescent extends Fragment implements AltosDroidTab {
                mAltosDroid = null;
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver) {
                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));
+               if (from_receiver != null) {
+                       mElevationView.setText(String.format("%3.0f°", from_receiver.elevation));
+                       mRangeView.setText(String.format("%6.0f m", from_receiver.range));
+                       mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
+                       mCompassView.setText(from_receiver.bearing_words(AltosGreatCircle.BEARING_LONG));
+                       mDistanceView.setText(String.format("%6.0f m", from_receiver.distance));
+               } else { 
+                       mElevationView.setText("<unknown>");
+                       mRangeView.setText("<unknown>");
+                       mBearingView.setText("<unknown>");
+                       mCompassView.setText("<unknown>");
+                       mDistanceView.setText("<unknown>");
                }
-               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"));
 
index a95e914557592b8de54eadd8c90067cbc1121e1d..93a42334efd872856d339efc2043febd3b95cb34 100644 (file)
@@ -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;
@@ -68,10 +68,10 @@ 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) {
+               if (from_receiver != null) {
+                       mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
+                       mDistanceView.setText(String.format("%6.0f m", from_receiver.distance));
                }
                mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
                mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
index 8fc8f59278ac2c59062c8bcb80d1a27a15179e5c..607ded46693fc8de67dee0f0b3b1199650cafc3b 100644 (file)
@@ -139,7 +139,7 @@ public class TabMap extends Fragment implements AltosDroidTab {
                }
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver) {
                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));
index 41776c1060a77b43fff4eaf61d2d034e295439cd..6906324dd594fd5de27a9e346b5f4011ce1b5cae 100644 (file)
@@ -100,7 +100,7 @@ public class TabPad extends Fragment implements AltosDroidTab {
                mAltosDroid = null;
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver) {
                mBatteryVoltageView.setText(String.format("%4.2f V", state.battery));
                mBatteryLights.set(state.battery > 3.7);
 
index fb07442ee47e0c6d38c492aae50c0c4922440b7f..716ec5894c9df42c5e0a975591ba8464c42e91bd 100644 (file)
@@ -36,7 +36,6 @@ public class TelemetryReader extends Thread {
 \r
        Handler     handler;\r
 \r
-       TelemetryService service;\r
        AltosLink   link;\r
        AltosRecord previous;\r
 \r
@@ -69,12 +68,12 @@ public class TelemetryReader extends Thread {
                                        if (record == null)\r
                                                break;\r
                                        state = new AltosState(record, state);\r
-                                       service.sendTelemetry(state);\r
+                                       handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget();\r
                                } catch (ParseException pp) {\r
                                        Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage()));\r
                                } catch (AltosCRCException ce) {\r
                                        ++crc_errors;\r
-                                       service.sendCrcErrors(crc_errors);\r
+                                       handler.obtainMessage(TelemetryService.MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget();\r
                                }\r
                        }\r
                } catch (InterruptedException ee) {\r
@@ -84,8 +83,7 @@ public class TelemetryReader extends Thread {
                }\r
        }\r
 \r
-       public TelemetryReader (TelemetryService in_service, AltosLink in_link, Handler in_handler) {\r
-               service = in_service;\r
+       public TelemetryReader (AltosLink in_link, Handler in_handler) {\r
                link    = in_link;\r
                handler = in_handler;\r
 \r
index e68545856862bd361bec34172b037559f6e7f04a..0ddfdfc3ad50c6ed281cac7a05b5910dd43546a7 100644 (file)
@@ -45,10 +45,10 @@ import android.location.LocationListener;
 import org.altusmetrum.altoslib_1.*;
 
 class AltosLocationListener implements LocationListener {
-       TelemetryService service;
+       Handler handler;
 
        public void onLocationChanged(Location location) {
-               service.sendLocation(location);
+               handler.obtainMessage(TelemetryService.MSG_LOCATION, location).sendToTarget();
        }
 
        public void onStatusChanged(String provider, int status, Bundle extras) {
@@ -60,8 +60,8 @@ class AltosLocationListener implements LocationListener {
        public void onProviderDisabled(String provider) {
        }
 
-       public AltosLocationListener(TelemetryService service) {
-               this.service = service;
+       public AltosLocationListener(Handler handler) {
+               this.handler = handler;
        }
 }
 
@@ -169,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 {
@@ -187,18 +199,13 @@ public class TelemetryService extends Service {
        }
 
        public void sendTelemetry(AltosState state) {
-               last_state = state;
-               mHandler.obtainMessage(MSG_TELEMETRY, state).sendToTarget();
        }
 
        public void sendLocation(Location location) {
-               last_location = location;
                mHandler.obtainMessage(MSG_LOCATION, location).sendToTarget();
        }
 
        public void sendCrcErrors(int crc_errors) {
-               last_crc_errors = crc_errors;
-               mHandler.obtainMessage(MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget();
        }
 
        private void sendMessageToClients(Message m) {
@@ -278,7 +285,7 @@ public class TelemetryService extends Service {
 
                setState(STATE_CONNECTED);
 
-               mTelemetryReader = new TelemetryReader(this, mAltosBluetooth, mHandler);
+               mTelemetryReader = new TelemetryReader(mAltosBluetooth, mHandler);
                mTelemetryReader.start();
                
                mTelemetryLogger = new TelemetryLogger(this, mAltosBluetooth);
@@ -308,7 +315,7 @@ public class TelemetryService extends Service {
                timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 10000L, 10000L);
 
                // Listen for GPS and Network position updates
-               locationListener = new AltosLocationListener(this);
+               locationListener = new AltosLocationListener(mHandler);
 
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);