src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx \
src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx \
src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx \
+ src/telemega-v4.0/telemega-v4.0-$(VERSION).ihx \
src/telemetrum-v2.0/telemetrum-v2.0-$(VERSION).ihx
keithp-fat: fat
- make sure that doc/*.txt have the right copyright year and the
new release is included
- make absolutely sure checked-out tree is "clean"
+ - make absolutely sure any commits Keith might have pushed to branches
+ like debian are already pulled
git log > ChangeLog
git commit -a
src/teledongle-v3.0/{*.elf,*.ihx} \
src/telegps-v1.0/{*.elf,*.ihx} \
src/telegps-v2.0/{*.elf,*.ihx} \
- src/telemega-v1.0/{*.elf,*.ihx} \
- src/telemega-v2.0/{*.elf,*.ihx} \
- src/telemega-v3.0/{*.elf,*.ihx} \
+ src/telemega-v[1-4].0/{*.elf,*.ihx} \
src/telemetrum-v2.0/{*.elf,*.ihx} \
+ src/telemetrum-v3.0/{*.elf,*.ihx} \
src/telemini-v3.0/{*.elf,*.ihx} \
src/telelco-v2.0/{*.elf,*.ihx} \
src/telefireeight-v1.0/{*.elf,*.ihx} \
src/teledongle-v3.0/flash-loader/*.elf \
src/telegps-v1.0/flash-loader/*.elf \
src/telegps-v2.0/flash-loader/{*.elf,*.bin} \
- src/telemega-v1.0/flash-loader/*.elf \
- src/telemega-v2.0/flash-loader/*.elf \
- src/telemega-v3.0/flash-loader/*.elf \
+ src/telemega-v[1-4].0/flash-loader/*.elf \
src/telemetrum-v2.0/flash-loader/*.elf \
+ src/telemetrum-v3.0/flash-loader/*.elf \
src/telemini-v3.0/flash-loader/{*.elf,*.bin} \
src/telelco-v2.0/flash-loader/*.elf \
src/telefireeight-v1.0/flash-loader/*.elf \
$(DRAWABLE_DIR)/greenled.png \
$(DRAWABLE_DIR)/grayled.png
-GRADLEW=bash ./gradlew --no-daemon
+GRADLEW=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 bash ./gradlew --no-daemon
LAYOUTS=$(LAYOUT_DIR)/*.xml
MENUS=$(MENU_DIR)/*.xml
--- /dev/null
+build.gradle
\ No newline at end of file
+++ /dev/null
-apply plugin: 'com.android.application'
-
-def keystorePropertiesFile = file(System.properties['user.home'] + "/altusmetrumllc/android_keystore.properties")
-def keystoreProperties = new Properties()
-keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
-
-android {
- signingConfigs {
- release {
- storeFile file(System.properties['user.home'] + "/altusmetrumllc/android_keystore.jks")
- storePassword keystoreProperties['storePassword']
- keyAlias keystoreProperties['keyAlias']
- keyPassword keystoreProperties['keyPassword']
- }
- }
-
- compileSdkVersion 28
- defaultConfig {
- applicationId "org.altusmetrum.AltosDroid"
- minSdkVersion 26
- targetSdkVersion 28
- versionCode 19
- versionName "1.9.1rc1"
- }
- buildTypes {
- release {
- signingConfig signingConfigs.release
- minifyEnabled false
- debuggable false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- debug {
- debuggable true
- }
- }
- lintOptions {
- abortOnError false
- }
-}
-
-dependencies {
- implementation 'androidx.appcompat:appcompat:1.0.0'
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'com.google.android.gms:play-services-maps:17.0.0'
- implementation fileTree(dir: 'libs', include: ['*.jar'])
-}
-
--- /dev/null
+apply plugin: 'com.android.application'
+
+def keystorePropertiesFile = file(System.properties['user.home'] + "/altusmetrumllc/android_keystore.properties")
+def keystoreProperties = new Properties()
+keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+
+android {
+ signingConfigs {
+ release {
+ storeFile file(System.properties['user.home'] + "/altusmetrumllc/android_keystore.jks")
+ storePassword keystoreProperties['storePassword']
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ }
+ }
+
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "org.altusmetrum.AltosDroid"
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode @ANDROID_VERSION@
+ versionName "@VERSION@"
+ }
+ buildTypes {
+ release {
+ signingConfig signingConfigs.release
+ minifyEnabled false
+ debuggable false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ debug {
+ debuggable true
+ }
+ }
+ lintOptions {
+ abortOnError false
+ }
+}
+
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.0.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.core:core:1.2.0'
+ implementation 'com.google.android.gms:play-services-maps:17.0.0'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+}
<application android:label="@string/app_name"
android:icon="@drawable/app_icon"
android:allowBackup="true"
- android:theme="@style/CustomTheme">
+ android:theme="@style/Medium">
<activity android:name="org.altusmetrum.AltosDroid.AltosDroid"
android:label="@string/app_name"
android:theme="@android:style/Theme.Dialog"
android:configChanges="orientation|keyboardHidden" />
+ <activity android:name=".SelectTrackerActivity"
+ android:label="@string/select_tracker"
+ android:theme="@android:style/Theme.Dialog"
+ android:configChanges="orientation|keyboardHidden" />
+
<activity android:name=".PreloadMapActivity"
android:label="@string/preload_maps"
android:theme="@android:style/Theme.Dialog"
import java.lang.ref.WeakReference;
import java.util.*;
+import android.Manifest;
import android.app.Activity;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import android.os.Parcelable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import android.view.*;
import android.location.LocationManager;
import android.location.LocationListener;
import android.hardware.usb.*;
-
-import org.altusmetrum.altoslib_13.*;
+import android.content.pm.PackageManager;
+import androidx.core.app.ActivityCompat;
+import org.altusmetrum.altoslib_14.*;
class SavedState {
long received_time;
}
}
-class Tracker implements CharSequence, Comparable {
- int serial;
- String call;
- double frequency;
-
- String display;
-
- public Tracker(int serial, String call, double frequency) {
- if (call == null)
- call = "none";
-
- this.serial = serial;
- this.call = call;
- this.frequency = frequency;
- if (frequency == 0.0)
- display = "Auto";
- else if (frequency == AltosLib.MISSING) {
- display = String.format("%-8.8s %6d", call, serial);
- } else {
- display = String.format("%-8.8s %7.3f %6d", call, frequency, serial);
- }
- }
-
- public Tracker(AltosState s) {
- this(s == null ? 0 : s.cal_data().serial,
- s == null ? null : s.cal_data().callsign,
- s == null ? 0.0 : s.frequency);
- }
-
- /* CharSequence */
- public char charAt(int index) {
- return display.charAt(index);
- }
-
- public int length() {
- return display.length();
- }
-
- public CharSequence subSequence(int start, int end) throws IndexOutOfBoundsException {
- return display.subSequence(start, end);
- }
-
- public String toString() {
- return display.toString();
- }
-
- /* Comparable */
- public int compareTo (Object other) {
- Tracker o = (Tracker) other;
- if (frequency == 0.0) {
- if (o.frequency == 0.0)
- return 0;
- return -1;
- }
- if (o.frequency == 0.0)
- return 1;
-
- int a = serial - o.serial;
- int b = call.compareTo(o.call);
- int c = (int) Math.signum(frequency - o.frequency);
-
- if (b != 0)
- return b;
- if (c != 0)
- return c;
- return a;
- }
-}
-
-public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
+public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
// Actions sent to the telemetry server at startup time
public static final int REQUEST_IDLE_MODE = 5;
public static final int REQUEST_IGNITERS = 6;
public static final int REQUEST_SETUP = 7;
+ public static final int REQUEST_SELECT_TRACKER = 8;
+ public static final int REQUEST_DELETE_TRACKER = 9;
public static final String EXTRA_IDLE_MODE = "idle_mode";
public static final String EXTRA_IDLE_RESULT = "idle_result";
+ public static final String EXTRA_FREQUENCY = "frequency";
public static final String EXTRA_TELEMETRY_SERVICE = "telemetry_service";
+ public static final String EXTRA_TRACKERS = "trackers";
+ public static final String EXTRA_TRACKERS_TITLE = "trackers_title";
// Setup result bits
public static final int SETUP_BAUD = 1;
public static final int SETUP_UNITS = 2;
public static final int SETUP_MAP_SOURCE = 4;
public static final int SETUP_MAP_TYPE = 8;
+ public static final int SETUP_FONT_SIZE = 16;
public static FragmentManager fm;
TelemetryState telemetry_state;
Tracker[] trackers;
-
UsbDevice pending_usb_device;
boolean start_with_usb;
case TelemetryState.CONNECT_CONNECTED:
if (telemetry_state.config != null) {
String str = String.format("S/N %d %6.3f MHz%s", telemetry_state.config.serial,
- telemetry_state.frequency, idle_mode ? " (idle)" : "");
+ telemetry_state.frequency, telemetry_state.idle_mode ? " (idle)" : "");
if (telemetry_state.telemetry_rate != AltosLib.ao_telemetry_rate_38400)
str = str.concat(String.format(" %d bps",
AltosLib.ao_telemetry_rate_values[telemetry_state.telemetry_rate]));
}
int selected_serial = 0;
- int current_serial;
long switch_time;
void set_switch_time() {
if (new_telemetry_state != null)
telemetry_state = new_telemetry_state;
- if (selected_serial != 0)
- current_serial = selected_serial;
+ if (selected_frequency != AltosLib.MISSING) {
+ AltosState selected_state = telemetry_state.get(selected_serial);
+ AltosState latest_state = telemetry_state.get(telemetry_state.latest_serial);
+
+ if (selected_state != null && selected_state.frequency == selected_frequency) {
+ selected_frequency = AltosLib.MISSING;
+ } else if ((selected_state == null || selected_state.frequency != selected_frequency) &&
+ (latest_state != null && latest_state.frequency == selected_frequency))
+ {
+ selected_frequency = AltosLib.MISSING;
+ selected_serial = telemetry_state.latest_serial;
+ }
+ }
- if (current_serial == 0)
- current_serial = telemetry_state.latest_serial;
+ if (!telemetry_state.containsKey(selected_serial)) {
+ selected_serial = telemetry_state.latest_serial;
+ AltosDebug.debug("selected serial set to %d", selected_serial);
+ }
+
+ int shown_serial = selected_serial;
+
+ if (telemetry_state.idle_mode)
+ shown_serial = telemetry_state.latest_serial;
if (!registered_units_listener) {
registered_units_listener = true;
}
int num_trackers = 0;
- for (AltosState s : telemetry_state.states.values()) {
+
+ for (AltosState s : telemetry_state.values()) {
num_trackers++;
}
int n = 0;
trackers[n++] = new Tracker(0, "auto", 0.0);
- for (AltosState s : telemetry_state.states.values())
+ for (AltosState s : telemetry_state.values())
trackers[n++] = new Tracker(s);
Arrays.sort(trackers);
- update_title(telemetry_state);
-
- AltosState state = null;
- boolean aged = true;
-
- if (telemetry_state.states.containsKey(current_serial)) {
- state = telemetry_state.states.get(current_serial);
- int age = state_age(state.received_time);
- if (age < 20)
- aged = false;
- if (current_serial == selected_serial)
- aged = false;
- else if (switch_time != 0 && (switch_time - state.received_time) > 0)
- aged = true;
- }
-
- if (aged) {
- AltosState newest_state = null;
- int newest_age = 0;
-
- for (int serial : telemetry_state.states.keySet()) {
- AltosState existing = telemetry_state.states.get(serial);
- int existing_age = state_age(existing.received_time);
+ if (telemetry_state.frequency != AltosLib.MISSING)
+ telem_frequency = telemetry_state.frequency;
- if (newest_state == null || existing_age < newest_age) {
- newest_state = existing;
- newest_age = existing_age;
- }
- }
+ update_title(telemetry_state);
- if (newest_state != null)
- state = newest_state;
- }
+ AltosState state = telemetry_state.get(shown_serial);
update_ui(telemetry_state, state, telemetry_state.quiet);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
+ static String age_string(int age) {
+ String text;
+ if (age < 60)
+ text = String.format("%ds", age);
+ else if (age < 60 * 60)
+ text = String.format("%dm", age / 60);
+ else if (age < 60 * 60 * 24)
+ text = String.format("%dh", age / (60 * 60));
+ else
+ text = String.format("%dd", age / (24 * 60 * 60));
+ return text;
+ }
+
void update_age() {
if (saved_state != null) {
int age = state_age(saved_state.received_time);
set_screen_on(age);
- String text;
- if (age < 60)
- text = String.format("%ds", age);
- else if (age < 60 * 60)
- text = String.format("%dm", age / 60);
- else if (age < 60 * 60 * 24)
- text = String.format("%dh", age / (60 * 60));
- else
- text = String.format("%dd", age / (24 * 60 * 60));
- mAgeView.setText(text);
+ mAgeView.setText(age_string(age));
}
}
for (AltosDroidTab mTab : mTabs)
mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
- AltosDebug.debug("quiet %b\n", quiet);
if (mAltosVoice != null && mTabsAdapter.currentItem() != null)
mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet);
}
int deg = (int) Math.floor(p);
double min = (p - Math.floor(p)) * 60.0;
- return String.format("%d°%9.4f\" %s", deg, min, h);
+ return String.format("%d° %7.4f\" %s", deg, min, h);
}
static String number(String format, double value) {
return tab_view;
}
+ static public int[] themes = {
+ R.style.Small,
+ R.style.Medium,
+ R.style.Large,
+ R.style.Extra
+ };
+
+ static public int[] dialog_themes = {
+ R.style.Small_Dialog,
+ R.style.Medium_Dialog,
+ R.style.Large_Dialog,
+ R.style.Extra_Dialog
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
+ // Initialise preferences
+ AltosDroidPreferences.init(this);
+ setTheme(themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
AltosDebug.init(this);
AltosDebug.debug("+++ ON CREATE +++");
- // Initialise preferences
- AltosDroidPreferences.init(this);
fm = getSupportFragmentManager();
mStateView = (TextView) findViewById(R.id.state_value);
mAgeView = (TextView) findViewById(R.id.age_value);
mAgeNewColor = mAgeView.getTextColors().getDefaultColor();
- mAgeOldColor = getResources().getColor(R.color.old_color);
+ mAgeOldColor = getResources().getColor(R.color.old_color, getTheme());
}
private void ensureBluetooth() {
noticeIntent(intent);
}
- @Override
- public void onResume() {
- super.onResume();
- AltosDebug.debug("+ ON RESUME +");
-
+ private void enable_location_updates() {
// Listen for GPS and Network position updates
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
update_ui(telemetry_state, state, true);
}
+ static final int MY_PERMISSION_REQUEST = 1001;
+
+ public boolean have_location_permission = false;
+ public boolean have_storage_permission = false;
+ public boolean asked_permission = false;
+
+ AltosMapOnline map_online;
+
+ void
+ tell_map_permission(AltosMapOnline map_online) {
+ this.map_online = map_online;
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == MY_PERMISSION_REQUEST) {
+ for (int i = 0; i < grantResults.length; i++) {
+ if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
+ if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
+ have_location_permission = true;
+ enable_location_updates();
+ if (map_online != null)
+ map_online.position_permission();
+ }
+ if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ have_storage_permission = true;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ AltosDebug.debug("+ ON RESUME +");
+
+ if (!asked_permission) {
+ asked_permission = true;
+ if (ActivityCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED)
+ {
+ have_location_permission = true;
+ }
+ if (ActivityCompat.checkSelfPermission(this,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED)
+ {
+ have_storage_permission = true;
+ }
+ int count = (have_location_permission ? 0 : 1) + (have_storage_permission ? 0 : 1);
+ if (count > 0)
+ {
+ String[] permissions = new String[count];
+ int i = 0;
+ if (!have_location_permission)
+ permissions[i++] = Manifest.permission.ACCESS_FINE_LOCATION;
+ if (!have_location_permission)
+ permissions[i++] = Manifest.permission.WRITE_EXTERNAL_STORAGE;
+ ActivityCompat.requestPermissions(this, permissions, MY_PERMISSION_REQUEST);
+ }
+ }
+ if (have_location_permission)
+ enable_location_updates();
+ }
+
@Override
public void onPause() {
super.onPause();
AltosDebug.debug("- ON PAUSE -");
// Stop listening for location updates
- ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
+ if (have_location_permission)
+ ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
}
@Override
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- AltosDebug.debug("onActivityResult " + resultCode);
+ AltosDebug.debug("onActivityResult request %d result %d", requestCode, resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect to
if (resultCode == Activity.RESULT_OK)
note_setup_changes(data);
break;
+ case REQUEST_SELECT_TRACKER:
+ if (resultCode == Activity.RESULT_OK)
+ select_tracker(data);
+ break;
+ case REQUEST_DELETE_TRACKER:
+ if (resultCode == Activity.RESULT_OK)
+ delete_track(data);
+ break;
}
}
private void note_setup_changes(Intent data) {
int changes = data.getIntExtra(SetupActivity.EXTRA_SETUP_CHANGES, 0);
+ AltosDebug.debug("note_setup_changes changes %d\n", changes);
+
if ((changes & SETUP_BAUD) != 0) {
try {
mService.send(Message.obtain(null, TelemetryService.MSG_SETBAUD,
/* nothing to do here */
}
set_switch_time();
+ if ((changes & SETUP_FONT_SIZE) != 0) {
+ AltosDebug.debug(" ==== Recreate to switch font sizes ==== ");
+ finish();
+ startActivity(getIntent());
+ }
}
private void connectUsb(UsbDevice device) {
}
private void bluetoothEnabled(Intent data) {
- try {
- mService.send(Message.obtain(null, TelemetryService.MSG_BLUETOOTH_ENABLED, null));
- } catch (RemoteException e) {
- AltosDebug.debug("send BT enabled message failed");
+ if (mService != null) {
+ try {
+ mService.send(Message.obtain(null, TelemetryService.MSG_BLUETOOTH_ENABLED, null));
+ } catch (RemoteException e) {
+ AltosDebug.debug("send BT enabled message failed");
+ }
}
}
return true;
}
+ double telem_frequency = 434.550;
+ double selected_frequency = AltosLib.MISSING;
+
void setFrequency(double freq) {
+ telem_frequency = freq;
+ selected_frequency = AltosLib.MISSING;
try {
mService.send(Message.obtain(null, TelemetryService.MSG_SETFREQUENCY, freq));
set_switch_time();
}
}
- void select_tracker(int serial) {
- int i;
+ void select_tracker(int serial, double frequency) {
- AltosDebug.debug("select tracker %d\n", serial);
+ AltosDebug.debug("select tracker %d %7.3f\n", serial, frequency);
if (serial == selected_serial) {
AltosDebug.debug("%d already selected\n", serial);
}
if (serial != 0) {
+ int i;
for (i = 0; i < trackers.length; i++)
if (trackers[i].serial == serial)
break;
AltosDebug.debug("attempt to select unknown tracker %d\n", serial);
return;
}
+ if (frequency != 0.0 && frequency != AltosLib.MISSING)
+ setFrequency(frequency);
}
- current_serial = selected_serial = serial;
+ selected_serial = serial;
update_state(null);
}
- void touch_trackers(Integer[] serials) {
- AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this);
- builder_tracker.setTitle("Select Tracker");
-
- final Tracker[] my_trackers = new Tracker[serials.length + 1];
-
- my_trackers[0] = new Tracker(null);
-
- for (int i = 0; i < serials.length; i++) {
- AltosState s = telemetry_state.states.get(serials[i]);
- my_trackers[i+1] = new Tracker(s);
- }
- builder_tracker.setItems(my_trackers,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- if (item == 0)
- select_tracker(0);
- else
- select_tracker(my_trackers[item].serial);
- }
- });
- AlertDialog alert_tracker = builder_tracker.create();
- alert_tracker.show();
+ void select_tracker(Intent data) {
+ int serial = data.getIntExtra(SelectTrackerActivity.EXTRA_SERIAL_NUMBER, 0);
+ double frequency = data.getDoubleExtra(SelectTrackerActivity.EXTRA_FREQUENCY, 0.0);
+ select_tracker(serial, frequency);
}
void delete_track(int serial) {
}
}
+ void delete_track(Intent data) {
+ int serial = data.getIntExtra(SelectTrackerActivity.EXTRA_SERIAL_NUMBER, 0);
+ if (serial != 0)
+ delete_track(serial);
+ }
+
+ void start_select_tracker(Tracker[] select_trackers, int title_id, int request) {
+ Intent intent = new Intent(this, SelectTrackerActivity.class);
+ AltosDebug.debug("put title id 0x%x %s", title_id, getResources().getString(title_id));
+ intent.putExtra(EXTRA_TRACKERS_TITLE, title_id);
+ if (select_trackers != null) {
+ ArrayList<Tracker> tracker_array = new ArrayList<Tracker>(Arrays.asList(select_trackers));
+ intent.putParcelableArrayListExtra(EXTRA_TRACKERS, tracker_array);
+ } else {
+ intent.putExtra(EXTRA_TRACKERS, (Parcelable[]) null);
+ }
+ startActivityForResult(intent, request);
+ }
+
+ void start_select_tracker(Tracker[] select_trackers) {
+ start_select_tracker(select_trackers, R.string.select_tracker, REQUEST_SELECT_TRACKER);
+ }
+
+ void touch_trackers(Integer[] serials) {
+ Tracker[] my_trackers = new Tracker[serials.length];
+
+ for (int i = 0; i < serials.length; i++) {
+ AltosState s = telemetry_state.get(serials[i]);
+ my_trackers[i] = new Tracker(s);
+ }
+ start_select_tracker(my_trackers);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent = null;
frequency_strings[i] = frequencies[i].toString();
AlertDialog.Builder builder_freq = new AlertDialog.Builder(this);
- builder_freq.setTitle("Pick a frequency");
+ builder_freq.setTitle("Select Frequency");
builder_freq.setItems(frequency_strings,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
setFrequency(frequencies[item]);
+ selected_frequency = frequencies[item].frequency;
}
});
AlertDialog alert_freq = builder_freq.create();
alert_freq.show();
return true;
case R.id.select_tracker:
- if (trackers != null) {
- AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
- builder_serial.setTitle("Select a tracker");
- builder_serial.setItems(trackers,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- System.out.printf("select item %d %s\n", item, trackers[item].display);
- if (item == 0)
- select_tracker(0);
- else
- select_tracker(trackers[item].serial);
- }
- });
- AlertDialog alert_serial = builder_serial.create();
- alert_serial.show();
-
- }
+ start_select_tracker(trackers);
return true;
case R.id.delete_track:
- if (trackers != null) {
- AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
- builder_serial.setTitle("Delete a track");
- final Tracker[] my_trackers = new Tracker[trackers.length - 1];
- for (int i = 0; i < trackers.length - 1; i++)
- my_trackers[i] = trackers[i+1];
- builder_serial.setItems(my_trackers,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- delete_track(my_trackers[item].serial);
- }
- });
- AlertDialog alert_serial = builder_serial.create();
- alert_serial.show();
-
- }
+ if (trackers != null && trackers.length > 0)
+ start_select_tracker(trackers, R.string.delete_track, REQUEST_DELETE_TRACKER);
return true;
case R.id.idle_mode:
serverIntent = new Intent(this, IdleModeActivity.class);
serverIntent.putExtra(EXTRA_IDLE_MODE, idle_mode);
+ serverIntent.putExtra(EXTRA_FREQUENCY, telem_frequency);
startActivityForResult(serverIntent, REQUEST_IDLE_MODE);
return true;
}
import android.os.Handler;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public abstract class AltosDroidLink extends AltosLink {
package org.altusmetrum.AltosDroid;
import android.location.Location;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public interface AltosDroidMapInterface {
public void onCreateView(AltosDroid altos_droid);
import java.util.*;
import android.content.Context;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosDroidPreferences extends AltosPreferences {
final static String activeDeviceAddressPreference = "ACTIVE-DEVICE-ADDRESS";
final static String activeDeviceNamePreference = "ACTIVE-DEVICE-NAME";
+ public static final int font_size_small = 0;
+ public static final int font_size_medium = 1;
+ public static final int font_size_large = 2;
+ public static final int font_size_extra = 3;
+
+ final static String fontSizePreference = "FONT-SIZE";
+
+ static int font_size = font_size_medium;
+
static DeviceAddress active_device_address;
/* Map source preference name */
static int map_source;
+ /* Tracker sort selection */
+ final static String trackerSortPreference = "TRACKER-SORT";
+
+ static int tracker_sort;
+
public static void init(Context context) {
if (backend != null)
return;
AltosPreferences.init(new AltosDroidPreferencesBackend(context));
+ font_size = backend.getInt(fontSizePreference, font_size_medium);
+
String address = backend.getString(activeDeviceAddressPreference, null);
String name = backend.getString(activeDeviceNamePreference, null);
active_device_address = new DeviceAddress (address, name);
map_source = backend.getInt(mapSourcePreference, MAP_SOURCE_ONLINE);
+
+ tracker_sort = backend.getInt(trackerSortPreference, 0);
}
public static void set_active_device(DeviceAddress address) {
map_source_listeners.remove(l);
}
}
+
+ public static int font_size() {
+ synchronized (backend) {
+ return font_size;
+ }
+ }
+
+ public static void set_font_size(int new_font_size) {
+ synchronized (backend) {
+ if (font_size != new_font_size) {
+ font_size = new_font_size;
+ backend.putInt(fontSizePreference, font_size);
+ flush_preferences();
+ }
+ }
+ }
+
+
+ public static int tracker_sort() {
+ synchronized(backend) {
+ return tracker_sort;
+ }
+ }
+
+ public static void set_tracker_sort(int new_tracker_sort) {
+ synchronized(backend) {
+ if (tracker_sort != new_tracker_sort) {
+ tracker_sort = new_tracker_sort;
+ backend.putInt(trackerSortPreference, tracker_sort);
+ flush_preferences();
+ }
+ }
+ }
}
import android.os.Environment;
import android.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
public final static String NAME = "org.altusmetrum.AltosDroid";
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.location.Location;
import android.app.Activity;
+import android.content.*;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.widget.TextView;
}
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- altos_droid = (AltosDroid) activity;
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ altos_droid = (AltosDroid) context;
altos_droid.registerTab(this);
}
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.graphics.*;
import android.view.*;
draw_bitmap(here, here_bitmap, here_off_x, here_off_y);
}
- @Override public void invalidate() {
- Rect r = new Rect();
- getDrawingRect(r);
- super.invalidate();
- }
-
- @Override public void invalidate(int l, int t, int r, int b) {
- Rect rect = new Rect();
- getDrawingRect(rect);
- super.invalidate();
- }
-
@Override
protected void onDraw(Canvas view_canvas) {
if (map == null) {
if (telem_state != null) {
Integer[] old_serial = rockets.keySet().toArray(new Integer[0]);
- Integer[] new_serial = telem_state.states.keySet().toArray(new Integer[0]);
+ Integer[] new_serial = telem_state.keySet().toArray(new Integer[0]);
/* remove deleted keys */
for (int serial : old_serial) {
- if (!telem_state.states.containsKey(serial))
+ if (!telem_state.containsKey(serial))
rockets.remove(serial);
}
for (int serial : new_serial) {
Rocket rocket;
- AltosState t_state = telem_state.states.get(serial);
+ AltosState t_state = telem_state.get(serial);
if (rockets.containsKey(serial))
rocket = rockets.get(serial);
else {
if (t_state.gps != null) {
AltosLatLon latlon = new AltosLatLon(t_state.gps.lat, t_state.gps.lon);
rocket.set_position(latlon, t_state.received_time);
- if (state.cal_data().serial == serial)
+ if (state != null && state.cal_data().serial == serial)
there = latlon;
}
if (state != null)
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
return true;
}
+ void
+ position_permission() {
+ if (mMap != null)
+ mMap.setMyLocationEnabled(true);
+ }
+
@Override
public void onMapReady(GoogleMap googleMap) {
final int map_type = AltosPreferences.map_type();
mMap = googleMap;
if (mMap != null) {
map_type_changed(map_type);
- mMap.setMyLocationEnabled(true);
+ if (altos_droid.have_location_permission)
+ mMap.setMyLocationEnabled(true);
+ else
+ altos_droid.tell_map_permission(this);
mMap.getUiSettings().setTiltGesturesEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(false);
mMap.setOnMarkerClickListener(this);
if (telem_state != null) {
for (int serial : rockets.keySet()) {
- if (!telem_state.states.containsKey(serial))
+ if (!telem_state.containsKey(serial))
remove_rocket(serial);
}
- for (int serial : telem_state.states.keySet()) {
- set_rocket(serial, telem_state.states.get(serial));
+ for (int serial : telem_state.keySet()) {
+ set_rocket(serial, telem_state.get(serial));
}
}
import android.app.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUsb extends AltosDroidLink {
import android.speech.tts.TextToSpeech.OnInitListener;
import android.location.Location;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosVoice {
if (!tts_enabled) return;
last_speak_time = now();
if (!quiet)
- tts.speak(s, TextToSpeech.QUEUE_ADD, null);
+ tts.speak(s, TextToSpeech.QUEUE_ADD, null, null);
}
public synchronized long time_since_speak() {
if (state == null)
return false;
- AltosDebug.debug("tell_pad lag %b ltm %d\n", last_apogee_good, last_tell_mode);
-
if (state.apogee_voltage != AltosLib.MISSING)
last_apogee_good = tell_gonogo("apogee",
state.apogee_voltage >= AltosLib.ao_igniter_good,
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.device_list);
// Set result CANCELED incase the user backs out
AltosDebug.debug("doDiscovery()");
// Indicate scanning in the title
- setProgressBarIndeterminateVisibility(true);
setTitle(R.string.scanning);
// Turn on sub-title for new devices
/* When discovery is finished, change the Activity title
*/
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
- setProgressBarIndeterminateVisibility(false);
setTitle(R.string.select_device);
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
missing = true;
set = false;
- dRed = r.getDrawable(R.drawable.redled);
- dGreen = r.getDrawable(R.drawable.greenled);
- dGray = r.getDrawable(R.drawable.grayled);
+ dRed = in_red.getContext().getDrawable(R.drawable.redled);
+ dGreen = in_red.getContext().getDrawable(R.drawable.greenled);
+ dGray = in_red.getContext().getDrawable(R.drawable.grayled);
}
public void set(Boolean s, Boolean m) {
import android.view.View.OnClickListener;
import android.widget.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class IdleModeActivity extends Activity {
- private EditText callsign;
+ private EditText callsignText;
+ private TextView frequencyView;
private Button connect;
private Button disconnect;
private Button reboot;
private Button igniters;
+ private double frequency;
public static final String EXTRA_IDLE_MODE = "idle_mode";
public static final String EXTRA_IDLE_RESULT = "idle_result";
}
private String callsign() {
- return callsign.getEditableText().toString();
+ return callsignText.getEditableText().toString();
}
public void connect_idle() {
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.idle_mode);
- callsign = (EditText) findViewById(R.id.set_callsign);
- callsign.setText(new StringBuffer(AltosPreferences.callsign()));
+ callsignText = (EditText) findViewById(R.id.set_callsign);
+ callsignText.setText(new StringBuffer(AltosPreferences.callsign()));
+
+ frequency = getIntent().getDoubleExtra(AltosDroid.EXTRA_FREQUENCY, 0.0);
+ frequencyView = (TextView) findViewById(R.id.frequency);
+ frequencyView.setText(String.format("Frequency: %7.3f MHz", frequency));
connect = (Button) findViewById(R.id.connect_idle);
connect.setOnClickListener(new OnClickListener() {
import android.view.View.*;
import android.widget.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class IgniterItem {
public String name;
if (position == selected_item)
item.igniter_view.setBackgroundColor(Color.RED);
else
- item.igniter_view.setBackgroundColor(Color.BLACK);
+ item.igniter_view.setBackgroundColor(0);
return item.igniter_view;
}
}
switch (msg.what) {
case AltosDroid.MSG_IGNITER_STATUS:
- ia.igniter_status((HashMap <String,Integer>) msg.obj);
+ @SuppressWarnings("unchecked") HashMap<String,Integer> map = (HashMap <String,Integer>) msg.obj;
+ ia.igniter_status(map);
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.igniters);
igniters_view = (ListView) findViewById(R.id.igniters);
import android.view.inputmethod.*;
import android.widget.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class FrequencyItem {
public AltosFrequency frequency;
if (position == selected_item)
item.frequency_view.setBackgroundColor(Color.RED);
else
- item.frequency_view.setBackgroundColor(Color.BLACK);
+ item.frequency_view.setBackgroundColor(0);
return item.frequency_view;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.manage_frequencies);
frequencies_view = (ListView) findViewById(R.id.frequencies);
import android.view.Window;
import android.widget.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class MapTypeActivity extends Activity {
private Button hybrid;
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.map_type);
hybrid = (Button) findViewById(R.id.map_type_hybrid);
import android.location.LocationManager;
import android.location.LocationListener;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
/**
* This Activity appears as a dialog. It lists any paired devices and
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.map_preload);
// Set result CANCELED incase the user backs out
--- /dev/null
+/*
+ * Copyright © 2020 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.AltosDroid;
+
+import java.util.*;
+import android.app.Activity;
+import android.content.*;
+import android.os.*;
+import android.util.*;
+import android.view.*;
+import android.view.View.*;
+import android.widget.*;
+import android.graphics.*;
+import android.graphics.drawable.*;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import org.altusmetrum.altoslib_14.*;
+
+class TrackerComparatorCall implements Comparator<Tracker> {
+ public int compare(Tracker a, Tracker b) {
+ int v;
+
+ v = a.compareCall(b);
+ if (v != 0)
+ return v;
+ v = a.compareAge(b);
+ if (v != 0)
+ return v;
+ v = a.compareSerial(b);
+ if (v != 0)
+ return v;
+ return a.compareFrequency(b);
+ }
+ public boolean equals(Object o) {
+ return o instanceof TrackerComparatorCall;
+ }
+}
+
+class TrackerComparatorSerial implements Comparator<Tracker> {
+ public int compare(Tracker a, Tracker b) {
+ int v;
+
+ v = a.compareSerial(b);
+ if (v != 0)
+ return v;
+ v = a.compareAge(b);
+ if (v != 0)
+ return v;
+ v = a.compareCall(b);
+ if (v != 0)
+ return v;
+ return a.compareFrequency(b);
+ }
+ public boolean equals(Object o) {
+ return o instanceof TrackerComparatorSerial;
+ }
+}
+
+class TrackerComparatorAge implements Comparator<Tracker> {
+ public int compare(Tracker a, Tracker b) {
+ int v;
+
+ v = a.compareAge(b);
+ if (v != 0)
+ return v;
+ v = a.compareCall(b);
+ if (v != 0)
+ return v;
+ v = a.compareSerial(b);
+ if (v != 0)
+ return v;
+ return a.compareFrequency(b);
+ }
+ public boolean equals(Object o) {
+ return o instanceof TrackerComparatorAge;
+ }
+}
+
+class TrackerComparatorFrequency implements Comparator<Tracker> {
+ public int compare(Tracker a, Tracker b) {
+ int v;
+
+ v = a.compareFrequency(b);
+ if (v != 0)
+ return v;
+ v = a.compareAge(b);
+ if (v != 0)
+ return v;
+ v = a.compareCall(b);
+ if (v != 0)
+ return v;
+ return a.compareSerial(b);
+ }
+ public boolean equals(Object o) {
+ return o instanceof TrackerComparatorFrequency;
+ }
+}
+
+public class SelectTrackerActivity extends Activity implements OnTouchListener {
+ // Return Intent extra
+ public static final String EXTRA_SERIAL_NUMBER = "serial_number";
+ public static final String EXTRA_FREQUENCY = "frequency";
+
+ private int button_ids[] = {
+ R.id.call_button,
+ R.id.serial_button,
+ R.id.frequency_button,
+ R.id.age_button
+ };
+
+ private static final int call_button = 0;
+ private static final int serial_button = 1;
+ private static final int freq_button = 2;
+ private static final int age_button = 3;
+ private RadioButton radio_buttons[] = new RadioButton[4];
+ private TableLayout table;
+
+ private Tracker[] trackers;
+
+ private void set_sort(int id) {
+ AltosDroidPreferences.set_tracker_sort(id);
+ resort();
+ }
+
+ private void resort() {
+ Comparator<Tracker> compare;
+ int tracker_sort = AltosDroidPreferences.tracker_sort();
+ AltosDebug.debug("sort %d", tracker_sort);
+ switch (tracker_sort) {
+ case call_button:
+ default:
+ compare = new TrackerComparatorCall();
+ break;
+ case serial_button:
+ compare = new TrackerComparatorSerial();
+ break;
+ case freq_button:
+ compare = new TrackerComparatorFrequency();
+ break;
+ case age_button:
+ compare = new TrackerComparatorAge();
+ break;
+ }
+ Arrays.sort(trackers, compare);
+ set_trackers();
+ }
+
+ void init_button_state() {
+ int tracker_sort = AltosDroidPreferences.tracker_sort();
+ for (int i = 0; i < 4; i++)
+ radio_buttons[i].setChecked(i == tracker_sort);
+ }
+
+ OnCheckedChangeListener button_listener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ int id = buttonView.getId();
+ if (isChecked) {
+ int sort_id = -1;
+ for (int i = 0; i < 4; i++) {
+ if (id == button_ids[i])
+ sort_id = i;
+ else
+ radio_buttons[i].setChecked(false);
+ }
+ if (sort_id != -1)
+ set_sort(sort_id);
+ }
+ }
+ };
+
+ long start_time;
+
+ private void
+ insert_tracker(Tracker tracker) {
+ TableRow row = (TableRow) getLayoutInflater().inflate(R.layout.tracker_ent, null);
+
+ ((TextView) row.findViewById(R.id.call_view)).setText(tracker.call);
+ if (tracker.serial == 0)
+ ((TextView) row.findViewById(R.id.serial_view)).setText("");
+ else
+ ((TextView) row.findViewById(R.id.serial_view)).setText(String.format("%d", tracker.serial));
+ if (tracker.frequency == 0.0)
+ ((TextView) row.findViewById(R.id.frequency_view)).setText("");
+ else if (tracker.frequency == AltosLib.MISSING)
+ ((TextView) row.findViewById(R.id.frequency_view)).setText("");
+ else
+ ((TextView) row.findViewById(R.id.frequency_view)).setText(String.format("%7.3f", tracker.frequency));
+ if (tracker.received_time != 0) {
+ int age = (int) ((start_time - tracker.received_time + 500) / 1000);
+ ((TextView) row.findViewById(R.id.age_view)).setText(AltosDroid.age_string(age));
+ } else {
+ ((TextView) row.findViewById(R.id.age_view)).setText("");
+ }
+ row.setClickable(true);
+ row.setOnTouchListener(this);
+ table.addView(row);
+ }
+
+ private void set_trackers() {
+ for (int i = table.getChildCount() - 1; i >= 1; i--)
+ table.removeViewAt(i);
+ for (Tracker tracker : trackers)
+ insert_tracker(tracker);
+ }
+
+ private void done(View v) {
+ int result = Activity.RESULT_CANCELED;
+ Intent intent = new Intent();
+ for (int i = 1; i < table.getChildCount(); i++) {
+ View child = table.getChildAt(i);
+ if (child == v) {
+ Tracker tracker = trackers[i - 1];
+ intent.putExtra(EXTRA_SERIAL_NUMBER, tracker.serial);
+ intent.putExtra(EXTRA_FREQUENCY, tracker.frequency);
+ result = Activity.RESULT_OK;
+ break;
+ }
+ }
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ int title_id = getIntent().getIntExtra(AltosDroid.EXTRA_TRACKERS_TITLE, R.id.select_tracker);
+ AltosDebug.debug("get title id 0x%x %s", title_id, getResources().getText(title_id));
+ setTitle(getResources().getText(title_id));
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.tracker_list);
+ // Set result CANCELED incase the user backs out
+ setResult(Activity.RESULT_CANCELED);
+
+ for (int i = 0; i < 4; i++) {
+ radio_buttons[i] = (RadioButton) findViewById(button_ids[i]);
+ radio_buttons[i].setOnCheckedChangeListener(button_listener);
+ }
+
+ ArrayList<Parcelable> tracker_array = (ArrayList<Parcelable>) getIntent().getParcelableArrayListExtra(AltosDroid.EXTRA_TRACKERS);
+ if (tracker_array != null) {
+ Object[] array = tracker_array.toArray();
+ trackers = new Tracker[array.length];
+ for (int i = 0; i < array.length; i++)
+ trackers[i] = (Tracker) array[i];
+ }
+
+ start_time = System.currentTimeMillis();
+
+ table = (TableLayout) findViewById(R.id.tracker_list);
+
+ init_button_state();
+
+ resort();
+
+ set_trackers();
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ int action = event.getAction() & MotionEvent.ACTION_MASK;
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_OUTSIDE:
+ v.setBackgroundColor(0);
+ v.invalidate();
+ break;
+ case MotionEvent.ACTION_DOWN:
+ v.setBackgroundColor(Color.RED);
+ v.invalidate();
+ break;
+ }
+ if (action == MotionEvent.ACTION_UP) {
+ done(v);
+ return true;
+ }
+ return false;
+ }
+}
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class SetupActivity extends Activity {
private Spinner select_rate;
private Spinner set_units;
+ private Spinner font_size;
private Spinner map_type;
private Spinner map_source;
private Button manage_frequencies;
"2400",
};
+ static final String[] sizes = {
+ "Small",
+ "Medium",
+ "Large",
+ "Extra"
+ };
+
static final String[] map_types = {
"Hybrid",
"Satellite",
private int set_map_source;
private int set_map_type;
private boolean set_imperial_units;
-
- private int changes = 0;
-
- private void add_change(int change) {
- changes |= change;
- }
+ private int set_font_size;
private void done() {
+ int changes = 0;
Intent intent = new Intent();
- if ((changes & AltosDroid.SETUP_BAUD) != 0)
+
+ if (set_telemetry_rate != AltosPreferences.telemetry_rate(1)) {
+ changes |= AltosDroid.SETUP_BAUD;
AltosPreferences.set_telemetry_rate(1, set_telemetry_rate);
- if ((changes & AltosDroid.SETUP_UNITS) != 0)
+ }
+ if (set_imperial_units != AltosPreferences.imperial_units()) {
+ changes |= AltosDroid.SETUP_UNITS;
AltosPreferences.set_imperial_units(set_imperial_units);
- if ((changes & AltosDroid.SETUP_MAP_SOURCE) != 0)
+ }
+ if (set_map_source != AltosDroidPreferences.map_source()) {
+ changes |= AltosDroid.SETUP_MAP_SOURCE;
AltosDroidPreferences.set_map_source(set_map_source);
- if ((changes & AltosDroid.SETUP_MAP_TYPE) != 0)
+ }
+ if (set_map_type != AltosPreferences.map_type()) {
+ changes |= AltosDroid.SETUP_MAP_TYPE;
AltosPreferences.set_map_type(set_map_type);
+ }
+ if (set_font_size != AltosDroidPreferences.font_size()) {
+ changes |= AltosDroid.SETUP_FONT_SIZE;
+ AltosDroidPreferences.set_font_size(set_font_size);
+ }
intent.putExtra(EXTRA_SETUP_CHANGES, changes);
setResult(Activity.RESULT_OK, intent);
finish();
}
private void add_strings(Spinner spinner, String[] strings, int def) {
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item);
for (int i = 0; i < strings.length; i++)
adapter.add(strings[i]);
}
private void setBaud(int baud) {
- try {
- service.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, baud));
- set_telemetry_rate = baud;
- add_change(AltosDroid.SETUP_BAUD);
- } catch (RemoteException e) {
- }
+ set_telemetry_rate = baud;
}
private int string_to_rate(String baud) {
set_imperial_units = true;
break;
}
- add_change(AltosDroid.SETUP_UNITS);
+ }
+
+ private void set_font_size(int pos) {
+ set_font_size = pos;
}
private int default_map_type_pos() {
private void select_map_type(int pos) {
set_map_type = map_type_values[pos];
- add_change(AltosDroid.SETUP_MAP_TYPE);
}
private int default_map_source_pos() {
set_map_source = AltosDroidPreferences.MAP_SOURCE_OFFLINE;
break;
}
- add_change(AltosDroid.SETUP_MAP_SOURCE);
}
private void manage_frequencies(){
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
super.onCreate(savedInstanceState);
AltosDebug.init(this);
AltosDroidPreferences.init(this);
// Setup the window
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.setup);
select_rate = (Spinner) findViewById(R.id.select_rate);
add_strings(select_rate, rates, default_rate_pos());
select_rate.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ AltosDebug.debug("rate selected pos %d id %d", pos, id);
select_rate(pos);
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
+ font_size = (Spinner) findViewById(R.id.font_size);
+ add_strings(font_size, sizes, AltosDroidPreferences.font_size());
+ font_size.setOnItemSelectedListener(new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ set_font_size(pos);
+ }
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
map_type = (Spinner) findViewById(R.id.map_type);
add_strings(map_type, map_types, default_map_type_pos());
map_type.setOnItemSelectedListener(new OnItemSelectedListener() {
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.os.Bundle;
import android.view.*;
public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
if (state != null) {
- set_value(speed_view, AltosConvert.speed, 6, state.speed());
- set_value(height_view, AltosConvert.height, 6, state.height());
- set_value(max_speed_view, AltosConvert.speed, 6, state.max_speed());
- set_value(max_height_view, AltosConvert.height, 6, state.max_height());
+ set_value(speed_view, AltosConvert.speed, 1, state.speed());
+ set_value(height_view, AltosConvert.height, 1, state.height());
+ set_value(max_speed_view, AltosConvert.speed, 1, state.max_speed());
+ set_value(max_height_view, AltosConvert.height, 1, state.max_height());
if (from_receiver != null) {
- elevation_view.setText(AltosDroid.number("%3.0f°", from_receiver.elevation));
- set_value(range_view, AltosConvert.distance, 6, from_receiver.range);
- bearing_view.setText(AltosDroid.number("%3.0f°", from_receiver.bearing));
+ elevation_view.setText(AltosDroid.number("%1.0f°", from_receiver.elevation));
+ set_value(range_view, AltosConvert.distance, 1, from_receiver.range);
+ bearing_view.setText(AltosDroid.number("%1.0f°", from_receiver.bearing));
compass_view.setText(from_receiver.bearing_words(AltosGreatCircle.BEARING_LONG));
- set_value(distance_view, AltosConvert.distance, 6, from_receiver.distance);
+ set_value(distance_view, AltosConvert.distance, 1, from_receiver.distance);
} else {
elevation_view.setText("<unknown>");
range_view.setText("<unknown>");
if (state.apogee_voltage == AltosLib.MISSING) {
apogee_view.setVisibility(View.GONE);
} else {
- apogee_voltage_view.setText(AltosDroid.number("%4.2f V", state.apogee_voltage));
+ apogee_voltage_view.setText(AltosDroid.number("%1.2f V", state.apogee_voltage));
apogee_lights.set(state.apogee_voltage > 3.2, state.apogee_voltage == AltosLib.MISSING);
apogee_view.setVisibility(View.VISIBLE);
}
if (state.main_voltage == AltosLib.MISSING) {
main_view.setVisibility(View.GONE);
} else {
- main_voltage_view.setText(AltosDroid.number("%4.2f V", state.main_voltage));
+ main_voltage_view.setText(AltosDroid.number("%1.2f V", state.main_voltage));
main_lights.set(state.main_voltage > 3.2, state.main_voltage == AltosLib.MISSING);
main_view.setVisibility(View.VISIBLE);
}
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.app.Activity;
import android.os.Bundle;
private View view;
private int map_source;
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.tab_map, container, false);
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.os.Bundle;
import android.view.*;
public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
if (state != null) {
- battery_voltage_view.setText(AltosDroid.number(" %4.2f V", state.battery_voltage));
+ battery_voltage_view.setText(AltosDroid.number("%1.2f V", state.battery_voltage));
battery_lights.set(state.battery_voltage >= AltosLib.ao_battery_good, state.battery_voltage == AltosLib.MISSING);
if (state.apogee_voltage == AltosLib.MISSING) {
apogee_row.setVisibility(View.GONE);
} else {
- apogee_voltage_view.setText(AltosDroid.number(" %4.2f V", state.apogee_voltage));
+ apogee_voltage_view.setText(AltosDroid.number("%1.2f V", state.apogee_voltage));
apogee_row.setVisibility(View.VISIBLE);
}
apogee_lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good, state.apogee_voltage == AltosLib.MISSING);
if (state.main_voltage == AltosLib.MISSING) {
main_row.setVisibility(View.GONE);
} else {
- main_voltage_view.setText(AltosDroid.number(" %4.2f V", state.main_voltage));
+ main_voltage_view.setText(AltosDroid.number("%1.2f V", state.main_voltage));
main_row.setVisibility(View.VISIBLE);
}
main_lights.set(state.main_voltage >= AltosLib.ao_igniter_good, state.main_voltage == AltosLib.MISSING);
if (voltage == AltosLib.MISSING) {
ignite_row[i].setVisibility(View.GONE);
} else {
- ignite_voltage_view[i].setText(AltosDroid.number(" %4.2f V", voltage));
+ ignite_voltage_view[i].setText(AltosDroid.number("%1.2f V", voltage));
ignite_row[i].setVisibility(View.VISIBLE);
}
ignite_lights[i].set(voltage >= AltosLib.ao_igniter_good, voltage == AltosLib.MISSING);
if (telem_state.receiver_battery == AltosLib.MISSING) {
receiver_row.setVisibility(View.GONE);
} else {
- receiver_voltage_view.setText(AltosDroid.number(" %4.2f V", telem_state.receiver_battery));
+ receiver_voltage_view.setText(AltosDroid.number("%1.2f V", telem_state.receiver_battery));
receiver_row.setVisibility(View.VISIBLE);
}
receiver_voltage_lights.set(telem_state.receiver_battery >= AltosLib.ao_battery_good, telem_state.receiver_battery == AltosLib.MISSING);
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.os.Bundle;
import android.view.LayoutInflater;
public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
if (from_receiver != null) {
- mBearingView.setText(String.format("%3.0f°", from_receiver.bearing));
- set_value(mDistanceView, AltosConvert.distance, 6, from_receiver.distance);
+ mBearingView.setText(String.format("%1.0f°", from_receiver.bearing));
+ set_value(mDistanceView, AltosConvert.distance, 1, from_receiver.distance);
String direction = AltosDroid.direction(from_receiver, receiver);
if (direction == null)
mDirectionView.setText("");
}
if (state != null) {
- set_value(mMaxHeightView, AltosConvert.height, 6, state.max_height());
- set_value(mMaxAccelView, AltosConvert.accel, 6, state.max_acceleration());
- set_value(mMaxSpeedView, AltosConvert.speed, 6, state.max_speed());
+ set_value(mMaxHeightView, AltosConvert.height, 1, state.max_height());
+ set_value(mMaxAccelView, AltosConvert.accel, 1, state.max_acceleration());
+ set_value(mMaxSpeedView, AltosConvert.speed, 1, state.max_speed());
}
}
}
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
- mViewPager.setOnPageChangeListener(this);
+ mViewPager.addOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import java.util.concurrent.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class TelemetryReader extends Thread {
import android.content.Context;
import android.os.*;
import android.widget.Toast;
+import androidx.core.app.NotificationCompat;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class TelemetryService extends Service implements AltosIdleMonitorListener {
case MSG_SETFREQUENCY:
AltosDebug.debug("MSG_SETFREQUENCY");
s.telemetry_state.frequency = (Double) msg.obj;
- if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) {
+ if (s.idle_monitor != null) {
+ s.idle_monitor.set_frequency(s.telemetry_state.frequency);
+ } else if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) {
try {
s.altos_link.set_radio_frequency(s.telemetry_state.frequency);
s.altos_link.save_frequency();
private void telemetry(AltosTelemetry telem) {
AltosState state;
- if (telemetry_state.states.containsKey(telem.serial()))
- state = telemetry_state.states.get(telem.serial());
- else
+ state = telemetry_state.get(telem.serial());
+ if (state == null)
state = new AltosState(new AltosCalData());
telem.provide_data(state);
- telemetry_state.states.put(telem.serial(), state);
+ telemetry_state.put(telem.serial(), state);
telemetry_state.quiet = false;
if (state != null) {
AltosPreferences.set_state(state,telem.serial());
private Message message() {
if (telemetry_state == null)
AltosDebug.debug("telemetry_state null!");
- if (telemetry_state.states == null)
- AltosDebug.debug("telemetry_state.states null!");
return Message.obtain(null, AltosDroid.MSG_STATE, telemetry_state);
}
}
private void delete_serial(int serial) {
- telemetry_state.states.remove((Integer) serial);
+ telemetry_state.remove(serial);
AltosPreferences.remove_state(serial);
send_to_clients();
}
telemetry_stop();
idle_monitor = new AltosIdleMonitor(this, altos_link, true, false);
idle_monitor.set_callsign(AltosPreferences.callsign());
+ idle_monitor.set_frequency(telemetry_state.frequency);
+ telemetry_state.idle_mode = true;
idle_monitor.start();
send_idle_mode_to_clients();
}
} catch (InterruptedException ie) {
}
idle_monitor = null;
+ telemetry_state.idle_mode = false;
telemetry_start();
send_idle_mode_to_clients();
}
for (int serial : serials) {
AltosState saved_state = AltosPreferences.state(serial);
if (saved_state != null) {
- if (telemetry_state.latest_serial == 0)
- telemetry_state.latest_serial = serial;
-
AltosDebug.debug("recovered old state serial %d flight %d",
serial,
saved_state.cal_data().flight);
AltosDebug.debug("\tposition %f,%f",
saved_state.gps.lat,
saved_state.gps.lon);
- telemetry_state.states.put(serial, saved_state);
+ telemetry_state.put(serial, saved_state);
} else {
AltosDebug.debug("Failed to recover state for %d", serial);
AltosPreferences.remove_state(serial);
: "";
// Create notification to be displayed while the service runs
- Notification notification = new Notification.Builder(this, channelId)
+ Notification notification = new NotificationCompat.Builder(this, channelId)
.setContentTitle(getText(R.string.telemetry_service_label))
.setContentText(getText(R.string.telemetry_service_started))
.setContentIntent(contentIntent)
/* AltosIdleMonitorListener */
public void update(AltosState state, AltosListenerState listener_state) {
- telemetry_state.states.put(state.cal_data().serial, state);
+ if (state != null)
+ AltosDebug.debug("update call %s freq %7.3f", state.cal_data().callsign, state.frequency);
+ telemetry_state.put(state.cal_data().serial, state);
telemetry_state.receiver_battery = listener_state.battery;
send_to_clients();
}
package org.altusmetrum.AltosDroid;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class TelemetryState {
public static final int CONNECT_NONE = 0;
double frequency;
int telemetry_rate;
+ boolean idle_mode;
boolean quiet;
- HashMap<Integer,AltosState> states;
+ private HashMap<Integer,AltosState> states;
int latest_serial;
+ long latest_received_time;
+
+ public void put(int serial, AltosState state) {
+ long received_time = state.received_time;
+ if (received_time > latest_received_time || latest_serial == 0) {
+ latest_serial = serial;
+ latest_received_time = received_time;
+ }
+ states.put(serial, state);
+ }
+
+ public AltosState get(int serial) {
+ if (states.containsKey(serial))
+ return states.get(serial);
+ return null;
+ }
+
+ public void remove(int serial) {
+ states.remove((Integer) serial);
+ }
+
+ public Set<Integer> keySet() {
+ return states.keySet();
+ }
+
+ public Collection<AltosState> values() {
+ return states.values();
+ }
+
+ public boolean containsKey(int serial) {
+ return states.containsKey(serial);
+ }
public TelemetryState() {
connect = CONNECT_NONE;
--- /dev/null
+/*
+ * Copyright © 2020 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.AltosDroid;
+
+import java.lang.ref.WeakReference;
+import java.util.*;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothAdapter;
+import android.content.Intent;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.content.DialogInterface;
+import android.os.IBinder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.Parcelable;
+import android.os.Parcel;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import android.view.*;
+import android.widget.*;
+import android.app.AlertDialog;
+import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationListener;
+import android.hardware.usb.*;
+import android.content.pm.PackageManager;
+import androidx.core.app.ActivityCompat;
+import org.altusmetrum.altoslib_14.*;
+
+public class Tracker implements CharSequence, Comparable, Parcelable {
+ int serial;
+ String call;
+ double frequency;
+ long received_time;
+ String display;
+
+ private void make_display() {
+ if (frequency == 0.0)
+ display = "Auto";
+ else if (frequency == AltosLib.MISSING) {
+ display = String.format("%-8.8s %6d", call, serial);
+ } else {
+ display = String.format("%-8.8s %7.3f %6d", call, frequency, serial);
+ }
+ }
+
+ public Tracker(int serial, String call, double frequency, long received_time) {
+ if (call == null)
+ call = "none";
+
+ this.serial = serial;
+ this.call = call;
+ this.frequency = frequency;
+ this.received_time = received_time;
+ make_display();
+ }
+
+ public Tracker(int serial, String call, double frequency) {
+ this(serial, call, frequency, 0);
+ }
+
+ public Tracker(AltosState s) {
+ this(s == null ? 0 : s.cal_data().serial,
+ s == null ? null : s.cal_data().callsign,
+ s == null ? 0.0 : s.frequency,
+ s == null ? 0 : s.received_time);
+ }
+
+ /* CharSequence */
+ public char charAt(int index) {
+ return display.charAt(index);
+ }
+
+ public int length() {
+ return display.length();
+ }
+
+ public CharSequence subSequence(int start, int end) throws IndexOutOfBoundsException {
+ return display.subSequence(start, end);
+ }
+
+ public String toString() {
+ return display.toString();
+ }
+
+ /* Comparable */
+ public int compareTo (Object other) {
+ Tracker o = (Tracker) other;
+ if (frequency == 0.0) {
+ if (o.frequency == 0.0)
+ return 0;
+ return -1;
+ }
+ if (o.frequency == 0.0)
+ return 1;
+
+ int a = serial - o.serial;
+ int b = call.compareTo(o.call);
+ int c = (int) Math.signum(frequency - o.frequency);
+
+ if (b != 0)
+ return b;
+ if (c != 0)
+ return c;
+ return a;
+ }
+
+ /* Parcelable */
+
+ public int describeContents() {
+ AltosDebug.debug("describe contents %d", serial);
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ AltosDebug.debug("write to parcel %s", display);
+ out.writeInt(serial);
+ out.writeString(call);
+ out.writeDouble(frequency);
+ out.writeLong(received_time);
+ }
+
+ public static final Parcelable.Creator<Tracker> CREATOR
+ = new Parcelable.Creator<Tracker>() {
+ public Tracker createFromParcel(Parcel in) {
+ AltosDebug.debug("createFromParcel");
+ return new Tracker(in);
+ }
+
+ public Tracker[] newArray(int size) {
+ AltosDebug.debug("newArray %d", size);
+ return new Tracker[size];
+ }
+ };
+
+ /* newer (-1), same (0), older(1) */
+ public int compareAge(Tracker o) {
+ if (received_time == o.received_time)
+ return 0;
+ if (received_time == 0)
+ return -1;
+ if (o.received_time == 0)
+ return 1;
+ if (received_time > o.received_time)
+ return -1;
+ return 1;
+ }
+
+ public int compareCall(Tracker o) {
+ int v = call.compareTo(o.call);
+ if (v == 0)
+ return v;
+ if (call.equals("auto"))
+ return -1;
+ if (o.call.equals("auto"))
+ return 1;
+ return v;
+ }
+
+ public int compareSerial(Tracker o) {
+ return serial - o.serial;
+ }
+
+ public int compareFrequency(Tracker o) {
+ return (int) Math.signum(frequency - o.frequency);
+ }
+
+ private Tracker(Parcel in) {
+ serial = in.readInt();
+ call = in.readString();
+ frequency = in.readDouble();
+ received_time = in.readLong();
+ make_display();
+ AltosDebug.debug("Create from parcel %s", display);
+ }
+}
+
--- /dev/null
+all:
+ make -C ../../../../../../.. $@
+
+%:
+ make -C ../../../../../../.. $@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textSize="18sp"
android:padding="5dp"
-/>
\ No newline at end of file
+/>
android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <TextView android:id="@+id/set_callsign_label"
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView android:id="@+id/set_callsign_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/set_callsign_label"
+ />
+ <EditText android:id="@+id/set_callsign"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:hint="@string/set_callsign_label"/>
+ </LinearLayout>
+ <TextView android:id="@+id/frequency"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:text="@string/set_callsign_label"
+ android:text=""
/>
- <EditText android:id="@+id/set_callsign"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:hint="@string/set_callsign_label"/>
<Button android:id="@+id/connect_idle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dropdown"
/>
</TableRow>
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/font_size_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/font_size"
+ />
+ <Spinner android:id="@+id/font_size"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:prompt="@string/font_size"
+ android:spinnerMode="dropdown"
+ />
+ </TableRow>
<TableRow
android:layout_gravity="center"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical" >
- <LinearLayout
+ <TableLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:stretchColumns="2,3"
android:layout_weight="0"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:baselineAligned="true"
- android:orientation="horizontal" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/speed_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/speed_label" />
-
- <TextView
- android:id="@+id/speed_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/speed_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/height_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/height_label" />
-
- <TextView
- android:id="@+id/height_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/height_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- </LinearLayout>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:baselineAligned="true"
- android:orientation="horizontal" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/max_speed_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/max_speed_label" />
-
- <TextView
- android:id="@+id/max_speed_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/max_speed_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/max_height_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/max_height_label" />
-
- <TextView
- android:id="@+id/max_height_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/max_height_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- </LinearLayout>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:baselineAligned="true"
- android:orientation="horizontal"
- android:paddingTop="5dp" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/elevation_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/elevation_label" />
-
- <TextView
- android:id="@+id/elevation_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/elevation_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/range_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/range_label" />
-
- <TextView
- android:id="@+id/range_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/range_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- </LinearLayout>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:baselineAligned="true"
- android:orientation="horizontal"
- android:paddingTop="5dp" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/bearing_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bearing_label" />
-
- <TextView
- android:id="@+id/bearing_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/bearing_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/compass_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="" />
-
- <TextView
- android:id="@+id/compass_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/compass_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- </LinearLayout>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:baselineAligned="true"
- android:orientation="horizontal"
- android:paddingTop="5dp" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
-
- <TextView
- android:id="@+id/distance_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/gnd_distance_label" />
-
- <TextView
- android:id="@+id/distance_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/distance_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1" >
- </TextView>
-
- </LinearLayout>
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/lat_label"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/latitude_label" />
-
- <TextView
- android:id="@+id/lat_value"
+ >
+
+ <TextView
+ android:id="@+id/speed_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/speed_label" />
+
+ <TextView
+ android:id="@+id/speed_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/lat_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/lon_label"
+ >
+
+ <TextView
+ android:id="@+id/height_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/height_label" />
+
+ <TextView
+ android:id="@+id/height_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/longitude_label" />
-
- <TextView
- android:id="@+id/lon_value"
+ >
+
+ <TextView
+ android:id="@+id/max_speed_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/max_speed_label" />
+
+ <TextView
+ android:id="@+id/max_speed_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/lon_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:id="@+id/apogee_view"
- android:visibility="gone"
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dp" >
-
- <ImageView
- android:id="@+id/apogee_redled"
+ >
+
+ <TextView
+ android:id="@+id/max_height_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/max_height_label" />
+
+ <TextView
+ android:id="@+id/max_height_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="@string/apogee_voltage_label"
- android:src="@drawable/grayled" />
-
- <ImageView
- android:id="@+id/apogee_greenled"
+ >
+
+ <TextView
+ android:id="@+id/elevation_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/elevation_label" />
+
+ <TextView
+ android:id="@+id/elevation_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_toRightOf="@id/apogee_redled"
- android:contentDescription="@string/apogee_voltage_label"
- android:paddingRight="5dp"
- android:src="@drawable/grayled" />
-
- <TextView
- android:id="@+id/apogee_voltage_label"
+ >
+
+ <TextView
+ android:id="@+id/range_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/range_label" />
+
+ <TextView
+ android:id="@+id/range_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_toRightOf="@id/apogee_greenled"
- android:text="@string/apogee_voltage_label" />
-
- <TextView
- android:id="@+id/apogee_voltage_value"
+ >
+
+ <TextView
+ android:id="@+id/bearing_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/bearing_label" />
+
+ <TextView
+ android:id="@+id/bearing_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:id="@+id/main_view"
- android:visibility="gone"
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dp" >
-
- <ImageView
- android:id="@+id/main_redled"
+ >
+
+ <TextView
+ android:id="@+id/compass_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_column="3"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="@string/main_voltage_label"
- android:src="@drawable/grayled" />
-
- <ImageView
- android:id="@+id/main_greenled"
+ >
+
+ <TextView
+ android:id="@+id/distance_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/gnd_distance_label" />
+
+ <TextView
+ android:id="@+id/distance_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_toRightOf="@id/main_redled"
- android:contentDescription="@string/main_voltage_label"
- android:paddingRight="5dp"
- android:src="@drawable/grayled" />
-
- <TextView
- android:id="@+id/main_voltage_label"
+ >
+
+ <TextView
+ android:id="@+id/lat_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/latitude_label" />
+
+ <TextView
+ android:id="@+id/lat_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_toRightOf="@id/main_greenled"
- android:text="@string/main_voltage_label" />
-
- <TextView
- android:id="@+id/main_voltage_value"
+ >
+
+ <TextView
+ android:id="@+id/lon_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/longitude_label" />
+
+ <TextView
+ android:id="@+id/lon_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/apogee_view"
+ android:visibility="gone"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+ <ImageView
+ android:id="@+id/apogee_redled"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:contentDescription="@string/apogee_voltage_label"
+ android:src="@drawable/grayled" />
+
+ <ImageView
+ android:id="@+id/apogee_greenled"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:contentDescription="@string/apogee_voltage_label"
+ android:src="@drawable/grayled" />
+
+ <TextView
+ android:id="@+id/apogee_voltage_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/apogee_greenled"
+ android:text="@string/apogee_voltage_label" />
+
+ <TextView
+ android:id="@+id/apogee_voltage_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/main_view"
+ android:visibility="gone"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
- </LinearLayout>
+ >
+
+ <ImageView
+ android:id="@+id/main_redled"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
+ android:contentDescription="@string/main_voltage_label"
+ android:src="@drawable/grayled" />
+
+ <ImageView
+ android:id="@+id/main_greenled"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:contentDescription="@string/main_voltage_label"
+ android:paddingRight="5dp"
+ android:src="@drawable/grayled" />
+
+ <TextView
+ android:id="@+id/main_voltage_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/main_greenled"
+ android:text="@string/main_voltage_label" />
+
+ <TextView
+ android:id="@+id/main_voltage_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </TableRow>
+ </TableLayout>
</LinearLayout>
android:id="@+id/tabLabel"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:textSize="13dp"
android:textColor="#ffffff"
android:gravity="center_horizontal"
android:background="#808080"
android:layout_weight="1"/>
</FrameLayout>
- <LinearLayout
+ <TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:stretchColumns="1,3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal" >
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/distance_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/distance_label" />
-
- <TextView
- android:id="@+id/distance_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/distance_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/bearing_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/bearing_label" />
-
- <TextView
- android:id="@+id/bearing_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/bearing_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- </LinearLayout>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:baselineAligned="true"
- android:orientation="horizontal" >
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/target_lat_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/target_latitude_label" />
-
- <TextView
- android:id="@+id/target_lat_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/target_lat_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/target_lon_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/target_longitude_label" />
-
- <TextView
- android:id="@+id/target_lon_value"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/target_lon_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
- </LinearLayout>
-
- <LinearLayout
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/distance_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/distance_label" />
+
+ <TextView
+ android:id="@+id/distance_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="" />
+
+ <TextView
+ android:id="@+id/bearing_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/bearing_label" />
+
+ <TextView
+ android:id="@+id/bearing_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+ </TableLayout>
+
+ <TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
+ android:stretchColumns="1,2"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal" >
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/receiver_lat_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/receiver_latitude_label" />
-
- <TextView
- android:id="@+id/receiver_lat_value"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/receiver_lat_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="5dp" >
-
- <TextView
- android:id="@+id/receiver_lon_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/receiver_longitude_label" />
-
- <TextView
- android:id="@+id/receiver_lon_value"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/target_pos_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/target_pos_label" />
+
+ <TextView
+ android:id="@+id/target_lat_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+
+ <TextView
+ android:id="@+id/target_lon_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/receiver_lon_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
- </LinearLayout>
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/receiver_pos_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/receiver_pos_label" />
+
+ <TextView
+ android:id="@+id/receiver_lat_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+
+ <TextView
+ android:id="@+id/receiver_lon_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+ </TableLayout>
</LinearLayout>
<ImageView
android:id="@+id/battery_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/battery_voltage_label"
android:src="@drawable/grayled"
/>
<ImageView
android:id="@+id/battery_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
android:contentDescription="@string/battery_voltage_label"
+ android:paddingRight="5dp"
android:src="@drawable/grayled" />
<TextView
<ImageView
android:id="@+id/receiver_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/receiver_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/receiver_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/receiver_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/logging_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/logging_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/logging_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/logging_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/gps_locked_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/gps_locked_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/gps_locked_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/gps_locked_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/gps_ready_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/gps_ready_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/gps_ready_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/gps_ready_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/apogee_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/apogee_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/apogee_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/apogee_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/main_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/main_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/main_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/main_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_a_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_a_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_a_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_a_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_b_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_b_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_b_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_b_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_c_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_c_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_c_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_c_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_d_redled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_d_voltage_label"
android:src="@drawable/grayled" />
<ImageView
android:id="@+id/ignite_d_greenled"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:paddingRight="5dp"
android:contentDescription="@string/ignite_d_voltage_label"
android:src="@drawable/grayled" />
android:layout_height="wrap_content"
android:orientation="vertical" >
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_weight="0"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
+ <TableLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:stretchColumns="0,1"
+ android:layout_weight="0"
android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
-
- <TextView
- android:id="@+id/bearing_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bearing_label" />
-
- <TextView
- android:id="@+id/bearing_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/bearing_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
+ android:layout_height="wrap_content">
- <TextView
- android:id="@+id/direction_label"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/direction_label" />
+ >
- <TextView
- android:id="@+id/direction_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/direction_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/bearing_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/bearing_label" />
- <TextView
- android:id="@+id/distance_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/distance_label" />
+ <TextView
+ android:id="@+id/bearing_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
- <TextView
- android:id="@+id/distance_value"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@+id/distance_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ >
- <TextView
- android:id="@+id/target_lat_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/target_latitude_label" />
+ <TextView
+ android:id="@+id/direction_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/direction_label" />
- <TextView
- android:id="@+id/target_lat_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/target_lat_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/direction_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
- <TextView
- android:id="@+id/target_lon_label"
- android:layout_width="wrap_content"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/target_longitude_label" />
+ >
- <TextView
- android:id="@+id/target_lon_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/target_lon_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/distance_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/distance_label" />
- <TextView
- android:id="@+id/receiver_lat_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/receiver_latitude_label" />
+ <TextView
+ android:id="@+id/distance_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
- <TextView
- android:id="@+id/receiver_lat_value"
- android:layout_width="wrap_content"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/receiver_lat_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ >
+
+ <TextView
+ android:id="@+id/target_lat_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/target_latitude_label" />
- <TextView
- android:id="@+id/receiver_lon_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/receiver_longitude_label" />
+ <TextView
+ android:id="@+id/target_lat_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
- <TextView
- android:id="@+id/receiver_lon_value"
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/receiver_lon_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ >
- <TextView
- android:id="@+id/max_height_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/max_height_label" />
+ <TextView
+ android:id="@+id/target_lon_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/target_longitude_label" />
- <TextView
- android:id="@+id/max_height_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/max_height_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/target_lon_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
- <TextView
- android:id="@+id/max_speed_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/max_speed_label" />
+ </TableRow>
- <TextView
- android:id="@+id/max_speed_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/max_speed_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
-
- <RelativeLayout
- android:layout_gravity="fill"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+ <TextView
+ android:id="@+id/receiver_lat_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/receiver_latitude_label" />
+
+ <TextView
+ android:id="@+id/receiver_lat_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+ <TextView
+ android:id="@+id/receiver_lon_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/receiver_longitude_label" />
+
+ <TextView
+ android:id="@+id/receiver_lon_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""/>
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+ <TextView
+ android:id="@+id/max_height_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/max_height_label" />
- <TextView
- android:id="@+id/max_accel_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/max_accel_label" />
+ <TextView
+ android:id="@+id/max_height_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+
+ <TextView
+ android:id="@+id/max_speed_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/max_speed_label" />
- <TextView
- android:id="@+id/max_accel_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_below="@id/max_accel_label"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceSmall" />
- </RelativeLayout>
- </LinearLayout>
+ <TextView
+ android:id="@+id/max_speed_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+
+ <TableRow
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ >
+
+ <TextView
+ android:id="@+id/max_accel_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/max_accel_label" />
+
+ <TextView
+ android:id="@+id/max_accel_value"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+ </TableRow>
+ </TableLayout>
</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright © 2020 Keith Packard <keithp@keithp.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+-->
+<TableRow
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:id="@+id/call_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="3dp"
+ android:text="" />
+ <TextView
+ android:id="@+id/serial_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="3dp"
+ android:text="" />
+ <TextView
+ android:id="@+id/frequency_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="3dp"
+ android:text="" />
+ <TextView
+ android:id="@+id/age_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+</TableRow>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright © 2020 Keith Packard <keithp@keithp.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <TableLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/tracker_list"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:stretchColumns="1,2,3,4">
+ <TableRow
+ android:id="@+id/tracker_row"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:padding="2dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+ <RadioButton
+ android:id="@+id/call_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/callsign_label" />
+ <RadioButton
+ android:id="@+id/serial_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/serial_label" />
+ <RadioButton
+ android:id="@+id/frequency_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/freq_label" />
+ <RadioButton
+ android:id="@+id/age_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/age_label" />
+ </TableRow>
+ </TableLayout>
+ </ScrollView>
+</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="CustomTheme" parent="android:Theme.Material.Light">
- </style>
+ <style name="Small" parent="android:Theme.Material.Light">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:lineHeight">14sp</item>
+ </style>
+ <style name="Medium" parent="android:Theme.Material.Light">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">15sp</item>
+ <item name="android:lineHeight">18sp</item>
+ </style>
+ <style name="Large" parent="android:Theme.Material.Light">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">20sp</item>
+ <item name="android:lineHeight">40sp</item>
+ </style>
+ <style name="Extra" parent="android:Theme.Material.Light">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">27sp</item>
+ <item name="android:lineHeight">32sp</item>
+ </style>
+ <style name="Small.Dialog" parent="android:Theme.Material.Light.Dialog">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:lineHeight">14sp</item>
+ </style>
+ <style name="Medium.Dialog" parent="android:Theme.Material.Light.Dialog">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">15sp</item>
+ <item name="android:lineHeight">18sp</item>
+ </style>
+ <style name="Large.Dialog" parent="android:Theme.Material.Light.Dialog">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">20sp</item>
+ <item name="android:lineHeight">40sp</item>
+ </style>
+ <style name="Extra.Dialog" parent="android:Theme.Material.Light.Dialog">
+ <item name="android:textColor">#000000</item>
+ <item name="android:textSize">27sp</item>
+ <item name="android:lineHeight">32sp</item>
+ </style>
</resources>
<string name="select_tracker">Select Tracker</string>
<string name="delete_track">Delete Track</string>
<string name="map_type">Map Type</string>
- <string name="map_source">Toggle Online/Offline maps</string>
+ <string name="map_source">Map Source</string>
<!-- MapTypeActivity -->
<!-- <string name="map_type">Map Type</string> -->
<!-- DeviceListActivity -->
- <string name="scanning">scanning for devices…</string>
- <string name="select_device">select a device to connect</string>
+ <string name="scanning">Scanning…</string>
+ <string name="select_device">Select device</string>
<string name="none_paired">No devices have been paired</string>
<string name="none_found">No devices found</string>
<string name="title_paired_devices">Paired Devices</string>
<string name="title_other_devices">Other Available Devices</string>
<string name="button_scan">Scan for devices</string>
+ <!-- TrackerListActivity -->
+ <string name="freq_label">Freq</string>
+
<!-- Service -->
<string name="telemetry_service_label">AltosDroid Telemetry Service</string>
<string name="telemetry_service_started">Telemetry Service Started</string>
<!-- UI fields -->
<!-- Header -->
- <string name="callsign_label">Callsign</string>
+ <string name="callsign_label">Call</string>
<string name="serial_label">Serial</string>
<string name="flight_label">Flight</string>
<string name="state_label">State</string>
<string name="gps_ready_label">GPS Ready</string>
<string name="latitude_label">Latitude</string>
<string name="longitude_label">Longitude</string>
+ <string name="target_pos_label">Tar</string>
+ <string name="receiver_pos_label">Me</string>
<string name="target_latitude_label">Tar Lat</string>
<string name="target_longitude_label">Tar Lon</string>
<string name="receiver_latitude_label">My Lat</string>
<!-- Idle mode -->
<string name="idle_mode">Idle Mode</string>
- <string name="set_callsign_label">Callsign</string>
+ <string name="set_callsign_label">Callsign: </string>
<string name="connect_idle">Monitor</string>
<string name="disconnect_idle">Disconnect</string>
<string name="reboot_idle">Reboot</string>
<!-- <string name="map_type">Map Type</string> -->
<!-- <string name="map_source">Map Source</string> -->
<!-- <string name="preload_maps">Preload Maps</string> -->
+ <string name="font_size">Text Size</string>
<string name="manage_frequencies">Manage Frequencies</string>
<string name="done">OK</string>
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.concurrent.*;
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.*;
public boolean parse_line(String line) throws NumberFormatException {
if (line.startsWith("ADXL375 value")) {
- System.out.printf("adxl parse line %s\n", line);
String[] items = line.split("\\s+");
if (axis == AltosLib.MISSING)
throw new NumberFormatException("No ADXL375 axis specified");
if (items.length >= 3) {
accel = Integer.parseInt(items[2 + axis]);
- System.out.printf("accel %d\n", accel);
return true;
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosCRCException extends Exception {
public int rssi;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
/*
* Calibration and other data needed to construct 'real' values from various data
public int state = AltosLib.MISSING;
+ public String state_name() {
+ return AltosLib.state_name(state);
+ }
+
public void set_state(int state) {
if (state >= AltosLib.ao_flight_boost && boost_tick == AltosLib.MISSING)
set_boost_tick();
return temp_gps;
}
+ public int imu_type = AltosLib.MISSING;;
+
+ public void set_imu_type(int imu_type) {
+ this.imu_type = imu_type;
+ }
+
public double accel_zero_along, accel_zero_across, accel_zero_through;
public void set_accel_zero(double zero_along, double zero_across, double zero_through) {
}
public double accel_along(double counts) {
- return AltosIMU.convert_accel(counts - accel_zero_along);
+ return AltosIMU.convert_accel(counts - accel_zero_along, imu_type);
}
public double accel_across(double counts) {
- return AltosIMU.convert_accel(counts - accel_zero_across);
+ return AltosIMU.convert_accel(counts - accel_zero_across, imu_type);
}
public double accel_through(double counts) {
- return AltosIMU.convert_accel(counts - accel_zero_through);
+ return AltosIMU.convert_accel(counts - accel_zero_through, imu_type);
}
public double gyro_zero_roll, gyro_zero_pitch, gyro_zero_yaw;
if (gyro_zero_roll == AltosLib.MISSING || counts == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_roll);
+ return AltosIMU.gyro_degrees_per_second(counts - gyro_zero_roll, imu_type);
}
public double gyro_pitch(double counts) {
if (gyro_zero_pitch == AltosLib.MISSING || counts == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_pitch);
+ return AltosIMU.gyro_degrees_per_second(counts - gyro_zero_pitch, imu_type);
}
public double gyro_yaw(double counts) {
if (gyro_zero_yaw == AltosLib.MISSING || counts == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosIMU.gyro_degrees_per_second(counts, gyro_zero_yaw);
+ return AltosIMU.gyro_degrees_per_second(counts - gyro_zero_yaw, imu_type);
}
private double gyro_zero_overflow(double first) {
public double mag_along(double along) {
if (along == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosMag.convert_gauss(along);
+ return AltosIMU.convert_gauss(along, imu_type, AltosIMU.mag_along_axis(imu_type));
}
public double mag_across(double across) {
if (across == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosMag.convert_gauss(across);
+ return AltosIMU.convert_gauss(across, imu_type, AltosIMU.mag_across_axis(imu_type));
}
public double mag_through(double through) {
if (through == AltosLib.MISSING)
return AltosLib.MISSING;
- return AltosMag.convert_gauss(through);
+ return AltosIMU.convert_gauss(through, imu_type, AltosIMU.mag_through_axis(imu_type));
}
public AltosCalData() {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.text.*;
case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
case AltosLib.AO_LOG_FORMAT_TELEMEGA:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return 4095 - value;
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
return -value;
return true;
if (product.startsWith("TeleMetrum-v3"))
return true;
+ if (product.startsWith("TeleMega-v4"))
+ return true;
}
throw new AltosUnknownProduct(product);
}
return AltosAdxl375.X_AXIS;
if (product.startsWith("TeleMetrum-v3"))
return AltosAdxl375.X_AXIS;
+ if (product.startsWith("TeleMega-v4"))
+ return AltosAdxl375.X_AXIS;
}
throw new AltosUnknownProduct(product);
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosConfigDataException extends Exception {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosConfigValues {
/* set and get all of the dialog values */
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
public static AltosPyroName pyro_name = new AltosPyroName();
- public static AltosUnits magnetic_field = null;
+ public static AltosUnits magnetic_field = new AltosGauss();
public static String show_gs(String format, double a) {
a = meters_to_g(a);
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public abstract class AltosDataListener {
return time;
}
+ public String state_name() {
+ return cal_data().state_name();
+ }
+
public void set_state(int state) {
cal_data().set_state(state);
}
public abstract void set_apogee_voltage(double volts);
public abstract void set_main_voltage(double volts);
- public void set_gps(AltosGPS gps) {
+ public void set_gps(AltosGPS gps, boolean set_location, boolean set_sats) {
AltosCalData cal_data = cal_data();
cal_data.set_cal_gps(gps);
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosDataProvider {
public void provide_data(AltosDataListener listener) throws InterruptedException, AltosUnknownProduct;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosDistance extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
avoid_duplicate_files = true;
}
- public void set_gps(AltosGPS gps) {
- super.set_gps(gps);
+ public void set_gps(AltosGPS gps, boolean set_location, boolean set_sats) {
+ super.set_gps(gps, set_location, set_sats);
if (gps != null &&
gps.year != AltosLib.MISSING &&
gps.month != AltosLib.MISSING &&
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord> {
if (!AltosLib.is_gps_cmd(cmd())) {
AltosGPS gps = listener.temp_gps();
if (gps != null)
- listener.set_gps(gps);
+ listener.set_gps(gps, true, true);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordFull extends AltosEepromRecord {
public static final int record_length = 8;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
if (gps.vdop < 0.8)
gps.vdop += 2.56;
}
- listener.set_gps(gps);
+ listener.set_gps(gps, true, true);
break;
}
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordMega extends AltosEepromRecord {
public static final int record_length = 32;
case AltosLib.AO_LOG_FORMAT_TELEMEGA:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return data32(16);
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return data16(14);
case AltosLib.AO_LOG_FORMAT_TELEMEGA:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return data32(20);
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return data16(16);
case AltosLib.AO_LOG_FORMAT_TELEMEGA:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return data32(24);
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return data16(18);
private int mag_z() { return data16(22); }
private int mag_y() { return data16(24); }
+ private int imu_type() {
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
+ return AltosIMU.imu_type_telemega_v1_v2;
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
+ return AltosIMU.imu_type_telemega_v3;
+ case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ return AltosIMU.imu_type_easymega_v2;
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
+ return AltosIMU.imu_type_telemega_v4;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
private int accel_across() {
switch (log_format) {
case AltosLib.AO_LOG_FORMAT_TELEMEGA:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return accel_x();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return -accel_y();
default:
return AltosLib.MISSING;
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return accel_y();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return accel_x();
default:
return AltosLib.MISSING;
return gyro_x();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
return -gyro_y();
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
+ return -gyro_y();
default:
return AltosLib.MISSING;
}
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return gyro_y();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return gyro_x();
default:
return AltosLib.MISSING;
return mag_x();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
return -mag_y();
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
+ return mag_y();
default:
return AltosLib.MISSING;
}
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
return mag_y();
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
return mag_x();
default:
return AltosLib.MISSING;
AltosGPS gps;
+ cal_data.set_imu_type(imu_type());
+
switch (cmd()) {
case AltosLib.AO_LOG_FLIGHT:
cal_data.set_flight(flight());
cal_data.set_ground_accel(ground_accel());
cal_data.set_ground_pressure(ground_pres());
- listener.set_accel_ground(ground_accel_along(),
- ground_accel_across(),
- ground_accel_through());
+ listener.set_accel_ground(cal_data.accel_along(ground_accel_along()),
+ cal_data.accel_across(ground_accel_across()),
+ cal_data.accel_through(ground_accel_through()));
cal_data.set_gyro_zero(ground_roll() / 512.0,
ground_pitch() / 512.0,
ground_yaw() / 512.0);
cal_data.mag_across(mag_across),
cal_data.mag_through(mag_through));
-
- final double lsb_per_g = 1920.0/105.5;
-
- double acceleration = AltosConvert.acceleration_from_sensor(
- accel(),
- cal_data.ground_accel,
- cal_data.ground_accel + 2 * lsb_per_g,
- cal_data.ground_accel);
-
- listener.set_acceleration(acceleration);
+ listener.set_acceleration(cal_data.acceleration(accel()));
break;
case AltosLib.AO_LOG_TEMP_VOLT:
listener.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordMetrum extends AltosEepromRecord {
public static final int record_length = 16;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordMicroPeak2 extends AltosEepromRecord {
public static final int record_length = 2;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordMini extends AltosEepromRecord {
public static final int record_length = 16;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
return eeprom.config_data();
}
+ private void init_cal_data() {
+ for (AltosEepromRecord record : ordered) {
+ if (record.cmd() == AltosLib.AO_LOG_FLIGHT) {
+ cal_data.set_tick(record.tick());
+ cal_data.set_boost_tick();
+ cal_data.set_state(AltosLib.ao_flight_pad);
+ break;
+ }
+ }
+ }
+
public AltosCalData cal_data() {
if (cal_data == null) {
cal_data = new AltosCalData(config_data());
- for (AltosEepromRecord record : ordered) {
- if (record.cmd() == AltosLib.AO_LOG_FLIGHT) {
- cal_data.set_tick(record.tick());
- cal_data.set_boost_tick();
- break;
- }
- }
+ init_cal_data();
}
return cal_data;
}
public void capture_series(AltosDataListener listener) {
- AltosCalData cal_data = cal_data();
-
- cal_data.reset();
+ if (cal_data == null) {
+ cal_data();
+ } else {
+ cal_data.reset();
+ init_cal_data();
+ }
listener.set_log_format(config_data().log_format);
for (AltosEepromRecord record : ordered) {
case AltosLib.AO_LOG_FORMAT_TELEMEGA_3:
case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
record = new AltosEepromRecordMega(eeprom);
break;
case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosEepromRecordTiny extends AltosEepromRecord implements AltosDataProvider {
public static final int record_length = 2;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.File;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosFilterListener {
void filter_changed(double speed_filter, double accel_filter);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosFlashListener {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
void reset();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.io.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
}
public AltosTimeSeries orient_series;
+ public AltosTimeSeries azimuth_series;
public static final String orient_name = "Tilt Angle";
+ public static final String azimuth_name = "Azimuth Angle";
private void compute_orient() {
if (accel_ground_across == AltosLib.MISSING)
return;
- if (cal_data().pad_orientation == AltosLib.MISSING)
+ AltosCalData cal_data = cal_data();
+
+ if (cal_data.pad_orientation == AltosLib.MISSING)
return;
- if (cal_data().accel_zero_across == AltosLib.MISSING)
+ if (cal_data.accel_zero_across == AltosLib.MISSING)
return;
- AltosRotation rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
- AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
- AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
- cal_data().pad_orientation);
+ AltosRotation rotation = new AltosRotation(accel_ground_across,
+ accel_ground_through,
+ accel_ground_along,
+ cal_data.pad_orientation);
double prev_time = ground_time;
orient_series = add_series(orient_name, AltosConvert.orient);
orient_series.add(ground_time, rotation.tilt());
+ azimuth_series = add_series(azimuth_name, AltosConvert.orient);
+ azimuth_series.add(ground_time, rotation.azimuth());
+
for (AltosTimeValue roll_v : gyro_roll) {
double time = roll_v.time;
double dt = time - prev_time;
rotation.rotate(pitch, yaw, roll);
orient_series.add(time, rotation.tilt());
+ azimuth_series.add(time, rotation.azimuth());
}
prev_time = time;
}
public static final String gps_vdop_name = "GPS Vertical Dilution of Precision";
public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision";
- public void set_gps(AltosGPS gps) {
- super.set_gps(gps);
+ public void set_gps(AltosGPS gps, boolean new_location, boolean new_sats) {
+ super.set_gps(gps, new_location, new_sats);
+ AltosCalData cal_data = cal_data();
if (gps_series == null)
gps_series = new ArrayList<AltosGPSTimeValue>();
gps_series.add(new AltosGPSTimeValue(time(), gps));
- if (sats_in_soln == null) {
- sats_in_soln = add_series(sats_in_soln_name, null);
- }
- sats_in_soln.add(time(), gps.nsat);
- if (gps.pdop != AltosLib.MISSING) {
- if (gps_pdop == null)
- gps_pdop = add_series(gps_pdop_name, null);
- gps_pdop.add(time(), gps.pdop);
- }
- if (gps.hdop != AltosLib.MISSING) {
- if (gps_hdop == null)
- gps_hdop = add_series(gps_hdop_name, null);
- gps_hdop.add(time(), gps.hdop);
- }
- if (gps.vdop != AltosLib.MISSING) {
- if (gps_vdop == null)
- gps_vdop = add_series(gps_vdop_name, null);
- gps_vdop.add(time(), gps.vdop);
- }
- if (gps.locked) {
- if (gps.alt != AltosLib.MISSING) {
- if (gps_altitude == null)
- gps_altitude = add_series(gps_altitude_name, AltosConvert.height);
- gps_altitude.add(time(), gps.alt);
+ if (new_location) {
+ if (sats_in_soln == null) {
+ sats_in_soln = add_series(sats_in_soln_name, null);
}
- if (gps.ground_speed != AltosLib.MISSING) {
- if (gps_ground_speed == null)
- gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed);
- gps_ground_speed.add(time(), gps.ground_speed);
+ sats_in_soln.add(time(), gps.nsat);
+ if (gps.pdop != AltosLib.MISSING) {
+ if (gps_pdop == null)
+ gps_pdop = add_series(gps_pdop_name, null);
+ gps_pdop.add(time(), gps.pdop);
}
- if (gps.climb_rate != AltosLib.MISSING) {
- if (gps_ascent_rate == null)
- gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed);
- gps_ascent_rate.add(time(), gps.climb_rate);
+ if (gps.hdop != AltosLib.MISSING) {
+ if (gps_hdop == null)
+ gps_hdop = add_series(gps_hdop_name, null);
+ gps_hdop.add(time(), gps.hdop);
}
- if (gps.course != AltosLib.MISSING) {
- if (gps_course == null)
- gps_course = add_series(gps_course_name, null);
- gps_course.add(time(), gps.course);
+ if (gps.vdop != AltosLib.MISSING) {
+ if (gps_vdop == null)
+ gps_vdop = add_series(gps_vdop_name, null);
+ gps_vdop.add(time(), gps.vdop);
}
- if (gps.ground_speed != AltosLib.MISSING && gps.climb_rate != AltosLib.MISSING) {
- if (gps_speed == null)
- gps_speed = add_series(gps_speed_name, null);
- gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +
- gps.climb_rate * gps.climb_rate));
+ if (gps.locked) {
+ if (gps.alt != AltosLib.MISSING) {
+ if (gps_altitude == null)
+ gps_altitude = add_series(gps_altitude_name, AltosConvert.height);
+ gps_altitude.add(time(), gps.alt);
+ }
+ if (gps.ground_speed != AltosLib.MISSING) {
+ if (gps_ground_speed == null)
+ gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed);
+ gps_ground_speed.add(time(), gps.ground_speed);
+ }
+ if (gps.climb_rate != AltosLib.MISSING) {
+ if (gps_ascent_rate == null)
+ gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed);
+ gps_ascent_rate.add(time(), gps.climb_rate);
+ }
+ if (gps.course != AltosLib.MISSING) {
+ if (gps_course == null)
+ gps_course = add_series(gps_course_name, null);
+ gps_course.add(time(), gps.course);
+ }
+ if (gps.ground_speed != AltosLib.MISSING && gps.climb_rate != AltosLib.MISSING) {
+ if (gps_speed == null)
+ gps_speed = add_series(gps_speed_name, null);
+ gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +
+ gps.climb_rate * gps.climb_rate));
+ }
}
}
- if (gps.cc_gps_sat != null) {
- if (sats_in_view == null)
- sats_in_view = add_series(sats_in_view_name, null);
- sats_in_view.add(time(), gps.cc_gps_sat.length);
+ if (new_sats) {
+ if (gps.cc_gps_sat != null) {
+ if (sats_in_view == null)
+ sats_in_view = add_series(sats_in_view_name, null);
+ sats_in_view.add(time(), gps.cc_gps_sat.length);
+ }
}
}
public static final String mag_along_name = "Magnetic Field Along";
public static final String mag_across_name = "Magnetic Field Across";
public static final String mag_through_name = "Magnetic Field Through";
+ public static final String mag_total_name = "Magnetic Field Strength";
+ public static final String compass_name = "Compass";
- public AltosTimeSeries mag_along, mag_across, mag_through;
+ public AltosTimeSeries mag_along, mag_across, mag_through, mag_total, compass;
public void set_accel(double along, double across, double through) {
if (accel_along == null) {
mag_along = add_series(mag_along_name, AltosConvert.magnetic_field);
mag_across = add_series(mag_across_name, AltosConvert.magnetic_field);
mag_through = add_series(mag_through_name, AltosConvert.magnetic_field);
+ mag_total = add_series(mag_total_name, AltosConvert.magnetic_field);
+ compass = add_series(compass_name, AltosConvert.orient);
}
mag_along.add(time(), along);
mag_across.add(time(), across);
mag_through.add(time(), through);
+ mag_total.add(time(), Math.sqrt(along * along + across * across + through *through));
+ compass.add(time(), Math.atan2(across, through) * 180 / Math.PI);
}
public void set_orient(double orient) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosFontListener {
void font_size_changed(int font_size);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosForce extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.util.concurrent.*;
try {
AltosGPS gps = new AltosGPS(link, link.config_data());
if (gps != null)
- listener.set_gps(gps);
+ listener.set_gps(gps, true, true);
} catch (TimeoutException te) {
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosGPSTimeValue {
public double time;
--- /dev/null
+/*
+ * Copyright © 2020 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_14;
+
+import java.io.*;
+
+public class AltosGauss extends AltosUnits {
+
+ public double value(double v, boolean imperial_units) {
+ return v;
+ }
+
+ public double inverse(double v, boolean imperial_units) {
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ return "G";
+ }
+
+ public String say_units(boolean imperial_units) {
+ return "gauss";
+ }
+
+ public int show_fraction(int width, boolean imperial_units) {
+ return width - 1;
+ }
+
+ public AltosGauss() {
+ range_metric = new AltosUnitsRange[1];
+
+ range_metric[0] = new AltosUnitsRange(0, "µT", "microtesla") {
+ double value(double v) {
+ return v * 100;
+ }
+ int show_fraction(int width) {
+ return width / 9;
+ }
+ int say_fraction() {
+ return 0;
+ }
+ };
+
+ range_imperial = range_metric;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.lang.Math;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosHeight extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.LinkedList;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosHexsym {
String name;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.*;
import java.io.*;
public int mag_y = AltosLib.MISSING;
public int mag_z = AltosLib.MISSING;
- public static final double counts_per_g = 2048.0;
+ public static final double counts_per_g_mpu = 2048.0;
+ public static final double counts_per_g_bmx = 2048.0;
+
+ private static double counts_per_g(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
+ case imu_type_easymega_v2:
+ return counts_per_g_mpu;
+ case imu_type_telemega_v4:
+ return counts_per_g_bmx;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ public static double convert_accel(double counts, int imu_type) {
+ return counts / counts_per_g(imu_type) * AltosConvert.gravity;
+ }
+
+ public static final double GYRO_FULLSCALE_DEGREES_MPU = 2000.0;
+ public static final double GYRO_COUNTS_MPU = 32767.0;
+ public static final double counts_per_degree_mpu = GYRO_COUNTS_MPU / GYRO_FULLSCALE_DEGREES_MPU;
+ public static final double GYRO_FULLSCALE_DEGREES_BMX = 2000.0;
+ public static final double GYRO_COUNTS_BMX = 32767.0;
+ public static final double counts_per_degree_bmx = GYRO_COUNTS_BMX / GYRO_FULLSCALE_DEGREES_BMX;
+
+ private static double counts_per_degree(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
+ case imu_type_easymega_v2:
+ return counts_per_degree_mpu;
+ case imu_type_telemega_v4:
+ return counts_per_degree_bmx;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
- public static double convert_accel(double counts) {
- return counts / counts_per_g * AltosConvert.gravity;
+ public static double gyro_degrees_per_second(double counts, int imu_type) {
+ return counts / counts_per_degree(imu_type);
}
- /* In radians */
- public static final double GYRO_FULLSCALE_DEGREES = 2000.0;
- public static final double GYRO_COUNTS = 32767.0;
+ public static final int imu_axis_x = 0;
+ public static final int imu_axis_y = 1;
+ public static final int imu_axis_z = 2;
+
+ public static final double MAG_FULLSCALE_GAUSS_MPU = 48.00; /* 4800µT */
+ public static final double MAG_COUNTS_MPU = 32767.0;
+ public static final double counts_per_gauss_mpu = MAG_COUNTS_MPU / MAG_FULLSCALE_GAUSS_MPU;
+
+ public static final double counts_per_gauss_bmx = 100.0; /* BMX driver converts to µT */
+
+ public static double counts_per_gauss(int imu_type, int axis) {
+ switch(imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_easymega_v1:
+ return AltosMag.counts_per_gauss;
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v2:
+ return counts_per_gauss_mpu;
+ case imu_type_telemega_v4:
+ return 100.0;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
- public static double gyro_degrees_per_second(double counts, double cal) {
- return (counts - cal) * GYRO_FULLSCALE_DEGREES / GYRO_COUNTS;
+ public static double convert_gauss(double counts, int imu_type, int imu_axis) {
+ return counts / counts_per_gauss(imu_type, imu_axis);
}
public boolean parse_string(String line) {
return n;
}
- public static final int orient_telemega = 0;
- public static final int orient_easymega_v2 = 1;
+ public static final int imu_type_telemega_v1_v2 = 0; /* MPU6000 */
+ public static final int imu_type_telemega_v3 = 1; /* MPU9250 */
+ public static final int imu_type_telemega_v4 = 2; /* BMX160 */
+
+ public static final int imu_type_easymega_v1 = 3; /* MPU6000 */
+ public static final int imu_type_easymega_v2 = 4; /* MPU9250 */
- private int accel_across(int orient) {
- switch (orient) {
- case orient_telemega:
+ private int accel_across(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return accel_x;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
+ return -accel_y;
+ case imu_type_telemega_v4:
return -accel_y;
default:
return AltosLib.MISSING;
}
}
- private int accel_along(int orient) {
- switch (orient) {
- case orient_telemega:
+ private int accel_along(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return accel_y;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
+ case imu_type_telemega_v4:
return accel_x;
default:
return AltosLib.MISSING;
}
}
- private int accel_through(int orient) {
+ private int accel_through(int imu_type) {
return accel_z;
}
- private int gyro_roll(int orient) {
- switch (orient) {
- case orient_telemega:
+ private int gyro_roll(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return gyro_y;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
+ case imu_type_telemega_v4:
return gyro_x;
default:
return AltosLib.MISSING;
}
}
- private int gyro_pitch(int orient) {
- switch (orient) {
- case orient_telemega:
+ private int gyro_pitch(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return gyro_x;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
+ return -gyro_y;
+ case imu_type_telemega_v4:
return -gyro_y;
default:
return AltosLib.MISSING;
}
}
- private int gyro_yaw(int orient) {
+ private int gyro_yaw(int imu_type) {
return gyro_z;
}
- private int mag_across(int orient) {
- switch (orient) {
- case orient_telemega:
+ public static int mag_across_axis(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
+ return imu_axis_x;
+ case imu_type_telemega_v4:
+ case imu_type_easymega_v2:
+ return imu_axis_y;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int mag_across(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return mag_x;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
return -mag_y;
+ case imu_type_telemega_v4:
+ return mag_y;
default:
return AltosLib.MISSING;
}
}
- private int mag_along(int orient) {
- switch (orient) {
- case orient_telemega:
+ public static int mag_along_axis(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
+ return imu_axis_y;
+ case imu_type_easymega_v2:
+ case imu_type_telemega_v4:
+ return imu_axis_x;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int mag_along(int imu_type) {
+ switch (imu_type) {
+ case imu_type_telemega_v1_v2:
+ case imu_type_telemega_v3:
+ case imu_type_easymega_v1:
return mag_y;
- case orient_easymega_v2:
+ case imu_type_easymega_v2:
+ case imu_type_telemega_v4:
return mag_x;
default:
return AltosLib.MISSING;
}
}
- private int mag_through(int orient) {
+ public static int mag_through_axis(int imu_type) {
+ return imu_axis_z;
+ }
+
+ private int mag_through(int imu_type) {
return mag_z;
}
- static public void provide_data(AltosDataListener listener, AltosLink link, int orient) throws InterruptedException {
+ static public void provide_data(AltosDataListener listener, AltosLink link, int imu_type) throws InterruptedException {
try {
AltosIMU imu = new AltosIMU(link);
AltosCalData cal_data = listener.cal_data();
+ cal_data.set_imu_type(imu_type);
+
if (imu != null) {
- listener.set_gyro(cal_data.gyro_roll(imu.gyro_roll(orient)),
- cal_data.gyro_pitch(imu.gyro_pitch(orient)),
- cal_data.gyro_yaw(imu.gyro_yaw(orient)));
- listener.set_accel_ground(imu.accel_along(orient),
- imu.accel_across(orient),
- imu.accel_through(orient));
+ listener.set_gyro(cal_data.gyro_roll(imu.gyro_roll(imu_type)),
+ cal_data.gyro_pitch(imu.gyro_pitch(imu_type)),
+ cal_data.gyro_yaw(imu.gyro_yaw(imu_type)));
+ listener.set_accel_ground(cal_data.accel_along(imu.accel_along(imu_type)),
+ cal_data.accel_across(imu.accel_across(imu_type)),
+ cal_data.accel_through(imu.accel_through(imu_type)));
+ listener.set_accel(cal_data.accel_along(imu.accel_along(imu_type)),
+ cal_data.accel_across(imu.accel_across(imu_type)),
+ cal_data.accel_through(imu.accel_through(imu_type)));
if (imu.mag_x != AltosLib.MISSING) {
- listener.set_mag(cal_data.mag_along(imu.mag_along(orient)),
- cal_data.mag_across(imu.mag_across(orient)),
- cal_data.mag_through(imu.mag_through(orient)));
+ listener.set_mag(cal_data.mag_along(imu.mag_along(imu_type)),
+ cal_data.mag_across(imu.mag_across(imu_type)),
+ cal_data.mag_through(imu.mag_through(imu_type)));
}
}
} catch (TimeoutException te) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
int[] idlers;
static final int idle_gps = 0;
- static final int idle_imu = 1;
- static final int idle_imu_em_v2 = 2;
- static final int idle_mag = 3;
- static final int idle_mma655x = 4;
- static final int idle_ms5607 = 5;
- static final int idle_adxl375 = 6;
+ static final int idle_imu_tm_v1_v2 = 1;
+ static final int idle_imu_tm_v3 = 2;
+ static final int idle_imu_tm_v4 = 3;
+ static final int idle_imu_em_v1 = 4;
+ static final int idle_imu_em_v2 = 5;
+ static final int idle_mag = 6;
+ static final int idle_mma655x = 7;
+ static final int idle_ms5607 = 8;
+ static final int idle_adxl375 = 9;
static final int idle_sensor_tm = 10;
static final int idle_sensor_metrum = 11;
case idle_gps:
AltosGPS.provide_data(listener, link);
break;
- case idle_imu:
- AltosIMU.provide_data(listener, link, AltosIMU.orient_telemega);
+ case idle_imu_tm_v1_v2:
+ AltosIMU.provide_data(listener, link, AltosIMU.imu_type_telemega_v1_v2);
+ break;
+ case idle_imu_tm_v3:
+ AltosIMU.provide_data(listener, link, AltosIMU.imu_type_telemega_v3);
+ break;
+ case idle_imu_tm_v4:
+ AltosIMU.provide_data(listener, link, AltosIMU.imu_type_telemega_v4);
+ break;
+ case idle_imu_em_v1:
+ AltosIMU.provide_data(listener, link, AltosIMU.imu_type_easymega_v1);
break;
case idle_imu_em_v2:
- AltosIMU.provide_data(listener, link, AltosIMU.orient_easymega_v2);
+ AltosIMU.provide_data(listener, link, AltosIMU.imu_type_easymega_v2);
break;
case idle_mag:
AltosMag.provide_data(listener, link);
AltosIdler.idle_gps,
AltosIdler.idle_mma655x,
AltosIdler.idle_ms5607,
- AltosIdler.idle_imu, AltosIdler.idle_mag,
+ AltosIdler.idle_imu_tm_v1_v2, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleMega-v1",
AltosIdler.idle_gps,
AltosIdler.idle_mma655x,
AltosIdler.idle_ms5607,
- AltosIdler.idle_imu, AltosIdler.idle_mag,
+ AltosIdler.idle_imu_tm_v1_v2, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleMega-v2",
AltosIdler.idle_gps,
AltosIdler.idle_mma655x,
AltosIdler.idle_ms5607,
- AltosIdler.idle_imu, AltosIdler.idle_mag,
+ AltosIdler.idle_imu_tm_v1_v2, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("TeleMega-v3",
AltosIdler.idle_gps,
AltosIdler.idle_mma655x,
AltosIdler.idle_ms5607,
- AltosIdler.idle_imu,
+ AltosIdler.idle_imu_tm_v3,
+ AltosIdler.idle_sensor_mega),
+ new AltosIdler("TeleMega-v4",
+ AltosIdler.idle_gps,
+ AltosIdler.idle_adxl375,
+ AltosIdler.idle_ms5607,
+ AltosIdler.idle_imu_tm_v4,
AltosIdler.idle_sensor_mega),
new AltosIdler("EasyMega-v1",
AltosIdler.idle_mma655x,
AltosIdler.idle_ms5607,
- AltosIdler.idle_imu, AltosIdler.idle_mag,
+ AltosIdler.idle_imu_em_v1, AltosIdler.idle_mag,
AltosIdler.idle_sensor_mega),
new AltosIdler("EasyMega-v2",
AltosIdler.idle_adxl375,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.concurrent.*;
boolean remote;
boolean close_on_exit;
- double frequency;
+ double frequency = AltosLib.MISSING;
String callsign;
AltosState state;
if (state == null)
state = new AltosState(new AltosCalData(link.config_data()));
fetch.provide_data(state);
+ if (frequency != AltosLib.MISSING)
+ state.set_frequency(frequency);
if (!link.has_error && !link.reply_abort)
worked = true;
} finally {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosIdleMonitorListener {
public void update(AltosState state, AltosListenerState listener_state);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosLatLon {
public double lat;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosLatitude extends AltosLocation {
public String pos() { return "N"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.*;
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.io.*;
public static final int AO_LOG_FORMAT_EASYMEGA_2 = 16;
public static final int AO_LOG_FORMAT_TELESTATIC = 17;
public static final int AO_LOG_FORMAT_MICROPEAK2 = 18;
+ public static final int AO_LOG_FORMAT_TELEMEGA_4 = 19;
public static final int AO_LOG_FORMAT_NONE = 127;
public static boolean isspace(int c) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosLine {
public String line;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.concurrent.*;
int cal) {
if (debug)
System.out.printf("set_radio_frequency %7.3f (freq %b) (set %b) %d\n", frequency, has_frequency, has_setting, cal);
- if (frequency == 0)
+ if (frequency == 0 || frequency == AltosLib.MISSING)
return;
if (has_frequency)
set_radio_freq((int) Math.floor (frequency * 1000 + 0.5));
public String name;
public void start_remote() throws TimeoutException, InterruptedException {
- if (frequency == 0.0)
+ if (frequency == 0.0 || frequency == AltosLib.MISSING)
frequency = AltosPreferences.frequency(serial);
if (debug)
System.out.printf("start remote %7.3f\n", frequency);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public abstract class AltosLocation extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosLongitude extends AltosLocation {
public String pos() { return "E"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapCacheListener {
public void map_cache_changed(int map_cache);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapLoaderListener {
public abstract void loader_start(int max);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosMapRectangle {
AltosLatLon ul, lr;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.net.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapStoreListener {
abstract void notify_store(AltosMapStore store, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapTileListener {
abstract public void notify_tile(AltosMapTile tile, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapTypeListener {
public void map_type_changed(int map_type);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosMapZoomListener {
abstract public void zoom_changed(int zoom);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosNoSymbol extends Exception {
public AltosNoSymbol(String name) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosOrient extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosPointDouble {
public double x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosPointInt {
public int x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosPresTemp {
double pres = AltosLib.MISSING;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosPressure extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.text.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosPyroName extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosQuaternion {
double r; /* real bit */
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosRectangle {
public int x, y, width, height;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
boolean done = false;
public void set_time(double time) {
- if (last_time != AltosLib.MISSING) {
- semaphore.release();
- double delay = Math.min(time - last_time,10);
- if (delay > 0) {
- try {
- Thread.sleep((int) (delay * 1000));
- } catch (InterruptedException ie) {
+ if (time > -2) {
+ if (last_time != AltosLib.MISSING) {
+ semaphore.release();
+ double delay = Math.min(time - last_time,10);
+ if (delay > 0) {
+ try {
+ Thread.sleep((int) (delay * 1000));
+ } catch (InterruptedException ie) {
+ }
}
}
}
public void set_apogee_voltage(double volts) { state.set_apogee_voltage(volts); }
public void set_main_voltage(double volts) { state.set_main_voltage(volts); }
- public void set_gps(AltosGPS gps) { super.set_gps(gps); state.set_gps(gps); }
+ public void set_gps(AltosGPS gps, boolean set_location, boolean set_sats) {
+ super.set_gps(gps, set_location, set_sats);
+ state.set_gps(gps, set_location, set_sats);
+ }
public void set_orient(double orient) { state.set_orient(orient); }
public void set_gyro(double roll, double pitch, double yaw) { state.set_gyro(roll, pitch, yaw); }
File file;
AltosReplay replay;
Thread t;
- int reads;
public AltosCalData cal_data() {
return replay.state.cal_data();
}
public AltosState read() {
- switch (reads) {
- case 0:
- /* Tell the display that we're in pad mode */
- replay.state.set_state(AltosLib.ao_flight_pad);
- break;
- case 1:
- t = new Thread(replay);
- t.start();
- /* fall through */
- default:
- /* Wait for something to change */
- try {
- replay.semaphore.acquire();
- } catch (InterruptedException ie) {
- }
- break;
+ /* Wait for something to change */
+ try {
+ replay.semaphore.acquire();
+ } catch (InterruptedException ie) {
}
- reads++;
/* When done, let the display know */
if (replay.done)
public File backing_file() { return file; }
public AltosReplayReader(AltosRecordSet record_set, File in_file) {
- reads = 0;
file = in_file;
name = file.getName();
replay = new AltosReplay(record_set);
+ t = new Thread(replay);
+ t.start();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosRotation extends AltosQuaternion {
private AltosQuaternion rotation;
*
* rot = ao_rotation * vertical * ao_rotation°
* rot = ao_rotation * (0,0,0,1) * ao_rotation°
- * = ((a.z, a.y, -a.x, a.r) * (a.r, -a.x, -a.y, -a.z)) .z
+ * = ((-a.z, a.y, -a.x, a.r) * (a.r, -a.x, -a.y, -a.z)) .z
*
* = (-a.z * -a.z) + (a.y * -a.y) - (-a.x * -a.x) + (a.r * a.r)
* = a.z² - a.y² - a.x² + a.r²
return tilt;
}
+ /* Compute azimuth angle from a reference line pointing out the side
+ * of the airframe
+ *
+ * rot = ao_rotation * x_axis * ao_rotation°
+ * rot = ao_rotation * (0,1,0,0) * ao_rotation°
+ * = (-a.x, a.r, a.z, -a.y) * (a.r, -a.x, -a.y, -a.z) . x
+ * = (-a.x * -a.x) + (a.r * a.r) + (a.z * -a.z) - (-a.y * -a.y)
+ * = a.x² + a.r² - a.z² - a.y²
+ *
+ * = (-a.x, a.r, a.z, -a.y) * (a.r, -a.x, -a.y, -a.z) . y
+ * = (-a.x * -a.y) - (a.r * -a.z) + (a.z * a.r) + (-a.y * -a.x)
+ * = a.x * a.y + a.r * a.z + a.z * a.r + a.y * a.x
+ *
+ * The X value will be the cosine of the rotation. The Y value will be the
+ * sine of the rotation; use the sign of that to figure out which direction from
+ * zero we've headed
+ */
+
+ public double azimuth() {
+ double rotx = rotation.x * rotation.x + rotation.r * rotation.r - rotation.z * rotation.z - rotation.y * rotation.y;
+ double roty = rotation.x * rotation.y + rotation.r * rotation.z + rotation.z * rotation.r + rotation.y * rotation.x;
+
+ double az = Math.acos(rotx) * 180.0 / Math.PI;
+ if (roty < 0)
+ return -az;
+ return az;
+ }
+
/* Given euler rotations in three axes, perform a combined rotation using
* quaternions
*/
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosRotationRate extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosSpeed extends AltosUnits {
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosState extends AltosDataListener {
}
public double height() {
- double k = kalman_height.value();
- if (k != AltosLib.MISSING)
- return k;
-
double b = baro_height();
if (b != AltosLib.MISSING)
return b;
+ double k = kalman_height.value();
+ if (k != AltosLib.MISSING)
+ return k;
+
return gps_height();
}
public double max_height() {
- double k = kalman_height.max();
- if (k != AltosLib.MISSING)
- return k;
-
double a = altitude.max();
double g = ground_altitude();
if (a != AltosLib.MISSING && g != AltosLib.MISSING)
return a - g;
+
+ double k = kalman_height.max();
+ if (k != AltosLib.MISSING)
+ return k;
+
return max_gps_height();
}
gps.climb_rate * gps.climb_rate), time);
if (gps.course != AltosLib.MISSING)
gps_course.set(gps.course, time);
+ } else if (state() == AltosLib.ao_flight_pad || state() == AltosLib.ao_flight_stateless) {
+ set_npad(0);
}
if (gps.lat != 0 && gps.lon != 0 &&
pad_lat != AltosLib.MISSING &&
}
}
- public String state_name() {
- return AltosLib.state_name(state());
- }
-
public void set_state(int state) {
super.set_state(state);
ascent = (AltosLib.ao_flight_boost <= state() &&
received_time = ms;
}
- public void set_gps(AltosGPS gps) {
- super.set_gps(gps);
+ public void set_gps(AltosGPS gps, boolean set_location, boolean set_sats) {
+ super.set_gps(gps, set_location, set_sats);
if (gps != null) {
this.gps = gps;
update_gps();
void update_pad_rotation() {
if (cal_data().pad_orientation != AltosLib.MISSING && accel_ground_along != AltosLib.MISSING) {
- rotation = new AltosRotation(AltosIMU.convert_accel(accel_ground_across - cal_data().accel_zero_across),
- AltosIMU.convert_accel(accel_ground_through - cal_data().accel_zero_through),
- AltosIMU.convert_accel(accel_ground_along - cal_data().accel_zero_along),
+ rotation = new AltosRotation(accel_ground_across,
+ accel_ground_through,
+ accel_ground_along,
cal_data().pad_orientation);
orient.set_computed(rotation.tilt(), time);
}
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosStateName extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
final static int packet_type_location = 0x05;
final static int packet_type_satellite = 0x06;
final static int packet_type_companion = 0x07;
- final static int packet_type_mega_sensor = 0x08;
+ final static int packet_type_mega_sensor_mpu = 0x08;
final static int packet_type_mega_data = 0x09;
final static int packet_type_metrum_sensor = 0x0a;
final static int packet_type_metrum_data = 0x0b;
final static int packet_type_mini2 = 0x10;
final static int packet_type_mini3 = 0x11;
+ final static int packet_type_mega_sensor_bmx160 = 0x12;
static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException {
AltosTelemetry telem = null;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryCompanion extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
AltosTelemetryIterable telems;
AltosCalData cal_data;
+ int first_state;
public void write_comments(PrintStream out) {
}
cal_data = new AltosCalData();
AltosTelemetryNullListener l = new AltosTelemetryNullListener(cal_data);
+ first_state = AltosLib.ao_flight_startup;
for (AltosTelemetry telem : telems) {
telem.provide_data(l);
+ if (cal_data.state == AltosLib.ao_flight_pad)
+ first_state = cal_data.state;
if (l.cal_data_complete())
break;
}
}
public void capture_series(AltosDataListener listener) {
- AltosCalData cal_data = cal_data();
-
+ cal_data();
cal_data.reset();
+ cal_data.state = first_state;
for (AltosTelemetry telem : telems) {
- int tick = telem.tick();
- cal_data.set_tick(tick);
-
- /* Try to pick up at least one pre-boost value */
- if (cal_data.time() >= -2)
- telem.provide_data(listener);
+ telem.provide_data(listener);
if (listener.state() == AltosLib.ao_flight_landed)
break;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(apogee));
listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(main));
if (gps != null)
- listener.set_gps(gps);
+ listener.set_gps(gps, true, true);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryLocation extends AltosTelemetryStandard {
gps.course = course() * 2;
gps.climb_rate = climb_rate() * 1.0e-2;
}
- listener.set_gps(gps);
+ listener.set_gps(gps, true, false);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.util.HashMap;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMegaData extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
int orient() { return int8(5); }
int mag_z() { return int16(28); }
int mag_y() { return int16(30); }
- public AltosTelemetryMegaSensor(int[] bytes) throws AltosCRCException {
+ int imu_type;
+
+ private int accel_across(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return accel_x();
+ case AltosIMU.imu_type_easymega_v2:
+ return -accel_y();
+ case AltosIMU.imu_type_telemega_v4:
+ return -accel_y();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int accel_along(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return accel_y();
+ case AltosIMU.imu_type_easymega_v2:
+ case AltosIMU.imu_type_telemega_v4:
+ return accel_x();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int accel_through(int imu_type) {
+ return accel_z();
+ }
+
+ private int gyro_roll(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return gyro_y();
+ case AltosIMU.imu_type_easymega_v2:
+ case AltosIMU.imu_type_telemega_v4:
+ return gyro_x();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int gyro_pitch(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return gyro_x();
+ case AltosIMU.imu_type_easymega_v2:
+ return -gyro_y();
+ case AltosIMU.imu_type_telemega_v4:
+ return gyro_y();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int gyro_yaw(int imu_type) {
+ return gyro_z();
+ }
+
+ public static int mag_across_axis(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return AltosIMU.imu_axis_x;
+ case AltosIMU.imu_type_telemega_v4:
+ case AltosIMU.imu_type_easymega_v2:
+ return AltosIMU.imu_axis_y;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int mag_across(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return mag_x();
+ case AltosIMU.imu_type_telemega_v4:
+ case AltosIMU.imu_type_easymega_v2:
+ return -mag_y();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ public static int mag_along_axis(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return AltosIMU.imu_axis_y;
+ case AltosIMU.imu_type_easymega_v2:
+ case AltosIMU.imu_type_telemega_v4:
+ return AltosIMU.imu_axis_x;
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ private int mag_along(int imu_type) {
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ case AltosIMU.imu_type_easymega_v1:
+ return mag_y();
+ case AltosIMU.imu_type_easymega_v2:
+ case AltosIMU.imu_type_telemega_v4:
+ return mag_x();
+ default:
+ return AltosLib.MISSING;
+ }
+ }
+
+ public static int mag_through_axis(int imu_type) {
+ return AltosIMU.imu_axis_z;
+ }
+
+ private int mag_through(int imu_type) {
+ return mag_z();
+ }
+
+ public AltosTelemetryMegaSensor(int[] bytes, int imu_type) throws AltosCRCException {
super(bytes);
+ switch (imu_type) {
+ case AltosIMU.imu_type_telemega_v1_v2:
+ case AltosIMU.imu_type_telemega_v3:
+ if (serial() < 3000)
+ imu_type = AltosIMU.imu_type_telemega_v1_v2;
+ else
+ imu_type = AltosIMU.imu_type_telemega_v3;
+ break;
+ default:
+ break;
+ }
+ this.imu_type = imu_type;
}
public void provide_data(AltosDataListener listener) {
listener.set_temperature(temp() / 100.0);
listener.set_orient(orient());
+ cal_data.set_imu_type(imu_type);
/* XXX we have no calibration data for these values */
if (cal_data.gyro_zero_roll == AltosLib.MISSING)
cal_data.set_gyro_zero(0, 0, 0);
- int accel_along = accel_y();
- int accel_across = accel_x();
- int accel_through = accel_z();
- int gyro_roll = gyro_y();
- int gyro_pitch = gyro_x();
- int gyro_yaw = gyro_z();
+ int accel_along = accel_along(imu_type);
+ int accel_across = accel_across(imu_type);
+ int accel_through = accel_through(imu_type);
+
+ int gyro_roll = gyro_roll(imu_type);
+ int gyro_pitch = gyro_pitch(imu_type);
+ int gyro_yaw = gyro_yaw(imu_type);
- int mag_along = mag_y();
- int mag_across = mag_x();
- int mag_through = mag_z();
+ int mag_along = mag_along(imu_type);
+ int mag_across = mag_across(imu_type);
+ int mag_through = mag_through(imu_type);
listener.set_accel(cal_data.accel_along(accel_along),
cal_data.accel_across(accel_across),
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMini2 extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryMini3 extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetryRaw extends AltosTelemetryStandard {
public AltosTelemetryRaw(int[] bytes) throws AltosCRCException {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetrySatellite extends AltosTelemetryStandard {
int channels() { return uint8(5); }
AltosGPS gps = listener.make_temp_gps(true);
gps.cc_gps_sat = sats();
- listener.set_gps(gps);
+ listener.set_gps(gps, false, true);
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTelemetrySensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public abstract class AltosTelemetryStandard extends AltosTelemetry {
public int int8(int off) {
case packet_type_companion:
telem = new AltosTelemetryCompanion(bytes);
break;
- case packet_type_mega_sensor:
- telem = new AltosTelemetryMegaSensor(bytes);
+ case packet_type_mega_sensor_mpu:
+ telem = new AltosTelemetryMegaSensor(bytes, AltosIMU.imu_type_telemega_v3);
+ break;
+ case packet_type_mega_sensor_bmx160:
+ telem = new AltosTelemetryMegaSensor(bytes, AltosIMU.imu_type_telemega_v4);
break;
case packet_type_mega_data:
telem = new AltosTelemetryMegaData(bytes);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTemperature extends AltosUnits {
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTime extends AltosUnits {
public double value(double v, boolean imperial_units) { return v; }
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.util.*;
public AltosUnits units;
ArrayList<AltosTimeValue> values;
boolean data_changed;
+ double min_time = -2;
public int compareTo(AltosTimeSeries other) {
return label.compareTo(other.label);
}
public void add(AltosTimeValue tv) {
- data_changed = true;
- values.add(tv);
+ if (tv.time >= min_time) {
+ data_changed = true;
+ values.add(tv);
+ }
}
public void erase_values() {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosTimeValue {
public double time;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.io.*;
import java.lang.*;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosUnitInfoListener {
public abstract void notify_unit_info(AltosUnitInfo unit_info);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosUnitsListener {
public void units_changed(boolean imperial_units);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosUnknownProduct extends Exception {
public String product;
* General Public License for more details.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosUsbId {
public int vid;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosVersion {
public final static String version = "@VERSION@";
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public class AltosVoltage extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
public interface AltosWriter {
AltosGPS.java \
AltosGPSTimeValue.java \
AltosGPSSat.java \
+ AltosGauss.java \
AltosGreatCircle.java \
AltosHexfile.java \
AltosHexsym.java \
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class Altos extends AltosUILib {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosAscent extends AltosUIFlightTab {
JLabel cur, max;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosCompanionInfo extends JTable implements AltosFlightDisplay {
private AltosFlightInfoTableModel model;
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigFC implements ActionListener {
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigFCUI
extends AltosUIDialog
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigPyroUI
extends AltosUIDialog
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigTD implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigTDUI
extends AltosUIDialog
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosConfigureUI
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosDescent extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
import java.text.*;
import java.util.prefs.*;
import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosFlightStatusTableModel extends AbstractTableModel {
private String[] columnNames = {
package altosui;
import java.awt.event.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosFlightStatusUpdate implements ActionListener {
import javax.swing.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
AltosVoice voice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import java.io.*;
import java.util.concurrent.*;
import java.util.Arrays;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener {
AltosDevice device;
thread = new AltosIdleMonitor(this, link, (boolean) remote);
+ thread.set_frequency(AltosUIPreferences.frequency(serial));
+
status_update = new AltosFlightStatusUpdate(flightStatus);
new javax.swing.Timer(100, status_update).start();
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosIgniteUI
extends AltosUIDialog
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosIgnitor extends AltosUIFlightTab {
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosLanded extends AltosUIFlightTab implements ActionListener {
import java.io.*;
import java.util.concurrent.*;
import java.awt.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosLaunch {
AltosDevice device;
import java.io.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
class FireButton extends JButton {
protected void processMouseEvent(MouseEvent e) {
package altosui;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosPad extends AltosUIFlightTab {
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class AltosUI extends AltosUIFrame implements AltosEepromGrapher {
public AltosVoice voice = new AltosVoice();
FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx
FIRMWARE_TMEGA_2_0=$(top_srcdir)/src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx
FIRMWARE_TMEGA_3_0=$(top_srcdir)/src/telemega-v3.0/telemega-v3.0-$(VERSION).ihx
-FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0)
+FIRMWARE_TMEGA_4_0=$(top_srcdir)/src/telemega-v4.0/telemega-v4.0-$(VERSION).ihx
+FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0) $(FIRMWARE_TMEGA_3_0) $(FIRMWARE_TMEGA_4_0)
FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx
FIRMWARE_EMINI_2_0=$(top_srcdir)/src/easymini-v2.0/easymini-v2.0-$(VERSION).ihx
File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx"
File "../src/telemega-v2.0/telemega-v2.0-${VERSION}.ihx"
File "../src/telemega-v3.0/telemega-v3.0-${VERSION}.ihx"
+ File "../src/telemega-v4.0/telemega-v4.0-${VERSION}.ihx"
File "../src/easymini-v1.0/easymini-v1.0-${VERSION}.ihx"
File "../src/easymini-v2.0/easymini-v2.0-${VERSION}.ihx"
File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx"
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosBTDevice extends altos_bt_device implements AltosDevice {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
AltosBTDevice current;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosBTKnown implements Iterable<AltosBTDevice> {
LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.basic.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {
LinkedBlockingQueue<AltosBTDevice> found_devices;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosCSVUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class AltosEditFreqUI extends AltosUIDialog implements ActionListener {
Frame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosDataChooser extends JFileChooser {
JFrame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import libaltosJNI.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosDisplayThread extends Thread {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosEepromDelete implements Runnable {
AltosEepromList flights;
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public interface AltosEepromGrapher {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosEepromManage implements ActionListener {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class result_holder {
static int result;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class AltosEepromItem implements ActionListener {
AltosEepromLog log;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosFlashUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.table.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosFlightStatsTable extends JComponent implements AltosFontListener {
GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
static final private AltosUILineStyle accel_color = new AltosUILineStyle();
static final private AltosUILineStyle vert_accel_color = new AltosUILineStyle();
static final private AltosUILineStyle orient_color = new AltosUILineStyle();
+ static final private AltosUILineStyle azimuth_color = new AltosUILineStyle();
+ static final private AltosUILineStyle compass_color = new AltosUILineStyle();
static final private AltosUILineStyle gps_height_color = new AltosUILineStyle();
static final private AltosUILineStyle altitude_color = new AltosUILineStyle();
static final private AltosUILineStyle mag_along_color = new AltosUILineStyle();
static final private AltosUILineStyle mag_across_color = new AltosUILineStyle();
static final private AltosUILineStyle mag_through_color = new AltosUILineStyle();
+ static final private AltosUILineStyle mag_total_color = new AltosUILineStyle();
static AltosUnits dop_units = null;
static AltosUnits tick_units = null;
dbm_axis = newAxis("Signal Strength", null, dbm_color, 0);
gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_roll_color, 0);
- orient_axis = newAxis("Tilt Angle", AltosConvert.orient, orient_color, 0);
+ orient_axis = newAxis("Angle", AltosConvert.orient, orient_color, 0);
mag_axis = newAxis("Magnetic Field", AltosConvert.magnetic_field, mag_along_color, 0);
course_axis = newAxis("Course", AltosConvert.orient, gps_course_color, 0);
dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0);
false,
mag_axis);
+ flight_series.register_axis(AltosUIFlightSeries.mag_total_name,
+ mag_total_color,
+ false,
+ mag_axis);
+
flight_series.register_axis(AltosUIFlightSeries.orient_name,
orient_color,
false,
orient_axis);
+ flight_series.register_axis(AltosUIFlightSeries.azimuth_name,
+ azimuth_color,
+ false,
+ orient_axis);
+
+ flight_series.register_axis(AltosUIFlightSeries.compass_name,
+ compass_color,
+ false,
+ orient_axis);
+
flight_series.register_axis(AltosUIFlightSeries.thrust_name,
accel_color,
true,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
private AltosFlightInfoTableModel model;
- static final int info_columns = 3;
- static final int info_rows = 17;
+ static final int info_columns = 4;
+ static final int info_rows = 18;
private AltosState last_state;
private AltosListenerState last_listener_state;
if (state.gps.lon != AltosLib.MISSING)
info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W');
if (state.gps.alt != AltosLib.MISSING)
- info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt);
+ info_add_row(1, "GPS altitude", "%8.1f m", state.gps.alt);
if (state.gps_height != AltosLib.MISSING)
- info_add_row(1, "GPS height", "%8.1f", state.gps_height);
+ info_add_row(1, "GPS height", "%8.1f m", state.gps_height);
if (state.gps.ground_speed != AltosLib.MISSING && state.gps.course != AltosLib.MISSING)
info_add_row(1, "GPS ground speed", "%6.1f m/s %3d°",
}
}
}
+
+ if (state != null && state.accel_along() != AltosLib.MISSING) {
+ info_add_row(3, "Accel along", "%8.1f m/s²", state.accel_along());
+ info_add_row(3, "Accel across", "%8.1f m/s²", state.accel_across());
+ info_add_row(3, "Accel through", "%8.1f m/s²", state.accel_through());
+ info_add_row(3, "Gyro roll", "%8.1f °/s", state.gyro_roll());
+ info_add_row(3, "Gyro pitch", "%8.1f °/s", state.gyro_pitch());
+ info_add_row(3, "Gyro yaw", "%8.1f °/s", state.gyro_yaw());
+ if (state.mag_along() != AltosLib.MISSING) {
+ /* Report mag in nanoteslas (1 G = 100000 nT (or γ)) */
+ info_add_row(3, "Mag along", "%8.1f µT", state.mag_along() * 100.0);
+ info_add_row(3, "Mag across", "%8.1f µT", state.mag_across() * 100.0);
+ info_add_row(3, "Mag Through", "%8.1f µT", state.mag_through() * 100.0);
+ info_add_row(3, "Mag Bearing", "%8.1f°", Math.atan2(state.mag_across(), state.mag_through()) * 180/Math.PI);
+ }
+ }
+
+ if (state != null && state.igniter_voltage != null) {
+ for (int i = 0; i < state.igniter_voltage.length; i++)
+ info_add_row(3, AltosLib.igniter_name(i), "%9.2f V", state.igniter_voltage[i]);
+ }
+
info_finish();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public interface AltosPositionListener {
public void position_changed(int position);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosRomconfigUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class AltosScanResult {
String callsign;
* Deal with TeleDongle on a serial port
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import libaltosJNI.*;
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public class AltosSerialInUseException extends Exception {
public AltosDevice device;
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public interface AltosShapeListener {
void set_shapes_visible(boolean visible);
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUIAccelCal
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class DelegatingRenderer implements ListCellRenderer<Object> {
AltosUIPreferences.set_map_cache(size);
} catch (ClassCastException ce) {
- map_cache.setSelectedItem(new Integer(AltosUIPreferences.map_cache()));
+ map_cache.setSelectedItem(AltosUIPreferences.map_cache());
}
}
});
- map_cache.setSelectedItem (new Integer(AltosUIPreferences.map_cache()));
+ map_cache.setSelectedItem (AltosUIPreferences.map_cache());
pane.add(map_cache, constraints(1, 2, GridBagConstraints.BOTH));
row++;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public class AltosUIDataMissing extends Exception {
public int id;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public interface AltosUIDataPoint {
public abstract double x() throws AltosUIDataMissing;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public interface AltosUIDataSet {
public abstract String name();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
add(line_width_label, c);
line_width = new JSpinner();
- line_width.setValue(new Integer(1));
+ line_width.setValue(1);
line_width.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
int w = (Integer) line_width.getValue();
if (w < 1) {
w = 1;
- line_width.setValue(new Integer(w));
+ line_width.setValue(w);
}
- System.out.printf("line width set to %d\n", w);
set_line_width(w);
}
});
speed_filter = new JSlider(JSlider.HORIZONTAL, 0, 10000, (int) (filter_listener.speed_filter() * 1000.0));
Hashtable<Integer,JLabel> label_table = new Hashtable<Integer,JLabel>();
for (int i = 0; i <= 10000; i += 5000) {
- label_table.put(new Integer(i), new JLabel(String.format("%d", i)));
+ label_table.put(i, new JLabel(String.format("%d", i)));
}
speed_filter.setPaintTicks(true);
speed_filter.setMajorTickSpacing(1000);
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public abstract class AltosUIFlightTab extends JComponent implements AltosFlightDisplay, HierarchyListener {
public GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUIFreqList extends JComboBox<AltosFrequency> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_13;
+package org.altusmetrum.altoslib_14;
import javax.swing.*;
import javax.imageio.ImageIO;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public abstract class AltosUIIndicator implements AltosFontListener, AltosUnitsListener {
JLabel label;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUILib extends AltosLib {
* General Public License for more details.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
public interface AltosUIListener {
public void ui_changed(String look_and_feel);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.concurrent.*;
import javax.imageio.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.net.URL;
import java.net.URLConnection;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
class AltosUIMapPos extends Box implements ActionListener {
AltosUIMapPreload preload;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.*;
import java.awt.Component;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUIPreferences extends AltosPreferences {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.File;
import java.util.prefs.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import javax.swing.filechooser.FileSystemView;
public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUIRateList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUITelemetryList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosUSBDevice extends altos_device implements AltosDevice {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
*/
-package org.altusmetrum.altosuilib_13;
+package org.altusmetrum.altosuilib_14;
import java.lang.reflect.*;
import java.util.HashMap;
#!/bin/sh
-VERSION=3.0
+VERSION=4.0
PRODUCT=TeleMega
BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
echo "$PRODUCT-v$VERSION Test Program"
-echo "Copyright 2014 by Keith Packard. Released under GPL v2"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
echo
echo "Expectations:"
echo "\t$PRODUCT v$VERSION powered from USB"
--- /dev/null
+#!/bin/sh
+
+VERSION=3.0
+PRODUCT=TeleMega
+BASE=`echo $PRODUCT | tr 'A-Z' 'a-z'`
+
+echo "$PRODUCT-v$VERSION Test Program"
+echo "Copyright 2014 by Keith Packard. Released under GPL v2"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo
+
+ret=1
+ao-list | while read product serial dev; do
+ case "$product" in
+ "$PRODUCT-v$VERSION")
+
+ echo "Testing $product $serial $dev"
+
+ ./test-igniters $dev main drogue 3 0 1 2
+ echo""
+
+ echo "Testing baro sensor"
+ ../ao-tools/ao-test-baro/ao-test-baro --tty="$dev"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ FLASHSIZE=8388608
+
+ echo "Testing flash"
+ ../ao-tools/ao-test-flash/ao-test-flash --tty="$dev" "$FLASHSIZE"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "Testing GPS"
+ ../ao-tools/ao-test-gps/ao-test-gps --tty="$dev"
+
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "failed"
+ exit 1
+ esac
+ echo""
+
+ echo "$PRODUCT-v$VERSION" serial "$serial" is ready to ship
+ echo "\007"
+ ret=0
+ ;;
+ esac
+done
exit 1
fi
-VERSION=3.0
+VERSION=4.0
REPO=~/altusmetrumllc/Binaries
PRODUCT=TeleMega
echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
-echo "Copyright 2017 by Bdale Garbee. Released under GPL v3"
+echo "Copyright 2020 by Bdale Garbee. Released under GPL v3"
echo
echo "Expectations:"
echo "\t$PRODUCT v$VERSION powered from USB"
--- /dev/null
+#!/bin/sh
+
+if [ -x /usr/bin/ao-flash-stm ]; then
+ FLASH_STM=/usr/bin/ao-flash-stm
+else
+ echo "Can't find ao-flash-stm! Aborting."
+ exit 1
+fi
+
+if [ -x /usr/bin/ao-usbload ]; then
+ USBLOAD=/usr/bin/ao-usbload
+else
+ echo "Can't find ao-usbload! Aborting."
+ exit 1
+fi
+
+VERSION=3.0
+REPO=~/altusmetrumllc/Binaries
+PRODUCT=TeleMega
+
+echo "$PRODUCT v$VERSION Turn-On and Calibration Program"
+echo "Copyright 2017 by Bdale Garbee. Released under GPL v3"
+echo
+echo "Expectations:"
+echo "\t$PRODUCT v$VERSION powered from USB"
+echo "\t\twith ST-Link-V2 cabled to debug header"
+echo "\t\twith coax from UHF to frequency counter"
+echo
+
+case $# in
+ 1)
+ SERIAL="$1"
+ echo "$PRODUCT-$VERSION serial number: $SERIAL"
+ ;;
+ 0)
+ echo -n "$PRODUCT-$VERSION serial number: "
+ read SERIAL
+ ;;
+ *)
+ echo "Usage: $0 <serial-number>" 1>&2
+ exit 1;
+ ;;
+esac
+
+echo $FLASH_STM
+
+$FLASH_STM $REPO/loaders/telemega-v$VERSION*.elf
+
+sleep 3
+
+$USBLOAD --serial=$SERIAL --force $REPO/telemega-v$VERSION*.elf || exit 1
+
+sleep 5
+
+dev=`ao-list | awk '/TeleMega-v'"$VERSION"'/ { print $3; exit(0); }'`
+
+case "$dev" in
+/dev/tty*)
+ echo "TeleMega found on $dev"
+ ;;
+*)
+ echo 'No TeleMega-v'"$VERSION"' found'
+ exit 1
+ ;;
+esac
+
+echo 'E 0' > $dev
+
+SERIAL=$SERIAL ./cal-freq $dev
+
+failed=1
+while [ $failed = 1 ]; do
+ ../ao-tools/ao-cal-accel/ao-cal-accel $dev
+ failed=$?
+done
+
+echo 'E 1' > $dev
+
+./test-telemega
+
+exit $?
case AO_LOG_FORMAT_MICROPEAK2:
len = 2;
break;
+ case AO_LOG_FORMAT_TELEMEGA_4:
+ len = 32;
+ break;
+ max_adc= 4095;
+ adc_ref = 3.3;
+ batt_r1 = 5600;
+ batt_r2 = 10000;
+ sense_r1 = 100e3;
+ sense_r2 = 27e3;
+ break;
}
if (arg_len)
len = arg_len;
case AO_LOG_FORMAT_TELEMEGA:
case AO_LOG_FORMAT_TELEMEGA_3:
case AO_LOG_FORMAT_EASYMEGA_2:
+ case AO_LOG_FORMAT_TELEMEGA_4:
log_mega = (struct ao_log_mega *) &eeprom->data[pos];
switch (log_mega->type) {
case AO_LOG_FLIGHT:
}
printf ("\n");
break;
- case AO_TELEMETRY_MEGA_SENSOR:
+ case AO_TELEMETRY_MEGA_SENSOR_MPU:
+ case AO_TELEMETRY_MEGA_SENSOR_BMX160:
printf ("orient %3d accel %5d pres %9d temp %5d accel_x %5d accel_y %5d accel_z %5d gyro_x %5d gyro_y %5d gyro_z %5d mag_x %5d mag_y %5d mag_z %5d\n",
telem.mega_sensor.orient,
telem.mega_sensor.accel,
#define AO_LOG_FORMAT_EASYMEGA_2 16 /* 32 byte typed telemega records with 32 bit gyro cal, mpu9250 rotated 90° and adxl375 */
#define AO_LOG_FORMAT_TELESTATIC 17 /* 32 byte typed telestatic records */
#define AO_LOG_FORMAT_MICROPEAK2 18 /* 2-byte baro values with header */
+#define AO_LOG_FORMAT_TELEMEGA_4 19 /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
enum ao_pyro_flag {
uint16_t companion_data[AO_COMPANION_MAX_CHANNELS]; /* 8 */
/* 32 */
};
-
-#define AO_TELEMETRY_MEGA_SENSOR 0x08
+
+#define AO_TELEMETRY_MEGA_SENSOR_MPU 0x08 /* Invensense IMU */
+#define AO_TELEMETRY_MEGA_SENSOR_BMX160 0x12 /* BMX160 IMU */
struct ao_telemetry_mega_sensor {
uint16_t serial; /* 0 */
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.1)
-ANDROID_VERSION=18
+AC_INIT([altos], 1.9.2)
+ANDROID_VERSION=27
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2019-12-05
+RELEASE_DATE=2020-02-26
AC_SUBST(RELEASE_DATE)
+DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
+
+AC_SUBST(DOC_DATE)
+
VERSION_DASH=`echo $VERSION | sed 's/\./-/g'`
AC_SUBST(VERSION_DASH)
AC_SUBST(ANDROID_VERSION)
dnl ==========================================================================
dnl Java library versions
-ALTOSUILIB_VERSION=13
-ALTOSLIB_VERSION=13
+ALTOSUILIB_VERSION=14
+ALTOSLIB_VERSION=14
AC_SUBST(ALTOSLIB_VERSION)
AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package])
ANDROID_RELEASE=no
if test "x$ANDROID_SDK" != "xno"; then
HAVE_ANDROID_SDK="yes"
- if test -f "$HOME/altusmetrumllc/google-play-release.keystore" -a -f "$HOME/altusmetrumllc/google-play-passphrase"; then
- ANDROID_RELEASE=yes
- fi
+ ANDROID_RELEASE=yes
else
HAVE_ANDROID_SDK="no"
fi
altosdroid/Makefile
altosdroid/local.properties
altosdroid/app/src/main/AndroidManifest.xml
+altosdroid/app/build.gradle
ao-tools/Makefile
ao-tools/lib/Makefile
ao-tools/ao-rawload/Makefile
endif
RELNOTES_INC=\
+ release-notes-1.9.2.inc \
release-notes-1.9.1.inc \
release-notes-1.9.inc \
release-notes-1.8.7.inc \
SUFFIXES = .dot .svg .inc .txt .adoc .pdf .html
+ATTRIBUTES=--attribute="revdate=$(DOC_DATE)" --attribute="version=$(VERSION)"
+
.dot.svg:
dot -Tsvg -o$@ $*.dot
sed -e 's/^[ ]*//' -e 's/^\\//' $*.inc > $@
.adoc.html:
- asciidoctor -b html5 $*.adoc
+ asciidoctor $(ATTRIBUTES) -b html5 $*.adoc
.adoc.pdf:
- asciidoctor-pdf $*.adoc
+ asciidoctor-pdf $(ATTRIBUTES) $*.adoc
all: $(HTML) $(PDF)
Creating documentation for a new release of AltOS
-* Write release notes in release-notes-${version}.inc. Add to
- Makefile
+* Write release notes in release-notes-${version}.inc. Add to Makefile
-* Make sure that doc/altusmetrum.txt has the right copyright
- year
+* Make sure that doc/altusmetrum.txt has the right copyright year
-* Add references to that as appropriate from each of the
- documents:
+* Make sure doc/altusmetrum-theme.yml has the right copyright year
+
+* Add references to that as appropriate from each of the documents:
release-notes.inc
easymini-release-notes.inc
telegps-release-notes.inc
-* Update version in main docs
-
- altusmetrum.txt
- easymini.txt
- micropeak.txt
- telegps.txt
- telemetry.txt
-
-* Add release-notes-${version}.inc to git
+* Add release-notes-${version}.inc to Makefile.am and git
* Make sure new hardware specs are documented in specs.inc
left:
content: '{page-number}'
right:
- content: '© 2018 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
+ content: '© 2020 Bdale Garbee and Keith Packard. Creative Commons ShareAlike 3.0 License'
verso:
left:
content: $footer_recto_right_content
= The Altus Metrum System: An Owner's Manual for Altus Metrum Rocketry Electronics
Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>; Bob Finch; Anthony Towns
:title-logo-image: image:../themes/background.png[]
-:revnumber: v1.9.1
-:revdate: 5 Dec 2019
+:revnumber: v{version}
+:revdate: 1 Jan 1970
:icons:
:icontype: svg
-:copyright: Bdale Garbee and Keith Packard 2019
+:copyright: Bdale Garbee and Keith Packard 2020
:doctype: book
:numbered:
:stylesheet: am.css
EasyMega provides explicit support for an external pyro
battery. All that is required is to remove the jumper
between the lipo terminal (Bottom 3) and the pyro terminal
- (Bottom 2). Then hook the negative pyro battery terminal to ground
- (Bottom 1) and the positive pyro battery to the pyro battery
- input (Bottom 2). You can then use the existing pyro screw
+ (Bottom 2). Then hook the negative pyro battery terminal to
+ ground (Bottom 1) and the switched positive pyro battery to
+ the pyro battery input (Bottom 2). Note that you must include
+ a switch between the pyro battery and the board for safety,
+ as the on-board power switch circuit only supports the primary
+ battery! You can then use the existing pyro screw
terminals to hook up all of the pyro charges.
=== Using Only One Battery With EasyMega
ground, connect it to the negative external battery
connection, top terminal 4.
- Connecting the positive battery terminal to the pyro
+ Connecting the switched positive battery terminal to the pyro
charges must be done separate from EasyMini, by soldering
- them together or using some other connector.
+ them together or using some other connector. Note that for
+ safety, you must put a switch between the pyro battery and
+ the rest of the circuit!
The other lead from each pyro charge is then inserted into
the appropriate per-pyro channel screw terminal (top
= EasyMini Owner's Manual
Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
:title-logo-image: image:../themes/background.png[]
-:revnumber: v1.9.1
-:revdate: 5 Dec 2019
-:copyright: Bdale Garbee and Keith Packard 2019
+:revnumber: v{version}
+:revdate: 01 Jan 1970
+:copyright: Bdale Garbee and Keith Packard 2020
:doctype: book
:numbered:
:toc:
= MicroPeak Owner's Manual
Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
-:revnumber: v1.9.1
-:revdate: 5 Dec 2019
-:copyright: Bdale Garbee and Keith Packard 2019
+:revnumber: v{version}
+:revdate: 01 Jan 1970
+:copyright: Bdale Garbee and Keith Packard 2020
:stylesheet: am.css
:linkcss:
:toc:
--- /dev/null
+= Release Notes for Version 1.9.2
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.2
+
+ == AltOS
+
+ * Add support for TeleMega v4.0
+
+ * Fix time wrapping issue with TeleLCO and TeleFire
+
+ == AltosUI, TeleGPS, MicroPeak
+
+ * Add column in AltosUI for IMU data from TeleMega and EasyMega
+
+ == AltosDroid
+
+ * Allow sorting of trackers by call, serial, frequency or age
+
+ * Offer selection of font sizes
+
+ * Various bug fixes for older Android versions
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.2.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.1.adoc[]
|40mW
|3.7V
+ |TeleMega v4.0
+ |MS5607 30km (100k')
+ |ADXL375 200g
+ |uBlox Max-8Q
+ |BMX160
+ |8MB
+ |40mW
+ |3.7V
+
endif::telemega[]
ifdef::easymega[]
|EasyMega v1.0
= TeleGPS Owner's Manual
Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
:title-logo-image: image:../themes/background.png[]
-:revnumber: v1.9.1
-:revdate: 5 Dec 2019
-:copyright: Bdale Garbee and Keith Packard 2019
+:revnumber: v{version}
+:revdate: 01 Jan 1970
+:copyright: Bdale Garbee and Keith Packard 2020
:stylesheet: am.css
:linkcss:
:toc:
= TeleLaunch: The Altus Metrum Wireless Launch Control System
Bdale Garbee <bdale@gag.com>
:title-logo-image: image:../themes/background.png[]
-:revnumber: v0.1
-:revdate: 16 Feb 2019
+:revnumber: v{version}
+:revdate: 01 Jan 1970
:icons:
:icontype: svg
:revremark: initial draft
TeleMega provides explicit support for an external pyro
battery. All that is required is to remove the jumper
between the lipo terminal (Bottom 3) and the pyro terminal
- (Bottom 2). Then hook the negative pyro battery terminal to ground
- (Bottom 1) and the positive pyro battery to the pyro battery
- input (Bottom 2). You can then use the existing pyro screw
+ (Bottom 2). Then hook the negative pyro battery terminal to
+ ground (Bottom 1) and the switched positive pyro battery to
+ the pyro battery input (Bottom 2). Note that you must include
+ a switch between the pyro battery and the board for safety,
+ as the on-board power switch circuit only supports the primary
+ battery! You can then use the existing pyro screw
terminals to hook up all of the pyro charges.
=== Using Only One Battery With TeleMega
stranded, into the GND hole just above the screw terminal
strip and solder it in place.
- Connecting the positive battery terminal to the pyro
+ Connecting the switched positive battery terminal to the pyro
charges must be done separate from TeleMetrum, by soldering
- them together or using some other connector.
-
+ them together or using some other connector. Note that you
+ must include a switch in the positive lead from the pyro
+ battery for safety!
The other lead from each pyro charge is then inserted into
- the appropriate per-pyro channel screw terminal (terminal 4 for the
- Main charge, terminal 6 for the Apogee charge).
+ the appropriate per-pyro channel screw terminal (terminal 4
+ for the Main charge, terminal 6 for the Apogee charge).
=== Using an Active Switch with TeleMetrum
= AltOS Telemetry
Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
-:revnumber: v1.9.1
-:revdate: 5 Dec 2019
-:copyright: Bdale Garbee and Keith Packard 2019
+:revnumber: v{version}
+:revdate: 01 Jan 1970
+:copyright: Bdale Garbee and Keith Packard 2020
:stylesheet: am.css
:linkcss:
:doctype: article
As described above, using an external pyro battery involves
connecting the negative battery terminal to the flight
- computer ground, connecting the positive battery terminal to
- one of the igniter leads and connecting the other igniter
- lead to the per-channel pyro circuit connection. Because
- there is no solid ground connection to use on TeleMini, this
- is not recommended.
+ computer ground, connecting the switched positive battery
+ terminal to one of the igniter leads and connecting the other
+ igniter lead to the per-channel pyro circuit connection.
+ Because there is no solid ground connection to use on
+ TeleMini, this is not recommended.
The only available ground connection on TeleMini v3 are
the two mounting holes next to the telemetry
Connecting the positive battery terminal to the pyro
charges must be done separate from TeleMini v3, by soldering
- them together or using some other connector.
+ them together or using some other connector. Note that you
+ must include a switch in the pyro battery positive lead for
+ safety!
The other lead from each pyro charge is then inserted into
the appropriate per-pyro channel screw terminal (terminal 3 for the
To use a separate pyro battery, connect the negative pyro
battery terminal to the flight computer ground terminal,
- the positive battery terminal to the igniter and the other
+ the the switched positive battery terminal to the igniter
+ and the other
igniter lead to the negative pyro terminal on the flight
computer. When the pyro channel fires, it will complete the
circuit between the negative pyro terminal and the ground
to hook this up for each flight computer will be found
in the section below for that flight computer.
+ Note that you must include a switch in the positive lead of
+ the pyro battery for safety, as the on-board power switch
+ circuit on our product only controls current flow from the
+ the primary or system battery!
+
+
=== Using a Different Kind of Battery
EasyMini
altos_getchar(struct altos_file *file, int timeout)
{
int ret;
+
+ file->busy = 1;
while (file->in_read == file->in_used) {
ret = altos_fill(file, timeout);
if (ret)
- return ret;
+ goto done;
}
- return file->in_data[file->in_read++];
+ ret = file->in_data[file->in_read++];
+done:
+ file->busy = 0;
+ return ret;
}
PUBLIC int
return BT_PORT_DEFAULT;
}
+#include <time.h>
+
PUBLIC void
altos_free(struct altos_file *file)
{
+ int i;
altos_close(file);
+ for (i = 0; i < 10 && file->busy; i++) {
+ struct timespec delay = { .tv_sec = 1, .tv_nsec = 0 };
+ nanosleep(&delay, NULL);
+ }
free(file);
}
unsigned char in_data[USB_BUF_SIZE];
int in_used;
int in_read;
+ int busy;
};
#ifdef LINUX
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosMapd implements AltosLaunchSiteListener {
import java.util.concurrent.*;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosMapdClient extends Thread implements AltosMapStoreListener {
private Socket socket;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosMapdPreferences extends AltosPreferencesBackend {
import java.util.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class AltosMap {
import java.lang.*;
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroData {
public int ground_pressure;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroDeviceDialog extends AltosDeviceDialog {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener {
MicroPeak owner;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroExport extends JFileChooser {
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroFile {
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroFileChooser extends JFileChooser {
JFrame frame;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroFrame extends AltosUIFrame {
static String[] micro_icon_names = {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroPeak extends MicroFrame implements ActionListener, ItemListener, AltosFilterListener {
import java.awt.*;
import java.io.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroRaw extends JTextArea implements AltosFontListener {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroSave extends JFileChooser {
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroSerial extends InputStream {
SWIGTYPE_p_altos_file file;
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public interface MicroSerialLog {
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class MicroUSB extends altos_device implements AltosDevice {
telemega-v1.0 telemega-v1.0/flash-loader \
telemega-v2.0 telemega-v2.0/flash-loader \
telemega-v3.0 telemega-v3.0/flash-loader \
+ telemega-v4.0 telemega-v4.0/flash-loader \
telemetrum-v2.0 telemetrum-v2.0/flash-loader \
telemetrum-v3.0 telemetrum-v3.0/flash-loader \
telegps-v0.3 telegps-v0.3/flash-loader \
static uint8_t ao_bmx160_configured;
+static struct ao_bmm150_trim ao_bmm150_trim;
+
#define ao_bmx160_spi_get() ao_spi_get(AO_BMX160_SPI_BUS, AO_SPI_SPEED_8MHz)
#define ao_bmx160_spi_put() ao_spi_put(AO_BMX160_SPI_BUS)
static void
_ao_bmx160_cmd(uint8_t cmd)
{
+ int i;
_ao_bmx160_reg_write(BMX160_CMD, cmd);
- ao_delay(AO_MS_TO_TICKS(100));
-}
-
-static void
-_ao_bmx160_mag_setup(void)
-{
- _ao_bmx160_reg_write(BMX160_MAG_IF_0, 0x80);
+ for (i = 0; i < 50; i++) {
+ uint8_t cmd_read;
+ cmd_read = _ao_bmx160_reg_read(BMX160_CMD);
+ if (cmd_read != cmd)
+ break;
+ }
}
static void
_ao_bmm150_wait_manual();
}
-#if BMX160_TEST
static uint8_t
_ao_bmm150_reg_read(uint8_t addr)
{
_ao_bmx160_reg_write(BMX160_MAG_IF_1, addr);
_ao_bmm150_wait_manual();
- return _ao_bmx160_reg_read(BMX160_DATA_0);
+ uint8_t ret = _ao_bmx160_reg_read(BMX160_DATA_0);
+ return ret;
+}
+
+static uint16_t
+_ao_bmm150_reg_read2(uint8_t lo_addr, uint8_t hi_addr)
+{
+ uint8_t lo = _ao_bmm150_reg_read(lo_addr);
+ uint8_t hi = _ao_bmm150_reg_read(hi_addr);
+
+ return ((uint16_t) hi << 8) | lo;
+}
+
+/*
+ * The compensate functions are taken from the BMM150 sample
+ * driver which has the following copyright:
+ *
+ * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @file bmm150.c
+ * @date 10/01/2020
+ * @version 1.0.3
+ *
+ */
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer X axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_x(int16_t mag_data_x, uint16_t data_rhall)
+{
+ int16_t retval;
+ uint16_t process_comp_x0 = 0;
+ int32_t process_comp_x1;
+ uint16_t process_comp_x2;
+ int32_t process_comp_x3;
+ int32_t process_comp_x4;
+ int32_t process_comp_x5;
+ int32_t process_comp_x6;
+ int32_t process_comp_x7;
+ int32_t process_comp_x8;
+ int32_t process_comp_x9;
+ int32_t process_comp_x10;
+
+ /* Overflow condition check */
+ if (mag_data_x != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL)
+ {
+ if (data_rhall != 0)
+ {
+ /* Availability of valid data*/
+ process_comp_x0 = data_rhall;
+ //printf("using data_rhall %d\n", data_rhall);
+ }
+ else if (ao_bmm150_trim.dig_xyz1 != 0)
+ {
+ process_comp_x0 = ao_bmm150_trim.dig_xyz1;
+ //printf("using trim value %d\n", process_comp_x0);
+ }
+ else
+ {
+ process_comp_x0 = 0;
+ //printf("no valid rhall\n");
+ }
+ if (process_comp_x0 != 0)
+ {
+ /* Processing compensation equations*/
+ process_comp_x1 = ((int32_t)ao_bmm150_trim.dig_xyz1) * 16384;
+ //printf("comp_x1 %d\n", process_comp_x1);
+ process_comp_x2 = ((uint16_t)(process_comp_x1 / process_comp_x0)) - ((uint16_t)0x4000);
+ //printf("comp_x2 %d\n", process_comp_x2);
+ retval = ((int16_t)process_comp_x2);
+ process_comp_x3 = (((int32_t)retval) * ((int32_t)retval));
+ //printf("comp_x3 %d\n", process_comp_x3);
+ process_comp_x4 = (((int32_t)ao_bmm150_trim.dig_xy2) * (process_comp_x3 / 128));
+ //printf("comp_x4 %d\n", process_comp_x4);
+ process_comp_x5 = (int32_t)(((int16_t)ao_bmm150_trim.dig_xy1) * 128);
+ //printf("comp_x5 %d\n", process_comp_x5);
+ process_comp_x6 = ((int32_t)retval) * process_comp_x5;
+ //printf("comp_x6 %d\n", process_comp_x6);
+ process_comp_x7 = (((process_comp_x4 + process_comp_x6) / 512) + ((int32_t)0x100000));
+ //printf("comp_x7 %d\n", process_comp_x7);
+ process_comp_x8 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_x2) + ((int16_t)0xA0)));
+ //printf("comp_x8 %d\n", process_comp_x8);
+ process_comp_x9 = ((process_comp_x7 * process_comp_x8) / 4096);
+ //printf("comp_x9 %d\n", process_comp_x9);
+ process_comp_x10 = ((int32_t)mag_data_x) * process_comp_x9;
+ //printf("comp_x10 %d\n", process_comp_x10);
+ retval = ((int16_t)(process_comp_x10 / 8192));
+ //printf("ret 1 %d\n", retval);
+ retval = (retval + (((int16_t)ao_bmm150_trim.dig_x1) * 8)) / 16;
+ //printf("final %d\n", retval);
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition */
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return retval;
+}
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer Y axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_y(int16_t mag_data_y, uint16_t data_rhall)
+{
+ int16_t retval;
+ uint16_t process_comp_y0 = 0;
+ int32_t process_comp_y1;
+ uint16_t process_comp_y2;
+ int32_t process_comp_y3;
+ int32_t process_comp_y4;
+ int32_t process_comp_y5;
+ int32_t process_comp_y6;
+ int32_t process_comp_y7;
+ int32_t process_comp_y8;
+ int32_t process_comp_y9;
+
+ /* Overflow condition check */
+ if (mag_data_y != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL)
+ {
+ if (data_rhall != 0)
+ {
+ /* Availability of valid data*/
+ process_comp_y0 = data_rhall;
+ }
+ else if (ao_bmm150_trim.dig_xyz1 != 0)
+ {
+ process_comp_y0 = ao_bmm150_trim.dig_xyz1;
+ }
+ else
+ {
+ process_comp_y0 = 0;
+ }
+ if (process_comp_y0 != 0)
+ {
+ /*Processing compensation equations*/
+ process_comp_y1 = (((int32_t)ao_bmm150_trim.dig_xyz1) * 16384) / process_comp_y0;
+ process_comp_y2 = ((uint16_t)process_comp_y1) - ((uint16_t)0x4000);
+ retval = ((int16_t)process_comp_y2);
+ process_comp_y3 = ((int32_t) retval) * ((int32_t)retval);
+ process_comp_y4 = ((int32_t)ao_bmm150_trim.dig_xy2) * (process_comp_y3 / 128);
+ process_comp_y5 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_xy1) * 128));
+ process_comp_y6 = ((process_comp_y4 + (((int32_t)retval) * process_comp_y5)) / 512);
+ process_comp_y7 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_y2) + ((int16_t)0xA0)));
+ process_comp_y8 = (((process_comp_y6 + ((int32_t)0x100000)) * process_comp_y7) / 4096);
+ process_comp_y9 = (((int32_t)mag_data_y) * process_comp_y8);
+ retval = (int16_t)(process_comp_y9 / 8192);
+ retval = (retval + (((int16_t)ao_bmm150_trim.dig_y1) * 8)) / 16;
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition*/
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return retval;
+}
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer Z axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_z(int16_t mag_data_z, uint16_t data_rhall)
+{
+ int32_t retval;
+ int16_t process_comp_z0;
+ int32_t process_comp_z1;
+ int32_t process_comp_z2;
+ int32_t process_comp_z3;
+ int16_t process_comp_z4;
+
+ if (mag_data_z != BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL)
+ {
+ if ((ao_bmm150_trim.dig_z2 != 0) && (ao_bmm150_trim.dig_z1 != 0) && (data_rhall != 0) &&
+ (ao_bmm150_trim.dig_xyz1 != 0))
+ {
+ /*Processing compensation equations*/
+ process_comp_z0 = ((int16_t)data_rhall) - ((int16_t) ao_bmm150_trim.dig_xyz1);
+ process_comp_z1 = (((int32_t)ao_bmm150_trim.dig_z3) * ((int32_t)(process_comp_z0))) / 4;
+ process_comp_z2 = (((int32_t)(mag_data_z - ao_bmm150_trim.dig_z4)) * 32768);
+ process_comp_z3 = ((int32_t)ao_bmm150_trim.dig_z1) * (((int16_t)data_rhall) * 2);
+ process_comp_z4 = (int16_t)((process_comp_z3 + (32768)) / 65536);
+ retval = ((process_comp_z2 - process_comp_z1) / (ao_bmm150_trim.dig_z2 + process_comp_z4));
+
+ /* saturate result to +/- 2 micro-tesla */
+ if (retval > BMM150_POSITIVE_SATURATION_Z)
+ {
+ retval = BMM150_POSITIVE_SATURATION_Z;
+ }
+ else if (retval < BMM150_NEGATIVE_SATURATION_Z)
+ {
+ retval = BMM150_NEGATIVE_SATURATION_Z;
+ }
+
+ /* Conversion of LSB to micro-tesla*/
+ retval = retval / 16;
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition*/
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return (int16_t)retval;
}
-#endif
static void
_ao_bmx160_sample(struct ao_bmx160_sample *sample)
*d++ = (t >> 8) | (t << 8);
}
#endif
+ uint16_t rhall = sample->rhall >> 2;
+ sample->mag_x = compensate_x(sample->mag_x >> 3, rhall);
+ sample->mag_y = compensate_y(sample->mag_y >> 3, rhall);
+ sample->mag_z = compensate_z(sample->mag_z >> 1, rhall);
}
#define G 981 /* in cm/s² */
static void
_ao_bmx160_setup(void)
{
+ int r;
+
if (ao_bmx160_configured)
return;
+ /* Dummy read of 0x7f register to enable SPI interface */
+ (void) _ao_bmx160_reg_read(0x7f);
+
/* Make sure the chip is responding */
_ao_bmx160_wait_alive();
- /* Reboot */
- _ao_bmx160_cmd(BMX160_CMD_SOFTRESET);
-
/* Force SPI mode */
_ao_bmx160_reg_write(BMX160_NV_CONF, 1 << BMX160_NV_CONF_SPI_EN);
+ /* Enable acc and gyr
+ */
+
+ _ao_bmx160_cmd(BMX160_CMD_ACC_SET_PMU_MODE(BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL));
+
+ for (r = 0; r < 20; r++) {
+ ao_delay(AO_MS_TO_TICKS(100));
+ if (((_ao_bmx160_reg_read(BMX160_PMU_STATUS)
+ >> BMX160_PMU_STATUS_ACC_PMU_STATUS)
+ & BMX160_PMU_STATUS_ACC_PMU_STATUS_MASK)
+ == BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL)
+ {
+ r = 0;
+ break;
+ }
+ }
+ if (r != 0)
+ AO_SENSOR_ERROR(AO_DATA_BMX160);
+
+ _ao_bmx160_cmd(BMX160_CMD_GYR_SET_PMU_MODE(BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL));
+
+ for (r = 0; r < 20; r++) {
+ ao_delay(AO_MS_TO_TICKS(100));
+ if (((_ao_bmx160_reg_read(BMX160_PMU_STATUS)
+ >> BMX160_PMU_STATUS_GYR_PMU_STATUS)
+ & BMX160_PMU_STATUS_GYR_PMU_STATUS_MASK)
+ == BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL)
+ {
+ r = 0;
+ break;
+ }
+ }
+ if (r != 0)
+ AO_SENSOR_ERROR(AO_DATA_BMX160);
+
/* Configure accelerometer:
*
* undersampling disabled
_ao_bmx160_reg_write(BMX160_ACC_RANGE,
BMX160_ACC_RANGE_16G);
+ for (r = 0x3; r <= 0x1b; r++)
+ (void) _ao_bmx160_reg_read(r);
+
/* Configure gyro:
*
* 200Hz sampling rate
*/
_ao_bmx160_cmd(BMX160_CMD_MAG_IF_SET_PMU_MODE(BMX160_PMU_STATUS_MAG_IF_PMU_STATUS_NORMAL));
+ _ao_bmx160_reg_write(BMX160_IF_CONF,
+ (BMX160_IF_CONF_IF_MODE_AUTO_MAG << BMX160_IF_CONF_IF_MODE));
+
/* Enter setup mode */
- _ao_bmx160_mag_setup();
+ _ao_bmx160_reg_write(BMX160_MAG_IF_0,
+ (1 << BMX160_MAG_IF_0_MAG_MANUAL_EN) |
+ (0 << BMX160_MAG_IF_0_MAG_OFFSET) |
+ (0 << BMX160_MAG_IF_0_MAG_RD_BURST));
/* Place in suspend mode to reboot the chip */
_ao_bmm150_reg_write(BMM150_POWER_MODE,
_ao_bmm150_reg_write(BMM150_REPXY, BMM150_REPXY_VALUE(9));
_ao_bmm150_reg_write(BMM150_REPZ, BMM150_REPZ_VALUE(15));
+ /* Read Trim values */
+ ao_bmm150_trim.dig_x1 = _ao_bmm150_reg_read(BMM150_DIG_X1);
+ ao_bmm150_trim.dig_y1 = _ao_bmm150_reg_read(BMM150_DIG_Y1);
+ ao_bmm150_trim.dig_z4 = _ao_bmm150_reg_read2(BMM150_DIG_Z4_LSB, BMM150_DIG_Z4_MSB);
+ ao_bmm150_trim.dig_x2 = _ao_bmm150_reg_read(BMM150_DIG_X2);
+ ao_bmm150_trim.dig_y2 = _ao_bmm150_reg_read(BMM150_DIG_Y2);
+ ao_bmm150_trim.dig_z2 = _ao_bmm150_reg_read2(BMM150_DIG_Z2_LSB, BMM150_DIG_Z2_MSB);
+ ao_bmm150_trim.dig_z1 = _ao_bmm150_reg_read2(BMM150_DIG_Z1_LSB, BMM150_DIG_Z1_MSB);
+ ao_bmm150_trim.dig_xyz1 = _ao_bmm150_reg_read2(BMM150_DIG_XYZ1_LSB, BMM150_DIG_XYZ1_MSB);
+ ao_bmm150_trim.dig_z3 = _ao_bmm150_reg_read2(BMM150_DIG_Z3_LSB, BMM150_DIG_Z3_MSB);
+ ao_bmm150_trim.dig_xy2 = _ao_bmm150_reg_read(BMM150_DIG_XY2);
+ ao_bmm150_trim.dig_xy1 = _ao_bmm150_reg_read(BMM150_DIG_XY1);
+
/* To get data out of the magnetometer, set the control op mode to 'forced', then read
* from the data registers
*/
- _ao_bmx160_reg_write(BMX160_MAG_IF_3, (BMM150_CONTROL_OP_MODE_FORCED << BMM150_CONTROL_OP_MODE));
+ _ao_bmx160_reg_write(BMX160_MAG_IF_3,
+ (BMM150_CONTROL_DATA_RATE_30 << BMM150_CONTROL_DATA_RATE) |
+ (BMM150_CONTROL_OP_MODE_FORCED << BMM150_CONTROL_OP_MODE));
_ao_bmx160_reg_write(BMX160_MAG_IF_2, BMM150_CONTROL);
_ao_bmx160_reg_write(BMX160_MAG_IF_1, BMM150_DATA_X_0_4);
- /* Set data rate to 200Hz */
- _ao_bmx160_reg_write(BMX160_MAG_CONF,
- (BMX160_MAG_CONF_MAG_ODR_200 << BMX160_MAG_CONF_MAG_ODR));
-
/* Put magnetometer interface back into 'normal mode'
*/
_ao_bmx160_reg_write(BMX160_MAG_IF_0,
(0 << BMX160_MAG_IF_0_MAG_MANUAL_EN) |
(0 << BMX160_MAG_IF_0_MAG_OFFSET) |
- (0 << BMX160_MAG_IF_0_MAG_RD_BURST));
+ (3 << BMX160_MAG_IF_0_MAG_RD_BURST));
- /* Enable acc and gyr
- */
+ /* Set data rate to 200Hz */
+ _ao_bmx160_reg_write(BMX160_MAG_CONF,
+ (BMX160_MAG_CONF_MAG_ODR_200 << BMX160_MAG_CONF_MAG_ODR));
- _ao_bmx160_cmd(BMX160_CMD_ACC_SET_PMU_MODE(BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL));
- _ao_bmx160_cmd(BMX160_CMD_GYR_SET_PMU_MODE(BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL));
ao_bmx160_configured = 1;
}
void
ao_bmx160_init(void)
{
- ao_add_task(&ao_bmx160_task, ao_bmx160, "bmx160");
-
ao_spi_init_cs(AO_BMX160_SPI_CS_PORT, (1 << AO_BMX160_SPI_CS_PIN));
+ ao_add_task(&ao_bmx160_task, ao_bmx160, "bmx160");
+
/* Pretend to be the bmx160 task. Grab the SPI bus right away and
* hold it for the task so that nothing else uses the SPI bus before
* we get the I2C mode disabled in the chip
ao_cur_task = &ao_bmx160_task;
ao_bmx160_spi_get();
ao_cur_task = NULL;
+
ao_cmd_register(&ao_bmx160_cmds[0]);
}
int16_t mag_x;
int16_t mag_y;
int16_t mag_z;
- int16_t rhall;
+ uint16_t rhall;
int16_t gyr_x;
int16_t gyr_y;
int16_t gyr_z;
uint8_t offset_6;
};
+struct ao_bmm150_trim {
+ int8_t dig_x1;
+ int8_t dig_y1;
+ int8_t dig_x2;
+ int8_t dig_y2;
+ uint16_t dig_z1;
+ int16_t dig_z2;
+ int16_t dig_z3;
+ int16_t dig_z4;
+ uint8_t dig_xy1;
+ int8_t dig_xy2;
+ uint16_t dig_xyz1;
+};
+
void
ao_bmx160_init(void);
#define BMX160_PMU_STATUS_GYR_PMU_STATUS_SUSPEND 0
#define BMX160_PMU_STATUS_GYR_PMU_STATUS_NORMAL 1
#define BMX160_PMU_STATUS_GYR_PMU_STATUS_FAST_START_UP 3
+#define BMX160_PMU_STATUS_GYR_PMU_STATUS_MASK 3
#define BMX160_PMU_STATUS_ACC_PMU_STATUS 4
#define BMX160_PMU_STATUS_ACC_PMU_STATUS_SUSPEND 0
#define BMX160_PMU_STATUS_ACC_PMU_STATUS_NORMAL 1
#define BMX160_PMU_STATUS_ACC_PMU_STATUS_LOW_POWER 2
+#define BMX160_PMU_STATUS_ACC_PMU_STATUS_MASK 3
#define BMX160_DATA_0 0x04
#define BMX160_MAG_X_0_7 0x04
#define BMX160_MAG_X_8_15 0x05
#define BMX160_ACC_RANGE_4G 0x5
#define BMX160_ACC_RANGE_8G 0x8
#define BMX160_ACC_RANGE_16G 0xc
-#define BMX160_ACC_RANGE_
-#define BMX160_ACC_RANGE_
#define BMX160_GYR_CONF 0x42
#define BMX160_GYR_CONF_GYR_ODR 0
#define BMX160_GYR_CONF_GYR_ODR_25 0x6
#define BMX160_FOC_CONF 0x69
#define BMX160_CONF 0x6A
#define BMX160_IF_CONF 0x6B
+#define BMX160_IF_CONF_IF_MODE 4
+#define BMX160_IF_CONF_IF_MODE_AUTO_MAG 0x02
#define BMX160_PMU_TRIGGER 0x6C
#define BMX160_SELF_TEST 0x6D
#define BMX160_NV_CONF 0x70
#define BMM150_REPZ 0x52
#define BMM150_REPZ_VALUE(n) ((n) -1)
+/* Trim Extended Registers */
+#define BMM150_DIG_X1 0x5D
+#define BMM150_DIG_Y1 0x5E
+#define BMM150_DIG_Z4_LSB 0x62
+#define BMM150_DIG_Z4_MSB 0x63
+#define BMM150_DIG_X2 0x64
+#define BMM150_DIG_Y2 0x65
+#define BMM150_DIG_Z2_LSB 0x68
+#define BMM150_DIG_Z2_MSB 0x69
+#define BMM150_DIG_Z1_LSB 0x6A
+#define BMM150_DIG_Z1_MSB 0x6B
+#define BMM150_DIG_XYZ1_LSB 0x6C
+#define BMM150_DIG_XYZ1_MSB 0x6D
+#define BMM150_DIG_Z3_LSB 0x6E
+#define BMM150_DIG_Z3_MSB 0x6F
+#define BMM150_DIG_XY2 0x70
+#define BMM150_DIG_XY1 0x71
+
+#define BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL -4096
+#define BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL -16384
+#define BMM150_OVERFLOW_OUTPUT -32768
+#define BMM150_NEGATIVE_SATURATION_Z -32767
+#define BMM150_POSITIVE_SATURATION_Z 32767
+
#define BMX160_GYRO_FULLSCALE ((float) 2000 * M_PI/180.0)
static inline float
int8_t ao_btm_stdio;
uint8_t ao_btm_connected;
-#define BT_DEBUG 1
+#define BT_DEBUG 0
#if BT_DEBUG
char ao_btm_buffer[256];
#define AO_LCO_BOX_DRAG 0x1000
/* UI values */
-static uint16_t ao_lco_fire_tick;
+static AO_TICK_TYPE ao_lco_fire_tick;
static uint8_t ao_lco_fire_down;
static uint8_t ao_lco_display_mutex;
static struct ao_task ao_lco_drag_task;
static uint8_t ao_lco_drag_active;
-static uint16_t
-ao_lco_drag_button_check(uint16_t now, uint16_t delay)
+static AO_TICK_TYPE
+ao_lco_drag_button_check(AO_TICK_TYPE now, AO_TICK_TYPE delay)
{
- uint16_t button_delay = ~0;
+ AO_TICK_TYPE button_delay = ~0;
/*
* Check to see if the button has been held down long enough
*/
if (ao_lco_fire_down) {
if (ao_lco_drag_race) {
- if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_STOP_TIME) {
+ if ((AO_TICK_SIGNED) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_STOP_TIME) {
ao_lco_drag_disable();
ao_lco_fire_down = 0;
}
else
button_delay = ao_lco_fire_tick + AO_LCO_DRAG_RACE_STOP_TIME - now;
} else {
- if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_START_TIME) {
+ if ((AO_TICK_SIGNED) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_START_TIME) {
ao_lco_drag_enable();
ao_lco_fire_down = 0;
}
static void
ao_lco_drag_monitor(void)
{
- uint16_t delay = ~0;
- uint16_t now;
+ AO_TICK_TYPE delay = ~0;
+ AO_TICK_TYPE now;
ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
for (;;) {
PRINTD("Drag monitor count %d active %d delay %d\n",
ao_lco_drag_beep_count, ao_lco_drag_active, delay);
- if (delay == (uint16_t) ~0)
+ if (delay == (AO_TICK_TYPE) ~0)
ao_sleep(&ao_lco_drag_beep_count);
else
ao_sleep_for(&ao_lco_drag_beep_count, delay);
ao_lco_drag_disable(void);
/* Handle drag beeps, return new delay */
-uint16_t
-ao_lco_drag_beep_check(uint16_t now, uint16_t delay);
+AO_TICK_TYPE
+ao_lco_drag_beep_check(AO_TICK_TYPE now, AO_TICK_TYPE delay);
/* Check if it's time to beep during drag race. Return new delay */
-uint16_t
-ao_lco_drag_warn_check(uint16_t now, uint16_t delay);
+AO_TICK_TYPE
+ao_lco_drag_warn_check(AO_TICK_TYPE now, AO_TICK_TYPE delay);
/* Request 'beeps' additional drag race beeps */
void
struct ao_pad_query ao_pad_query; /* latest query response */
static uint8_t ao_lco_channels[AO_PAD_MAX_BOXES]; /* pad channels available on each box */
-static uint16_t ao_lco_tick_offset[AO_PAD_MAX_BOXES]; /* offset from local to remote tick count */
+static uint16_t ao_lco_tick_offset[AO_PAD_MAX_BOXES]; /* 16 bit offset from local to remote tick count */
static uint8_t ao_lco_selected[AO_PAD_MAX_BOXES]; /* pads selected to fire */
#define AO_LCO_VALID_LAST 1
void
ao_lco_monitor(void)
{
- uint16_t delay;
+ AO_TICK_TYPE delay;
uint8_t box;
for (;;) {
uint8_t ao_lco_drag_beep_count;
static uint8_t ao_lco_drag_beep_on;
-static uint16_t ao_lco_drag_beep_time;
-static uint16_t ao_lco_drag_warn_time;
+static AO_TICK_TYPE ao_lco_drag_beep_time;
+static AO_TICK_TYPE ao_lco_drag_warn_time;
#define AO_LCO_DRAG_BEEP_TIME AO_MS_TO_TICKS(50)
#define AO_LCO_DRAG_WARN_TIME AO_SEC_TO_TICKS(5)
* turn it on or off as necessary and bump the remaining beep counts
*/
-uint16_t
-ao_lco_drag_beep_check(uint16_t now, uint16_t delay)
+AO_TICK_TYPE
+ao_lco_drag_beep_check(AO_TICK_TYPE now, AO_TICK_TYPE delay)
{
PRINTD("beep check count %d delta %d\n",
ao_lco_drag_beep_count,
- (int16_t) (now - ao_lco_drag_beep_time));
+ (AO_TICK_SIGNED) (now - ao_lco_drag_beep_time));
if (ao_lco_drag_beep_count) {
- if ((int16_t) (now - ao_lco_drag_beep_time) >= 0) {
+ if ((AO_TICK_SIGNED) (now - ao_lco_drag_beep_time) >= 0) {
if (ao_lco_drag_beep_on) {
ao_beep(0);
PRINTD("beep stop\n");
}
if (ao_lco_drag_beep_count) {
- uint16_t beep_delay = 0;
+ AO_TICK_TYPE beep_delay = 0;
if (ao_lco_drag_beep_time > now)
beep_delay = ao_lco_drag_beep_time - now;
* active
*/
-uint16_t
-ao_lco_drag_warn_check(uint16_t now, uint16_t delay)
+AO_TICK_TYPE
+ao_lco_drag_warn_check(AO_TICK_TYPE now, AO_TICK_TYPE delay)
{
if (ao_lco_drag_race) {
- uint16_t warn_delay;
+ AO_TICK_TYPE warn_delay;
- if ((int16_t) (now - ao_lco_drag_warn_time) >= 0) {
+ if ((AO_TICK_SIGNED) (now - ao_lco_drag_warn_time) >= 0) {
ao_lco_drag_add_beeps(1);
ao_lco_drag_warn_time = now + AO_LCO_DRAG_WARN_TIME;
}
static uint16_t lco_box;
static uint8_t lco_channels;
-static uint16_t tick_offset;
static void
lco_args(void)
ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)
{
int8_t r;
- uint16_t sent_time;
- uint16_t timeout = AO_MS_TO_TICKS(10);
+ AO_TICK_TYPE sent_time;
+ AO_TICK_TYPE timeout = AO_MS_TO_TICKS(10);
#if HAS_RADIO_RATE
switch (ao_config.radio_rate) {
ao_lco_arm(uint16_t box, uint8_t channels, uint16_t tick_offset)
{
ao_mutex_get(&ao_lco_mutex);
- command.tick = ao_time() - tick_offset;
+ command.tick = (uint16_t) ao_time() - tick_offset;
command.box = box;
command.cmd = AO_PAD_ARM;
command.channels = channels;
static struct ao_pad_command command;
static struct ao_pad_query query;
static uint8_t ao_pad_armed;
-static uint16_t ao_pad_arm_time;
+static AO_TICK_TYPE ao_pad_arm_time;
static uint8_t ao_pad_box;
static uint8_t ao_pad_disabled;
-static uint16_t ao_pad_packet_time;
+static AO_TICK_TYPE ao_pad_packet_time;
#ifndef AO_PAD_RSSI_MINIMUM
#define AO_PAD_RSSI_MINIMUM -90
prev = cur;
}
- if (ao_pad_armed && (int16_t) (ao_time() - ao_pad_arm_time) > AO_PAD_ARM_TIME)
+ if (ao_pad_armed && (AO_TICK_SIGNED) (ao_time() - ao_pad_arm_time) > AO_PAD_ARM_TIME)
ao_pad_armed = 0;
if (ao_pad_armed) {
static void
ao_pad(void)
{
- int16_t time_difference;
+ int16_t tick_difference;
int8_t ret;
ao_pad_box = 0;
if (command.channels & ~(AO_PAD_ALL_CHANNELS))
break;
- time_difference = command.tick - ao_time();
- PRINTD ("arm tick %d local tick %d\n", command.tick, ao_time());
- if (time_difference < 0)
- time_difference = -time_difference;
- if (time_difference > 10) {
- PRINTD ("time difference too large %d\n", time_difference);
+ tick_difference = command.tick - (uint16_t) ao_time();
+ PRINTD ("arm tick %d local tick %d\n", command.tick, (uint16_t) ao_time());
+ if (tick_difference < 0)
+ tick_difference = -tick_difference;
+ if (tick_difference > 10) {
+ PRINTD ("tick difference too large %d\n", tick_difference);
break;
}
if (query.arm_status != AO_PAD_ARM_STATUS_ARMED) {
PRINTD ("not armed\n");
break;
}
- if ((uint16_t) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) {
+ if ((AO_TICK_SIGNED) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) {
PRINTD ("late pad arm_time %d time %d\n",
ao_pad_arm_time, ao_time());
break;
#if HAS_LOG
if (!ao_log_running) ao_log_start();
#endif
- if ((uint16_t) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) {
+ if ((AO_TICK_SIGNED) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) {
PRINTD ("late pad arm_time %d time %d\n",
ao_pad_arm_time, ao_time());
break;
void
ao_boot_chain(uint32_t *base);
-void
+/* Return true to switch to application */
+int
ao_boot_check_pin(void);
/* Return true to switch to application (if present) */
typedef int16_t gyro_t; /* in raw sample units */
typedef int16_t angle_t; /* in degrees */
-/* Y axis is aligned with the direction of motion (along) */
-/* X axis is aligned in the other board axis (across) */
+/* X axis is aligned with the direction of motion (along) */
+/* Y axis is aligned in the other board axis (across) */
/* Z axis is aligned perpendicular to the board (through) */
static inline float ao_convert_gyro(float sensor)
#endif
#if HAS_ADS131A0X
ao_data_ring[head].ads131a0x = ao_ads131a0x_current;
+#endif
+#if HAS_BMX160
+ ao_data_ring[head].bmx160 = ao_bmx160_current;
#endif
ao_data_ring[head].tick = ao_tick_count;
ao_data_head = ao_data_ring_next(head);
#define AO_LOG_FORMAT_EASYMEGA_2 16 /* 32 byte typed telemega records with 32 bit gyro cal, mpu9250 rotated 90° and adxl375 */
#define AO_LOG_FORMAT_TELESTATIC 17 /* 32 byte typed telestatic records */
#define AO_LOG_FORMAT_MICROPEAK2 18 /* 2-byte baro values with header */
+#define AO_LOG_FORMAT_TELEMEGA_4 19 /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
/* Return the flight number from the given log slot, 0 if none, -slot on failure */
} u;
};
-#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2
+#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4
typedef struct ao_log_mega ao_log_type;
#endif
ao_log_data.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].mpu9250.mag_x;
ao_log_data.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].mpu9250.mag_z;
ao_log_data.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].mpu9250.mag_y;
+#endif
+#if HAS_BMX160
+ ao_log_data.u.sensor.accel_x = ao_data_ring[ao_log_data_pos].bmx160.acc_x;
+ ao_log_data.u.sensor.accel_y = ao_data_ring[ao_log_data_pos].bmx160.acc_y;
+ ao_log_data.u.sensor.accel_z = ao_data_ring[ao_log_data_pos].bmx160.acc_z;
+ ao_log_data.u.sensor.gyro_x = ao_data_ring[ao_log_data_pos].bmx160.gyr_x;
+ ao_log_data.u.sensor.gyro_y = ao_data_ring[ao_log_data_pos].bmx160.gyr_y;
+ ao_log_data.u.sensor.gyro_z = ao_data_ring[ao_log_data_pos].bmx160.gyr_z;
+ ao_log_data.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].bmx160.mag_x;
+ ao_log_data.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].bmx160.mag_z;
+ ao_log_data.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].bmx160.mag_y;
#endif
ao_log_data.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
ao_log_write(&ao_log_data);
struct ao_data *packet = (struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
telemetry.generic.tick = packet->tick;
- telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR;
-
+#if HAS_BMX160
+ telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR_BMX160;
+#else
#if HAS_MPU6000 || HAS_MPU9250
+ telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR_MPU;
+#else
+#error unknown IMU
+#endif
+#endif
+
+#if HAS_GYRO
telemetry.mega_sensor.orient = ao_sample_orient;
#endif
telemetry.mega_sensor.accel = ao_data_accel(packet);
telemetry.mega_sensor.mag_y = packet->mpu9250.mag_y;
#endif
+#if HAS_BMX160
+ telemetry.mega_sensor.accel_x = packet->bmx160.acc_x;
+ telemetry.mega_sensor.accel_y = packet->bmx160.acc_y;
+ telemetry.mega_sensor.accel_z = packet->bmx160.acc_z;
+
+ telemetry.mega_sensor.gyro_x = packet->bmx160.gyr_x;
+ telemetry.mega_sensor.gyro_y = packet->bmx160.gyr_y;
+ telemetry.mega_sensor.gyro_z = packet->bmx160.gyr_z;
+
+ telemetry.mega_sensor.mag_x = packet->bmx160.mag_x;
+ telemetry.mega_sensor.mag_z = packet->bmx160.mag_z;
+ telemetry.mega_sensor.mag_y = packet->bmx160.mag_y;
+#endif
+
ao_telemetry_send();
}
/* 32 */
};
-#define AO_TELEMETRY_MEGA_SENSOR 0x08
+#define AO_TELEMETRY_MEGA_SENSOR_MPU 0x08 /* Invensense IMU */
+#define AO_TELEMETRY_MEGA_SENSOR_BMX160 0x12 /* BMX160 IMU */
struct ao_telemetry_mega_sensor {
uint16_t serial; /* 0 */
#include <ao_boot.h>
#include <ao_exti.h>
-void
+int
ao_boot_check_pin(void)
{
uint16_t v;
- /* Enable power interface clock */
-// stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
-
/* Enable the input pin */
ao_enable_input(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN,
AO_BOOT_APPLICATION_MODE);
/* Reset the chip to turn off the port and the power interface clock */
ao_gpio_set_mode(AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0);
ao_disable_port(AO_BOOT_APPLICATION_GPIO);
-// stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN);
- if (v == AO_BOOT_APPLICATION_VALUE)
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ return v == AO_BOOT_APPLICATION_VALUE;
}
#ifdef AO_BOOT_CHAIN
if (ao_boot_check_chain()) {
#ifdef AO_BOOT_PIN
- ao_boot_check_pin();
+ if (ao_boot_check_pin())
#endif
+ {
+ ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ }
}
#endif
#if RELOCATE_INTERRUPT
#include <ao_boot.h>
#include <ao_exti.h>
-void
+int
ao_boot_check_pin(void)
{
uint16_t v;
ao_gpio_set_mode(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0);
ao_disable_port(&AO_BOOT_APPLICATION_GPIO);
stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN);
- if (v == AO_BOOT_APPLICATION_VALUE)
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ return v == AO_BOOT_APPLICATION_VALUE;
}
#ifdef AO_BOOT_CHAIN
if (ao_boot_check_chain()) {
#ifdef AO_BOOT_PIN
- ao_boot_check_pin();
+ if (ao_boot_check_pin())
#endif
+ {
+ ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ }
}
#endif
/* Set interrupt vector table offset */
#include <ao_boot.h>
#include <ao_exti.h>
-void
+int
ao_boot_check_pin(void)
{
uint16_t v;
ao_gpio_set_mode(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN, 0);
ao_disable_port(&AO_BOOT_APPLICATION_GPIO);
stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN);
- if (v == AO_BOOT_APPLICATION_VALUE)
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ return v == AO_BOOT_APPLICATION_VALUE;
}
#if AO_BOOT_CHAIN
if (ao_boot_check_chain()) {
#if AO_BOOT_PIN
- ao_boot_check_pin();
+ if (ao_boot_check_pin())
#endif
+ {
+ ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ }
}
#endif
/* Turn on syscfg */
static void
ao_lco_drag_monitor(void)
{
- uint16_t delay = ~0;
- uint16_t now;
+ AO_TICK_TYPE delay = ~0;
+ AO_TICK_TYPE now;
ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
for (;;) {
PRINTD("Drag monitor count %d delay %d\n", ao_lco_drag_beep_count, delay);
- if (delay == (uint16_t) ~0)
+ if (delay == (AO_TICK_TYPE) ~0)
ao_sleep(&ao_lco_drag_beep_count);
else
ao_sleep_for(&ao_lco_drag_beep_count, delay);
--- /dev/null
+ao_product.h
+telemega-*.elf
--- /dev/null
+#
+# AltOS build
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_boot.h \
+ ao_companion.h \
+ ao_data.h \
+ ao_sample.h \
+ ao_pins.h \
+ altitude-pa.h \
+ ao_kalman.h \
+ ao_product.h \
+ ao_ms5607.h \
+ ao_mpu9250.h \
+ ao_mma655x.h \
+ ao_cc1200_CC1200.h \
+ ao_profile.h \
+ ao_task.h \
+ ao_whiten.h \
+ ao_sample_profile.h \
+ ao_quaternion.h \
+ ao_mpu.h \
+ stm32l.h \
+ ao_ms5607_convert.c \
+ Makefile
+
+#
+# Common AltOS sources
+#
+
+#PROFILE=ao_profile.c
+#PROFILE_DEF=-DAO_PROFILE=1
+
+#SAMPLE_PROFILE=ao_sample_profile.c \
+# ao_sample_profile_timer.c
+#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1
+
+#STACK_GUARD=ao_mpu_stm.c
+#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1
+
+ALTOS_SRC = \
+ ao_boot_chain.c \
+ ao_interrupt.c \
+ ao_product.c \
+ ao_romconfig.c \
+ ao_cmd.c \
+ ao_config.c \
+ ao_task.c \
+ ao_led_stm.c \
+ ao_stdio.c \
+ ao_panic.c \
+ ao_timer.c \
+ ao_mutex.c \
+ ao_serial_stm.c \
+ ao_gps_ublox.c \
+ ao_gps_show.c \
+ ao_gps_report_mega.c \
+ ao_ignite.c \
+ ao_freq.c \
+ ao_dma_stm.c \
+ ao_spi_stm.c \
+ ao_cc1200.c \
+ ao_data.c \
+ ao_ms5607.c \
+ ao_adxl375.c \
+ ao_adc_stm.c \
+ ao_beep_stm.c \
+ ao_eeprom_stm.c \
+ ao_storage.c \
+ ao_m25.c \
+ ao_usb_stm.c \
+ ao_exti_stm.c \
+ ao_report.c \
+ ao_bmx160.c \
+ ao_convert_pa.c \
+ ao_convert_volt.c \
+ ao_log.c \
+ ao_log_mega.c \
+ ao_sample.c \
+ ao_kalman.c \
+ ao_flight.c \
+ ao_telemetry.c \
+ ao_packet_slave.c \
+ ao_packet.c \
+ ao_companion.c \
+ ao_pyro.c \
+ ao_aprs.c \
+ ao_pwm_stm.c \
+ $(PROFILE) \
+ $(SAMPLE_PROFILE) \
+ $(STACK_GUARD)
+
+PRODUCT=TeleMega-v4.0
+PRODUCT_DEF=-DTELEMEGA
+IDPRODUCT=0x0023
+
+CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF)
+
+PROGNAME=telemega-v4.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telemega.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(OBJ): $(INC)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#define HAS_TASK_QUEUE 1
+
+/* 8MHz High speed external crystal */
+#define AO_HSE 8000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL 12
+#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12)
+
+/* SYSCLK = 32MHz (no need to go faster than CPU) */
+#define AO_PLLDIV 3
+#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3)
+
+/* HCLK = 32MHz (CPU clock) */
+#define AO_AHB_PRESCALER 1
+#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1
+
+/* Run APB1 at 16MHz (HCLK/2) */
+#define AO_APB1_PRESCALER 2
+#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2
+
+/* Run APB2 at 16MHz (HCLK/2) */
+#define AO_APB2_PRESCALER 2
+#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2
+
+#define HAS_SERIAL_1 0
+#define USE_SERIAL_1_STDIN 0
+#define SERIAL_1_PB6_PB7 0
+#define SERIAL_1_PA9_PA10 0
+
+#define HAS_SERIAL_2 0
+#define USE_SERIAL_2_STDIN 0
+#define SERIAL_2_PA2_PA3 0
+#define SERIAL_2_PD5_PD6 0
+
+#define HAS_SERIAL_3 1
+#define USE_SERIAL_3_STDIN 0
+#define SERIAL_3_PB10_PB11 0
+#define SERIAL_3_PC10_PC11 1
+#define SERIAL_3_PD8_PD9 0
+
+#define ao_gps_getchar ao_serial3_getchar
+#define ao_gps_putchar ao_serial3_putchar
+#define ao_gps_set_speed ao_serial3_set_speed
+#define ao_gps_fifo (ao_stm_usart3.rx_fifo)
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+#define AO_LOG_FORMAT AO_LOG_FORMAT_TELEMEGA_4
+
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 0
+#define USE_EEPROM_CONFIG 1
+#define USE_STORAGE_CONFIG 0
+#define HAS_USB 1
+#define HAS_BEEP 1
+#define BEEPER_TIMER 3
+#define BEEPER_CHANNEL 1
+#define BEEPER_PORT (&stm_gpioc)
+#define BEEPER_PIN 6
+#define HAS_BATTERY_REPORT 1
+#define HAS_RADIO 1
+#define HAS_TELEMETRY 1
+#define HAS_APRS 1
+#define HAS_COMPANION 1
+
+#define HAS_SPI_1 1
+#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
+#define SPI_1_PB3_PB4_PB5 1 /* Accelerometer */
+#define SPI_1_PE13_PE14_PE15 1 /* IMU */
+#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz
+
+#define HAS_SPI_2 1
+#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */
+#define SPI_2_PD1_PD3_PD4 0
+#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz
+
+#define HAS_I2C_1 0
+#define I2C_1_PB8_PB9 0
+
+#define HAS_I2C_2 0
+#define I2C_2_PB10_PB11 0
+
+#define PACKET_HAS_SLAVE 1
+#define PACKET_HAS_MASTER 0
+
+#define LOW_LEVEL_DEBUG 0
+
+#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT (&stm_gpioc)
+#define LED_PIN_RED 8
+#define LED_PIN_GREEN 9
+#define AO_LED_RED (1 << LED_PIN_RED)
+#define AO_LED_GREEN (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_GPS 1
+#define HAS_FLIGHT 1
+#define HAS_ADC 1
+#define HAS_ADC_TEMP 1
+#define HAS_LOG 1
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE 1
+#define HAS_IGNITE_REPORT 1
+
+#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n])
+#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4])
+#define AO_SENSE_MAIN(p) ((p)->adc.sense[5])
+#define AO_IGNITER_CLOSED 400
+#define AO_IGNITER_OPEN 60
+
+/* Pyro A */
+#define AO_PYRO_PORT_0 (&stm_gpiod)
+#define AO_PYRO_PIN_0 6
+
+/* Pyro B */
+#define AO_PYRO_PORT_1 (&stm_gpiod)
+#define AO_PYRO_PIN_1 7
+
+/* Pyro C */
+#define AO_PYRO_PORT_2 (&stm_gpiod)
+#define AO_PYRO_PIN_2 5
+
+/* Pyro D */
+#define AO_PYRO_PORT_3 (&stm_gpioe)
+#define AO_PYRO_PIN_3 4
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioe)
+#define AO_IGNITER_DROGUE_PIN 6
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT (&stm_gpioe)
+#define AO_IGNITER_MAIN_PIN 5
+
+/* Number of general purpose pyro channels available */
+#define AO_PYRO_NUM 4
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING 32
+#define AO_ADC_NUM_SENSE 6
+
+struct ao_adc {
+ int16_t sense[AO_ADC_NUM_SENSE];
+ int16_t v_batt;
+ int16_t v_pbatt;
+ int16_t temp;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+ (p)->tick, \
+ (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \
+ (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \
+ (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp)
+
+#define AO_ADC_SENSE_A 0
+#define AO_ADC_SENSE_A_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_A_PIN 0
+
+#define AO_ADC_SENSE_B 1
+#define AO_ADC_SENSE_B_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_B_PIN 1
+
+#define AO_ADC_SENSE_C 2
+#define AO_ADC_SENSE_C_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_C_PIN 2
+
+#define AO_ADC_SENSE_D 3
+#define AO_ADC_SENSE_D_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_D_PIN 3
+
+#define AO_ADC_SENSE_DROGUE 4
+#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN 4
+
+#define AO_ADC_SENSE_MAIN 22
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe)
+#define AO_ADC_SENSE_MAIN_PIN 7
+
+#define AO_ADC_V_BATT 8
+#define AO_ADC_V_BATT_PORT (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN 0
+
+#define AO_ADC_V_PBATT 9
+#define AO_ADC_V_PBATT_PORT (&stm_gpiob)
+#define AO_ADC_V_PBATT_PIN 1
+
+#define AO_ADC_TEMP 16
+
+#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+ (1 << STM_RCC_AHBENR_GPIOEEN) | \
+ (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2)
+
+#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT
+#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN
+#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT
+#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN
+#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT
+#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN
+#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT
+#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN
+#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT
+#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN
+
+#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3)
+
+#define AO_ADC_SQ1 AO_ADC_SENSE_A
+#define AO_ADC_SQ2 AO_ADC_SENSE_B
+#define AO_ADC_SQ3 AO_ADC_SENSE_C
+#define AO_ADC_SQ4 AO_ADC_SENSE_D
+#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ7 AO_ADC_V_BATT
+#define AO_ADC_SQ8 AO_ADC_V_PBATT
+#define AO_ADC_SQ9 AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */
+#define AO_BATTERY_DIV_MINUS 100 /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT (&stm_gpioc)
+#define AO_MS5607_CS_PIN 4
+#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT (&stm_gpioa)
+#define AO_MS5607_MISO_PIN 6
+#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT (&stm_gpiod)
+#define AO_M25_SPI_CS_MASK (1 << 3)
+#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1120)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT 5695733
+
+#define AO_FEC_DEBUG 0
+#define AO_CC1200_SPI_CS_PORT (&stm_gpioc)
+#define AO_CC1200_SPI_CS_PIN 5
+#define AO_CC1200_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1200_SPI stm_spi2
+#define AO_CC1200_SPI_SPEED AO_SPI_SPEED_FAST
+
+#define AO_CC1200_INT_PORT (&stm_gpioe)
+#define AO_CC1200_INT_PIN 1
+#define AO_CC1200_MCU_WAKEUP_PORT (&stm_gpioc)
+#define AO_CC1200_MCU_WAKEUP_PIN (0)
+
+#define AO_CC1200_INT_GPIO 2
+#define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2
+
+#define AO_CC1200_MARC_GPIO 3
+#define AO_CC1200_MARC_GPIO_IOCFG CC1200_IOCFG3
+
+#define HAS_BOOT_RADIO 0
+
+/*
+ * bmx160
+ */
+
+#define HAS_BMX160 1
+#define AO_BMX160_INT_PORT (&stm_gpioe)
+#define AO_BMX160_INT_PIN 0
+#define AO_BMX160_SPI_BUS AO_SPI_1_PE13_PE14_PE15
+#define AO_BMX160_SPI_CS_PORT (&stm_gpiod)
+#define AO_BMX160_SPI_CS_PIN 2
+#define HAS_IMU 1
+
+#define ao_data_along(packet) ((packet)->bmx160.acc_x)
+#define ao_data_across(packet) (-(packet)->bmx160.acc_y)
+#define ao_data_through(packet) ((packet)->bmx160.acc_z)
+
+#define ao_data_roll(packet) ((packet)->bmx160.gyr_x)
+#define ao_data_pitch(packet) (-(packet)->bmx160.gyr_y)
+#define ao_data_yaw(packet) ((packet)->bmx160.gyr_z)
+
+#define ao_data_mag_along(packet) ((packet)->bmx160.mag_x)
+#define ao_data_mag_across(packet) ((packet)->bmx160.mag_y)
+#define ao_data_mag_through(packet) ((packet)->bmx160.mag_z)
+
+/* ADXL375 */
+
+#define HAS_ADXL375 1
+#define AO_ADXL375_SPI_INDEX (AO_SPI_1_PB3_PB4_PB5 | AO_SPI_MODE_3)
+#define AO_ADXL375_CS_PORT (&stm_gpiod)
+#define AO_ADXL375_CS_PIN 4
+#define AO_ADXL375_SPI_SPEED AO_SPI_SPEED_4MHz
+
+#define AO_ADXL375_AXIS x
+#define AO_ADXL375_INVERT 1
+
+#define NUM_CMDS 16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT (&stm_gpiob)
+#define AO_COMPANION_CS_PIN_0 (6)
+#define AO_COMPANION_CS_PIN AO_COMPANION_CS_PIN_0
+#define AO_COMPANION_CS_PIN_1 (7)
+#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR 0
+#define LEGACY_MONITOR 0
+#define HAS_MONITOR_PUT 1
+#define AO_MONITOR_LED 0
+#define HAS_RSSI 0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE 0
+#endif
+
+/*
+ * PWM output
+ */
+
+#define NUM_PWM 4
+#define PWM_MAX 20000
+#define AO_PWM_TIMER stm_tim4
+#define AO_PWM_TIMER_ENABLE STM_RCC_APB1ENR_TIM4EN
+#define AO_PWM_TIMER_SCALE 32
+
+#define AO_PWM_0_GPIO (&stm_gpiod)
+#define AO_PWM_0_PIN 12
+
+#define AO_PWM_1_GPIO (&stm_gpiod)
+#define AO_PWM_1_PIN 13
+
+#define AO_PWM_2_GPIO (&stm_gpiod)
+#define AO_PWM_2_PIN 14
+
+#define AO_PWM_3_GPIO (&stm_gpiod)
+#define AO_PWM_3_PIN 15
+
+#endif /* _AO_PINS_H_ */
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_bmx160.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_eeprom.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#include <ao_pyro.h>
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+#include <ao_pwm.h>
+
+int
+main(void)
+{
+ ao_clock_init();
+
+#if HAS_STACK_GUARD
+ ao_mpu_init();
+#endif
+
+ ao_task_init();
+ ao_serial_init();
+ ao_led_init();
+ ao_led_on(LEDS_AVAILABLE);
+ ao_timer_init();
+
+ ao_spi_init();
+ ao_dma_init();
+ ao_exti_init();
+
+ ao_adc_init();
+#if HAS_BEEP
+ ao_beep_init();
+#endif
+ ao_cmd_init();
+
+ ao_ms5607_init();
+ ao_bmx160_init();
+ ao_adxl375_init();
+
+ ao_eeprom_init();
+ ao_storage_init();
+
+ ao_flight_init();
+ ao_log_init();
+ ao_report_init();
+
+ ao_usb_init();
+ ao_gps_init();
+ ao_gps_report_mega_init();
+ ao_telemetry_init();
+ ao_radio_init();
+ ao_packet_slave_init(false);
+ ao_igniter_init();
+ ao_companion_init();
+ ao_pyro_init();
+
+ ao_config_init();
+#if AO_PROFILE
+ ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+ ao_sample_profile_init();
+#endif
+
+ ao_pwm_init();
+
+ ao_led_off(LEDS_AVAILABLE);
+
+ ao_start_scheduler();
+ return 0;
+}
--- /dev/null
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telemega-v4.0
+include $(TOPDIR)/stm/Makefile-flash.defs
--- /dev/null
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* External crystal at 8MHz */
+#define AO_HSE 8000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PB6 */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpiob
+#define AO_BOOT_APPLICATION_PIN 6
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */
#define AO_RECOVERY_VALUE 0
#define AO_RECOVERY_MODE AO_EXTI_MODE_PULL_UP
-/* Beeper is on Tim3 CH4 */
+/* Beeper is on Tim2 CH4 */
#define BEEPER_CHANNEL 4
-#define BEEPER_TIMER 3
+#define BEEPER_TIMER 2
#define BEEPER_PORT (&stm_gpioa)
#define BEEPER_PIN 3
#include <ao.h>
#include <ao_exti.h>
+#if HAS_FORCE_FREQ
static void
ao_check_recovery(void)
{
ao_gpio_set_mode(AO_RECOVERY_PORT, AO_RECOVERY_PIN, 0);
ao_disable_port(AO_RECOVERY_PORT);
}
+#endif
int
main(void)
{
+#if HAS_FORCE_FREQ
ao_check_recovery();
+#endif
ao_clock_init();
ao_task_init();
import java.util.concurrent.*;
import java.util.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPS
extends AltosUIFrame
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSConfigUI
extends AltosUIDialog
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSDisplayThread extends Thread {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSInfo extends AltosUIFlightTab {
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSPreferences
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSState extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_13.*;
-import org.altusmetrum.altosuilib_13.*;
+import org.altusmetrum.altoslib_14.*;
+import org.altusmetrum.altosuilib_14.*;
public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
package org.altusmetrum.telegps;
import java.awt.event.*;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class TeleGPSStatusUpdate implements ActionListener {