kopia lustrzana https://github.com/ge0rg/aprsdroid
Finalised implementation of compressed beacons transmitted
Add settings strings for compressed locations in strings resource Updated javAPRSlib to support setting "csT" field on compressed pakcets Implement compressed altitudes & course data. If speed/course is enabled then append altitude as per uncompressed packetspull/159/head
rodzic
7c17f16a98
commit
e17b20bdc3
Plik binarny nie jest wyświetlany.
|
@ -231,6 +231,10 @@
|
|||
<string name="p_locsource_summary">Manual, Periodic or SmartBeaconing™</string>
|
||||
<string name="p__location">Location Settings</string>
|
||||
<string name="p__location_summary">Configuration for sending position reports</string>
|
||||
<string name="p__location_compressed_beacons">Compressed Beacons</string>
|
||||
<string name="p__location_compressed_beacons_on">Send Compressed Beacons</string>
|
||||
<string name="p__location_compressed_beacons_off">Send Uncompressed Beacons</string>
|
||||
|
||||
|
||||
<string name="p_smartbeaconing">SmartBeaconing™</string>
|
||||
<string name="p_sb_help">SmartBeaconing™ help</string>
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="compressed_location"
|
||||
android:summaryOff="@string/p__location_compressed_beacons_off"
|
||||
android:summaryOn="@string/p__location_compressed_beacons_on"
|
||||
android:title="@string/p__location_compressed_beacons" />
|
||||
<de.duenndns.ListPreferenceWithValue
|
||||
android:key="loc_source"
|
||||
android:title="@string/p_locsource"
|
||||
|
|
|
@ -43,6 +43,20 @@ object AprsPacket {
|
|||
""
|
||||
}
|
||||
|
||||
def formatAltitudeCompressed(location : Location) : String = {
|
||||
if (location.hasAltitude) {
|
||||
var altitude = m2ft(location.getAltitude)
|
||||
var compressedAltitude = ((math.log(altitude) / math.log(1.002)) + 0.5).asInstanceOf[Int]
|
||||
var c = (compressedAltitude / 91).asInstanceOf[Byte] + 33
|
||||
var s = (compressedAltitude % 91).asInstanceOf[Byte] + 33
|
||||
// Negative altitudes cannot be expressed in base-91 and results in corrupt packets
|
||||
if(c < 33) c = 33
|
||||
if(s < 33) s = 33
|
||||
"%c%c".format(c.asInstanceOf[Char], s.asInstanceOf[Char])
|
||||
} else
|
||||
""
|
||||
}
|
||||
|
||||
def formatCourseSpeed(location : Location) : String = {
|
||||
// only report speeds above 2m/s (7.2km/h)
|
||||
if (location.hasSpeed && location.hasBearing)
|
||||
|
@ -53,6 +67,23 @@ object AprsPacket {
|
|||
""
|
||||
}
|
||||
|
||||
def formatCourseSpeedCompressed(location : Location) : String = {
|
||||
// only report speeds above 2m/s (7.2km/h)
|
||||
if (location.hasSpeed && location.hasBearing) {
|
||||
// && location.getSpeed > 2)
|
||||
var compressedBearing = (location.getBearing.asInstanceOf[Int] / 4).asInstanceOf[Int]
|
||||
var compressedSpeed = ((math.log(mps2kt(location.getSpeed)) / math.log(1.08)) - 1).asInstanceOf[Int]
|
||||
var c = compressedBearing.asInstanceOf[Byte] + 33;
|
||||
var s = compressedSpeed.asInstanceOf[Byte] + 33;
|
||||
// Negative speeds a courses cannot be expressed in base-91 and results in corrupt packets
|
||||
if(c < 33) c = 33
|
||||
if(s < 33) s = 33
|
||||
"%c%c".format(c.asInstanceOf[Char], s.asInstanceOf[Char])
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
def formatFreq(csespd : String, freq : Float) : String = {
|
||||
if (freq == 0) "" else {
|
||||
val prefix = if (csespd.length() > 0) "/" else ""
|
||||
|
|
|
@ -213,13 +213,54 @@ class AprsService extends Service {
|
|||
val pos = new Position(location.getLatitude, location.getLongitude, 0,
|
||||
symbol(0), symbol(1))
|
||||
pos.setPositionAmbiguity(prefs.getStringInt("priv_ambiguity", 0))
|
||||
val status_spd = if (prefs.getBoolean("priv_spdbear", true))
|
||||
AprsPacket.formatCourseSpeed(location) else ""
|
||||
val status_spd = if (prefs.getBoolean("priv_spdbear", true)) {
|
||||
if(prefs.getBoolean("compressed_location", false)) {
|
||||
// Compressed format
|
||||
AprsPacket.formatCourseSpeedCompressed(location)
|
||||
} else {
|
||||
AprsPacket.formatCourseSpeed(location)
|
||||
}
|
||||
} else ""
|
||||
val status_freq = AprsPacket.formatFreq(status_spd, prefs.getStringFloat("frequency", 0.0f))
|
||||
val status_alt = if (prefs.getBoolean("priv_altitude", true))
|
||||
AprsPacket.formatAltitude(location) else ""
|
||||
newPacket(new PositionPacket(
|
||||
pos, status_spd + status_freq + status_alt + " " + status, /* messaging = */ true))
|
||||
val status_alt = if (prefs.getBoolean("priv_altitude", true)) {
|
||||
// if speed is empty then use compressed altitude, otherwise use full length altitude
|
||||
if(prefs.getBoolean("compressed_location", false) && status_spd == "") {
|
||||
// Compressed format
|
||||
AprsPacket.formatAltitudeCompressed(location)
|
||||
} else {
|
||||
AprsPacket.formatAltitude(location)
|
||||
}
|
||||
} else ""
|
||||
if(prefs.getBoolean("compressed_location", false)) {
|
||||
if(status_spd == "") {
|
||||
// Speed is empty, so we can use a compressed altitude
|
||||
if(status_alt == "") {
|
||||
// Altitude is empty, so don't send any altitude data
|
||||
pos.setCsTField(" sT")
|
||||
} else {
|
||||
// 3 signifies current GPS fix, GGA altitude, software compressed.
|
||||
pos.setCsTField(status_alt + "3")
|
||||
}
|
||||
val packet = new PositionPacket(
|
||||
pos, status_freq + " " + status, /* messaging = */ true)
|
||||
packet.setCompressedFormat(true)
|
||||
newPacket(packet)
|
||||
} else {
|
||||
// Speed is present, so we need to append the altitude to the end of the packet using the
|
||||
// uncompressed method
|
||||
// Apply the csT field with speed and course
|
||||
// [ signifies current GPS fix, RMC speed, software compressed.
|
||||
pos.setCsTField(status_spd + "[")
|
||||
val packet = new PositionPacket(
|
||||
pos, status_freq + status_alt + " " + status, /* messaging = */ true)
|
||||
packet.setCompressedFormat(true)
|
||||
newPacket(packet)
|
||||
}
|
||||
} else {
|
||||
val packet = new PositionPacket(
|
||||
pos, status_spd + status_freq + status_alt + " " + status, /* messaging = */ true)
|
||||
newPacket(packet)
|
||||
}
|
||||
}
|
||||
|
||||
def sendPacket(packet : APRSPacket, status_postfix : String) {
|
||||
|
|
Ładowanie…
Reference in New Issue