diff options
Diffstat (limited to 'altosdroid/src')
9 files changed, 146 insertions, 56 deletions
diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index c9ce46a0..cf4227ca 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -47,6 +47,7 @@ import android.widget.TabHost;  import android.widget.TextView;  import android.widget.Toast;  import android.app.AlertDialog; +import android.location.Location;  import org.altusmetrum.altoslib_1.*; @@ -59,6 +60,8 @@ public class AltosDroid extends FragmentActivity {  	public static final int MSG_STATE_CHANGE    = 1;  	public static final int MSG_TELEMETRY       = 2;  	public static final int MSG_UPDATE_AGE      = 3; +	public static final int MSG_LOCATION	    = 4; +	public static final int MSG_CRC_ERROR	    = 5;  	// Intent request codes  	private static final int REQUEST_CONNECT_DEVICE = 1; @@ -87,6 +90,7 @@ public class AltosDroid extends FragmentActivity {  	// Timer and Saved flight state for Age calculation  	private Timer timer = new Timer();  	AltosState saved_state; +	Location saved_location;  	// Service  	private boolean mIsBound   = false; @@ -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);  	} 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/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index bda6b1fd..de3bc3d2 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,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); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index 3805b7e7..698e89fc 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,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); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java index a95e9145..c346dc99 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,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())); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index 8fc8f592..0a208fa8 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -40,6 +40,7 @@ import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.TextView; +import android.location.Location;  public class TabMap extends Fragment implements AltosDroidTab {  	AltosDroid mAltosDroid; @@ -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)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index 41776c10..5070ec0b 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,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)); +		}  	}  } 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..0ddfdfc3 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -45,9 +45,10 @@ import android.location.LocationListener;  import org.altusmetrum.altoslib_1.*;  class AltosLocationListener implements LocationListener { -	boolean	fine; +	Handler handler;  	public void onLocationChanged(Location location) { +		handler.obtainMessage(TelemetryService.MSG_LOCATION, location).sendToTarget();  	}  	public void onStatusChanged(String provider, int status, Bundle extras) { @@ -59,8 +60,8 @@ class AltosLocationListener implements LocationListener {  	public void onProviderDisabled(String provider) {  	} -	public AltosLocationListener(boolean fine) { -		this.fine = fine; +	public AltosLocationListener(Handler handler) { +		this.handler = handler;  	}  } @@ -77,6 +78,8 @@ public class TelemetryService extends Service {  	static final int MSG_DISCONNECTED      = 6;  	static final int MSG_TELEMETRY         = 7;  	static final int MSG_SETFREQUENCY      = 8; +	static final int MSG_LOCATION	       = 9; +	static final int MSG_CRC_ERROR	       = 10;  	public static final int STATE_NONE       = 0;  	public static final int STATE_READY      = 1; @@ -107,9 +110,14 @@ public class TelemetryService extends Service {  	// location listeners -	private AltosLocationListener gpsListener; -	private AltosLocationListener netListener; +	private AltosLocationListener locationListener; +	// Last data seen; send to UI when it starts + +	private AltosState last_state; +	private Location last_location; +	private int last_crc_errors; +  	// Handler of incoming messages from clients.  	static class IncomingHandler extends Handler {  		private final WeakReference<TelemetryService> service; @@ -129,6 +137,12 @@ public class TelemetryService extends Service {  					s.mClients.remove(msg.replyTo);  				}  				if (D) Log.d(TAG, "Client bound to service"); +				if (s.last_state != null) +					s.sendTelemetry(s.last_state); +				if (s.last_location != null) +					s.sendLocation(s.last_location); +				if (s.last_crc_errors != 0) +					s.sendCrcErrors(s.last_crc_errors);  				break;  			case MSG_UNREGISTER_CLIENT:  				s.mClients.remove(msg.replyTo); @@ -155,8 +169,20 @@ public class TelemetryService extends Service {  				}  				break;  			case MSG_TELEMETRY: +				// forward telemetry messages +				s.last_state = (AltosState) msg.obj;  				s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_TELEMETRY, msg.obj));  				break; +			case MSG_LOCATION: +				// forward location messages +				s.last_location = (Location) msg.obj; +				s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_LOCATION, msg.obj)); +				break; +			case MSG_CRC_ERROR: +				// forward crc error messages +				s.last_crc_errors = (Integer) msg.obj; +				s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_CRC_ERROR, msg.obj)); +				break;  			case MSG_SETFREQUENCY:  				if (s.state == STATE_CONNECTED) {  					try { @@ -172,6 +198,16 @@ public class TelemetryService extends Service {  		}  	} +	public void sendTelemetry(AltosState state) { +	} + +	public void sendLocation(Location location) { +		mHandler.obtainMessage(MSG_LOCATION, location).sendToTarget(); +	} + +	public void sendCrcErrors(int crc_errors) { +	} +  	private void sendMessageToClients(Message m) {  		for (int i=mClients.size()-1; i>=0; i--) {  			try { @@ -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();  | 
