Merge branch 'master' into droid-gps
authorKeith Packard <keithp@keithp.com>
Sat, 13 Apr 2013 17:51:04 +0000 (10:51 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 13 Apr 2013 17:51:04 +0000 (10:51 -0700)
17 files changed:
altosdroid/res/layout/altosdroid.xml
altosdroid/res/layout/tab_ascent.xml
altosdroid/res/layout/tab_descent.xml
altosdroid/res/layout/tab_landed.xml
altosdroid/res/layout/tab_map.xml
altosdroid/res/layout/tab_pad.xml
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
altoslib/AltosGreatCircle.java
altoslib/AltosState.java

index 364f6ba6d62677b370c0b1eef289ee8f949064b8..b653aa2e68fa35cf6571c47c9179d97d51a7f35b 100644 (file)
@@ -47,7 +47,7 @@
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/callsign_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
@@ -67,7 +67,7 @@
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/serial_label"
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
@@ -87,7 +87,7 @@
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/flight_label"
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/state_label"
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/rssi_label"
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_below="@+id/age_label"
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
        </LinearLayout>
 
index b7e97086ce6e4f51caf39e8926570e0ed0edb121..555da7f2ac406042f8aed4d2bd82dcdba867022e 100644 (file)
@@ -47,7 +47,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/height_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
@@ -68,7 +68,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/max_height_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
        </LinearLayout>
 
@@ -99,7 +99,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/speed_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/max_speed_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
        </LinearLayout>
 
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/accel_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/max_accel_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
        </LinearLayout>
 
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lat_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lon_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/apogee_voltage_label"
                        android:layout_toRightOf="@id/apogee_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/main_voltage_label"
                        android:layout_toRightOf="@id/main_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
 </LinearLayout>
\ No newline at end of file
index 4b62acf90b3a51ba77c4889c095ad4a3f960ec0c..5f11a999f8b929606a9a9077b8e4ea2159a04baf 100644 (file)
@@ -46,7 +46,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/speed_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
@@ -67,7 +67,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/height_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
        </LinearLayout>
@@ -99,7 +99,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/elevation_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/range_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
        </LinearLayout>
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/bearing_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/compass_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
        </LinearLayout>
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/distance_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <TextView
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lat_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lon_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/apogee_voltage_label"
                        android:layout_toRightOf="@id/apogee_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/main_voltage_label"
                        android:layout_toRightOf="@id/main_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
 </LinearLayout>
index b5c8d8c21e97d537e53489b736f9ac07c2c48842..18b1c566977fb02cfac2437e994732088c883e12 100644 (file)
@@ -37,7 +37,7 @@
                        android:layout_alignParentRight="true"
                        android:layout_below="@+id/bearing_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
@@ -58,7 +58,7 @@
                        android:layout_alignParentRight="true"
                        android:layout_below="@+id/distance_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
@@ -79,7 +79,7 @@
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lat_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/lon_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/max_height_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/max_speed_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_alignParentRight="true"
                        android:layout_below="@id/max_accel_label"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
 </LinearLayout>
\ No newline at end of file
index b9f4e69e7267d3d48dea9fca2d307ac0bf77cddc..233d2a0d313ad0f1ca95a3a76fbb3fd73a2aa872 100644 (file)
@@ -55,7 +55,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@+id/distance_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
@@ -77,7 +77,7 @@
                                android:layout_alignParentRight="true"
                                android:layout_below="@+id/bearing_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
        </LinearLayout>
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/lat_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
 
                <RelativeLayout
                                android:layout_alignParentRight="true"
                                android:layout_below="@id/lon_label"
                                android:text=""
-                               android:textAppearance="?android:attr/textAppearanceLarge" />
+                               android:textAppearance="?android:attr/textAppearanceMedium" />
                </RelativeLayout>
        </LinearLayout>
 </LinearLayout>
\ No newline at end of file
index f5ec46b544d70b8a76547646db144afe54b925df..b8ca1a442a791f5f5176dca79fb94bf939f116c7 100644 (file)
@@ -55,7 +55,7 @@
                        android:layout_below="@id/battery_voltage_label"
                        android:layout_toRightOf="@id/battery_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
@@ -93,7 +93,7 @@
                        android:layout_below="@id/apogee_voltage_label"
                        android:layout_toRightOf="@id/apogee_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/main_voltage_label"
                        android:layout_toRightOf="@id/main_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/logging_label"
                        android:layout_toRightOf="@id/logging_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/gps_locked_label"
                        android:layout_toRightOf="@id/gps_locked_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/gps_ready_label"
                        android:layout_toRightOf="@id/gps_ready_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/pad_lat_label"
                        android:layout_toRightOf="@id/gps_ready_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/pad_lon_label"
                        android:layout_toRightOf="@id/gps_ready_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
        <RelativeLayout
                        android:layout_below="@id/pad_alt_label"
                        android:layout_toRightOf="@id/gps_ready_greenled"
                        android:text=""
-                       android:textAppearance="?android:attr/textAppearanceLarge" />
+                       android:textAppearance="?android:attr/textAppearanceMedium" />
        </RelativeLayout>
 
 </LinearLayout>
\ No newline at end of file
index c9ce46a0d0c8487c075d6c95e6a8b6a845e32657..cf4227cae7895e8c713e16ee45207a177ed3b766 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,20 @@ public class AltosDroid extends FragmentActivity {
                }
                saved_state = state;
 
+               AltosGreatCircle from_receiver = null;
+
+               if (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);
+               }
+
                mCallsignView.setText(state.data.callsign);
                mSerialView.setText(String.format("%d", state.data.serial));
                mFlightView.setText(String.format("%d", state.data.flight));
@@ -222,7 +251,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, saved_location);
 
                mAltosVoice.tell(state);
        }
index 68bbe5935489b5875c94e21ca3273684104dce17..6ebb47f74e3b1ff9f3218f5655c5e1d43d6e2237 100644 (file)
@@ -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);
 }
index bda6b1fd3b5dfdb4fe63b0b8d3ff8f919a7f1926..de3bc3d29f5cefd8e5e16e2e643eff1017be410e 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;
@@ -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,7 +85,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, Location 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()));
@@ -92,8 +93,10 @@ public class TabAscent extends Fragment implements AltosDroidTab {
                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"));
+               if (state.gps != null) {
+                       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);
index 3805b7e77b98757a3e518deacc6cbdb18f8630c4..698e89fc83474c26caf62492be0f89ba0f5a79f7 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;
@@ -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,18 +89,26 @@ public class TabDescent extends Fragment implements AltosDroidTab {
                mAltosDroid = null;
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location 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>");
+               }
+               if (state.gps != null) {
+                       mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+                       mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
                }
-               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);
index a95e914557592b8de54eadd8c90067cbc1121e1d..c346dc991763cdfec4e69a45ea1f0e9146ead798 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;
@@ -26,6 +26,7 @@ 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;
@@ -68,13 +69,15 @@ 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.gps != null) {
+                       mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
+                       mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
                }
-               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()));
index 8fc8f59278ac2c59062c8bcb80d1a27a15179e5c..0a208fa8227c5fdb19473839fd130e671f83cd70 100644 (file)
@@ -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;
@@ -139,20 +140,24 @@ public class TabMap extends Fragment implements AltosDroidTab {
                }
        }
 
-       public void update_ui(AltosState state) {
+       public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location 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));
                }
-               mLatitudeView.setText(AltosDroid.pos(state.gps.lat, "N", "S"));
-               mLongitudeView.setText(AltosDroid.pos(state.gps.lon, "W", "E"));
+               if (state.gps != null) {
+                       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);
+                       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);
+                               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));
index 41776c1060a77b43fff4eaf61d2d034e295439cd..5070ec0bb0a33d765a33bc067a2f9f285bf2a105 100644 (file)
@@ -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,7 +101,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, Location receiver) {
                mBatteryVoltageView.setText(String.format("%4.2f V", state.battery));
                mBatteryLights.set(state.battery > 3.7);
 
@@ -122,18 +123,24 @@ public class TabPad extends Fragment implements AltosDroidTab {
                }
                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);
+               if (state.gps != null) {
+                       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(String.format("%4.0f m", altitude));
+               }
        }
 
 }
index 9460bdbc2817e904646a1430caf8e7944321cf78..716ec5894c9df42c5e0a975591ba8464c42e91bd 100644 (file)
@@ -68,12 +68,12 @@ public class TelemetryReader extends Thread {
                                        if (record == null)\r
                                                break;\r
                                        state = new AltosState(record, state);\r
-\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
+                                       handler.obtainMessage(TelemetryService.MSG_CRC_ERROR, new Integer(crc_errors)).sendToTarget();\r
                                }\r
                        }\r
                } catch (InterruptedException ee) {\r
index e1a5ada8ed2dd02e820f215268bcc4c8480f87b5..0ddfdfc3ad50c6ed281cac7a05b5910dd43546a7 100644 (file)
@@ -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 {
@@ -279,13 +315,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 +355,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();
index 921356a59f0cc36ae9bfda643b8f300ea423a096..f1cf0ae9089173de180b9b0e39108379ed807a53 100644 (file)
@@ -22,6 +22,8 @@ import java.lang.Math;
 public class AltosGreatCircle {
        public double   distance;
        public double   bearing;
+       public double   range;
+       public double   elevation;
 
        double sqr(double a) { return a * a; }
 
@@ -54,9 +56,8 @@ public class AltosGreatCircle {
                return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16];
        }
 
-       public AltosGreatCircle (double start_lat, double start_lon,
-                                double end_lat, double end_lon)
-       {
+       public AltosGreatCircle (double start_lat, double start_lon, double start_alt,
+                                double end_lat, double end_lon, double end_alt) {
                double lat1 = rad * start_lat;
                double lon1 = rad * -start_lon;
                double lat2 = rad * end_lat;
@@ -88,14 +89,25 @@ public class AltosGreatCircle {
                }
                distance = d * earth_radius;
                bearing = course * 180/Math.PI;
+
+               double height_diff = end_alt - start_alt;
+               range = Math.sqrt(distance * distance + height_diff * height_diff);
+               elevation = Math.atan2(height_diff, distance) * 180 / Math.PI;
+       }
+
+       public AltosGreatCircle (double start_lat, double start_lon,
+                                double end_lat, double end_lon) {
+               this(start_lat, start_lon, 0, end_lat, end_lon, 0);
        }
 
        public AltosGreatCircle(AltosGPS start, AltosGPS end) {
-               this(start.lat, start.lon, end.lat, end.lon);
+               this(start.lat, start.lon, start.alt, end.lat, end.lon, end.alt);
        }
 
        public AltosGreatCircle() {
                distance = 0;
                bearing = 0;
+               range = 0;
+               elevation = 0;
        }
 }
index f1bcb1c1a67a7e87ee5a3ef4cc70e1ce29c44351..a3b9a8c07efafdb54f889094c09e1b7ba6a505f9 100644 (file)
@@ -248,23 +248,21 @@ public class AltosState {
 
                if (height != AltosRecord.MISSING && height > max_height)
                        max_height = height;
+               elevation = 0;
+               range = -1;
+               gps_height = 0;
                if (data.gps != null) {
                        if (gps == null || !gps.locked || data.gps.locked)
                                gps = data.gps;
                        if (ngps > 0 && gps.locked) {
-                               from_pad = new AltosGreatCircle(pad_lat, pad_lon, gps.lat, gps.lon);
-                       }
-               }
-               elevation = 0;
-               range = -1;
-               if (ngps > 0) {
-                       gps_height = gps.alt - pad_alt;
-                       if (from_pad != null) {
-                               elevation = Math.atan2(height, from_pad.distance) * 180 / Math.PI;
-                               range = Math.sqrt(height * height + from_pad.distance * from_pad.distance);
+                               double h = height;
+
+                               if (h == AltosRecord.MISSING) h = 0;
+                               from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h);
+                               elevation = from_pad.elevation;
+                               range = from_pad.range;
+                               gps_height = gps.alt - pad_alt;
                        }
-               } else {
-                       gps_height = 0;
                }
        }