fix: Model rebuilt

This commit is contained in:
Piotr Dec 2024-07-31 20:16:44 +02:00
parent 75e10c1579
commit 785a35473e
Signed by: stawros
GPG key ID: F89F27AD8F881A91
6 changed files with 136 additions and 137 deletions

View file

@ -5,11 +5,11 @@ import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket import android.bluetooth.BluetoothSocket
import android.util.Log import android.util.Log
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
import com.mapbox.navigation.core.trip.session.NavigationSessionState
import com.mapbox.navigation.tripdata.maneuver.model.Maneuver import com.mapbox.navigation.tripdata.maneuver.model.Maneuver
import eu.ztsh.garmin.data.DataCache import eu.ztsh.garmin.data.DataCache
import eu.ztsh.garmin.data.GarminManeuver
import eu.ztsh.garmin.data.GarminMapper import eu.ztsh.garmin.data.GarminMapper
import eu.ztsh.garmin.data.GarminModelItem
import eu.ztsh.garmin.data.MapboxMapper import eu.ztsh.garmin.data.MapboxMapper
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
@ -39,46 +39,61 @@ class Garmin(
ManeuverProcessingThread(maneuver).start() ManeuverProcessingThread(maneuver).start()
} }
fun process(location: LocationMatcherResult) { // fun process(location: LocationMatcherResult) {
LocationProcessingThread(location).start() // LocationProcessingThread(location).start()
} // }
fun process(navigationSessionState: NavigationSessionState) { // fun process(navigationSessionState: NavigationSessionState) {
cache.update(navigationSessionState) // cache.update(navigationSessionState)
} // }
private inner class ManeuverProcessingThread(val maneuver: Maneuver) : ProcessingThread() { private inner class ManeuverProcessingThread(val maneuver: Maneuver) : ProcessingThread<GarminManeuver>() {
override fun run() { override fun process(): GarminManeuver? {
if (cache.hasChanged(maneuver)) { if (cache.hasChanged(maneuver)) {
cache.update(maneuver) cache.update(maneuver)
send(MapboxMapper.apply(maneuver)) return MapboxMapper.map(maneuver)
} }
return null
}
override fun enqueue(item: GarminManeuver) {
if (cache.hasChanged(item.lanes)) {
connection.enqueue(GarminMapper.map(item.lanes))
}
if (cache.hasChanged(item.direction)) {
connection.enqueue(GarminMapper.map(item.direction))
}
if (cache.hasChanged(item.distance)) {
connection.enqueue(GarminMapper.map(item.distance))
}
// flag?
} }
} }
private inner class LocationProcessingThread(val location: LocationMatcherResult) : ProcessingThread() { // private inner class LocationProcessingThread(val location: LocationMatcherResult) : ProcessingThread() {
//
// override fun process() {
// if (cache.hasChanged(location)) {
// cache.update(location)
// send(MapboxMapper.apply(location))
// }
// }
// }
private abstract inner class ProcessingThread<T : GarminModelItem> : Thread() {
abstract fun process(): T?
abstract fun enqueue(item: T)
override fun run() { override fun run() {
if (cache.hasChanged(location)) { val processing = process()
cache.update(location) if (processing != null) {
send(MapboxMapper.apply(location)) enqueue(processing)
cache.update(processing)
} }
}
}
private open inner class ProcessingThread : Thread() {
fun send(incoming: eu.ztsh.garmin.data.State) {
if (cache.hasChanged(incoming.distance)) {
connection.enqueue(GarminMapper.setDistance(incoming))
}
if (cache.hasChanged(incoming.direction)) {
connection.enqueue(GarminMapper.setDirection(incoming))
}
cache.update(incoming)
observer.join(this) observer.join(this)
} }
@ -86,7 +101,7 @@ class Garmin(
private inner class ProcessingThreadObserver { private inner class ProcessingThreadObserver {
fun join(thread: ProcessingThread) { fun <T : GarminModelItem> join(thread: ProcessingThread<T>) {
thread.join() thread.join()
} }

View file

@ -6,39 +6,38 @@ import com.mapbox.navigation.tripdata.maneuver.model.Maneuver
class DataCache { class DataCache {
private val stateCache: State = State() private val garminManeuver: GarminManeuver = GarminManeuver.empty()
private var maneuverCache: Maneuver? = null private var maneuverCache: Maneuver? = null
private var locationCache: LocationMatcherResult? = null private var locationCache: LocationMatcherResult? = null
private var session: NavigationSessionState? = null private var session: NavigationSessionState? = null
// state // state
fun hasChanged(lanes: Lanes?): Boolean { fun hasChanged(lanes: Lanes): Boolean {
return stateCache.lineArrows == null || stateCache.lineArrows != lanes return garminManeuver.lanes != lanes
} }
fun hasChanged(outlines: Outlines?): Boolean { fun hasChanged(distance: Distance): Boolean {
return stateCache.lineOutlines == null || stateCache.lineOutlines != outlines return garminManeuver.distance != distance
} }
fun hasChanged(distance: Distance?): Boolean { fun hasChanged(direction: Direction): Boolean {
return stateCache.distance == null || stateCache.distance != distance return garminManeuver.direction != direction
}
fun hasChanged(direction: Direction?): Boolean {
return stateCache.direction == null || stateCache.direction != direction
}
fun hasChanged(speed: Speed?): Boolean {
return stateCache.speed == null || stateCache.speed != speed
}
fun hasChanged(arrival: Arrival?): Boolean {
return stateCache.arrival == null || stateCache.arrival != arrival
} }
//
// fun hasChanged(speed: Speed?): Boolean {
// return stateCache.speed == null || stateCache.speed != speed
// }
//
// fun hasChanged(arrival: Arrival?): Boolean {
// return stateCache.arrival == null || stateCache.arrival != arrival
// }
// Merge states // Merge states
fun update(state: State) { fun update(item: GarminModelItem) {
stateCache.merge(state) when(item) {
is GarminManeuver -> garminManeuver.merge(item)
}
} }
// maneuver // maneuver

View file

@ -4,24 +4,20 @@ class GarminMapper {
companion object { companion object {
fun setLines(state: State): IntArray { fun map(lanes: Lanes): IntArray {
return intArrayOf(0x02, state.lineOutlines.sumOf { it.value }, state.lineArrows.sumOf { it.value }) return intArrayOf(0x02, lanes.lanes.lanes.sumOf { it.value }, lanes.outlines.lanes.sumOf { it.value })
} }
fun setDirection(state: State): IntArray { fun map(direction: Direction): IntArray {
return setDirection(state.direction.angle, state.direction.out, state.direction.roundabout) return toDirectionArray(direction.angle, direction.out, direction.roundabout)
} }
fun setDistance(state: State): IntArray { fun map(distance: Distance): IntArray {
return setDistance(state.distance, state.unit) return setDistance(distance.distance, distance.unit)
} }
fun setSpeed(state: State): IntArray { fun map(speed: Speed): IntArray {
return setSpeed(state.speed, state.limit, state.speed > state.limit) return setSpeed(speed.speed, speed.limit, speed.speed > speed.limit)
}
fun setSpeedFreeRide(state: State): Pair<IntArray, IntArray> {
return Pair(setDistance(state.speed), setSpeed(state.limit, limitWarning = state.speed > state.limit))
} }
fun setTime(hours: Int, minutes: Int, traffic: Boolean = false, flag: Boolean = false): IntArray { fun setTime(hours: Int, minutes: Int, traffic: Boolean = false, flag: Boolean = false): IntArray {
@ -54,20 +50,15 @@ class GarminMapper {
} }
} }
fun setSpeedControl(state: State): IntArray { fun speedControl(state: Boolean): IntArray {
return intArrayOf(0x04, if (state.control) 0x01 else 0x02) return intArrayOf(0x04, if (state) 0x01 else 0x02)
}
fun setCompass(state: State): IntArray {
// TODO: Implement
return setDirection(OutAngle.Straight, OutType.ArrowOnly)
} }
fun cleanDistance(): IntArray { fun cleanDistance(): IntArray {
return intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) return intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
} }
private fun setDirection( private fun toDirectionArray(
angle: OutAngle, angle: OutAngle,
out: OutType = OutType.Lane, out: OutType = OutType.Lane,
roundabout: OutAngle = OutAngle.AsDirection roundabout: OutAngle = OutAngle.AsDirection

View file

@ -7,14 +7,14 @@ class MapboxMapper {
companion object { companion object {
fun apply(maneuver: Maneuver): State { fun map(maneuver: Maneuver): GarminManeuver {
val state = State() val state = GarminManeuver()
maneuver.apply { maneuver.apply {
this.primary.apply { this.primary.apply {
state.direction = Direction() state.direction = Direction()
when (this.type) { when (this.type) {
"roundabout" -> { "roundabout" -> {
state.direction!!.out = OutType.RightRoundabout state.direction.out = OutType.RightRoundabout
} }
"arrive" -> { "arrive" -> {
@ -24,11 +24,11 @@ class MapboxMapper {
when (this.modifier) { when (this.modifier) {
"right" -> { "right" -> {
when (this.type) { when (this.type) {
"turn" -> state.direction!!.angle = OutAngle.Right "turn" -> state.direction.angle = OutAngle.Right
"roundabout" -> { "roundabout" -> {
when (this.degrees) { when (this.degrees) {
137.0 -> state.direction!!.angle = OutAngle.EasyRight 137.0 -> state.direction.angle = OutAngle.EasyRight
180.0 -> state.direction!!.angle = OutAngle.Straight 180.0 -> state.direction.angle = OutAngle.Straight
} }
} }
} }
@ -36,16 +36,16 @@ class MapboxMapper {
"left" -> { "left" -> {
when (this.type) { when (this.type) {
"turn" -> state.direction!!.angle = OutAngle.Left "turn" -> state.direction.angle = OutAngle.Left
} }
} }
} }
} }
this.stepDistance.apply { this.stepDistance.apply {
this.distanceRemaining?.apply { this.distanceRemaining?.apply {
distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply { distanceFormatter.formatDistance(this).split(" ").apply {
state.distance = Distance( state.distance = Distance(
this[0].replace(',', '.').toDouble().toInt(), this[0].replace(',', '.').toDouble(),
when (this[1]) { when (this[1]) {
"m" -> Unit.Metres "m" -> Unit.Metres
"km" -> Unit.Kilometres "km" -> Unit.Kilometres
@ -65,8 +65,8 @@ class MapboxMapper {
return state return state
} }
fun apply(locationMatcherResult: LocationMatcherResult): State { fun map(locationMatcherResult: LocationMatcherResult): GarminLocation {
val state = State() val state = GarminLocation()
// TODO: speed, limit, location?, bearing // TODO: speed, limit, location?, bearing
return state return state
} }

View file

@ -12,7 +12,6 @@ enum class OutType(val value: Int) {
} }
enum class OutAngle(val value: Int) { enum class OutAngle(val value: Int) {
Down(0x01), Down(0x01),
@ -52,7 +51,7 @@ enum class Lane(val value: Int) {
} }
open class Arrows(val lanes: List<Lane>) { class Arrows(val lanes: List<Lane>) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@ -68,11 +67,9 @@ open class Arrows(val lanes: List<Lane>) {
} }
} }
class Lanes(lanes: List<Lane>) : Arrows(lanes) class Lanes(val outlines: Arrows, val lanes: Arrows)
class Outlines(lanes: List<Lane>) : Arrows(lanes) class Distance(val distance: Double, val unit: Unit) {
class Distance(val distance: Int, val unit: Unit) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@ -87,7 +84,7 @@ class Distance(val distance: Int, val unit: Unit) {
} }
override fun hashCode(): Int { override fun hashCode(): Int {
var result = distance var result = distance.hashCode()
result = 31 * result + unit.hashCode() result = 31 * result + unit.hashCode()
return result return result
} }
@ -98,47 +95,12 @@ class Speed(val speed: Int, val limit: Int)
class Arrival(val hours: Int, val minutes: Int) class Arrival(val hours: Int, val minutes: Int)
class State { class Direction(
var angle: OutAngle = OutAngle.AsDirection,
var lineArrows: Lanes? = null var out: OutType = OutType.Lane,
var lineOutlines: Outlines? = null
var direction : Direction? = null
var distance: Distance? = null
var speed: Speed? = null
var arrival: Arrival? = null
// TODO: Bearing
// TODO: support
var traffic: Boolean? = null
var flag: Boolean? = null
var control: Boolean? = null
fun merge(other: State) {
if (other.lineArrows != null) {
this.lineArrows = other.lineArrows
}
if (other.lineOutlines != null) {
this.lineOutlines = other.lineOutlines
}
if (other.direction != null) {
this.direction = other.direction
}
if (other.distance != null) {
this.distance = other.distance
}
if (other.speed != null) {
this.speed = other.speed
}
if (other.arrival != null) {
this.arrival = other.arrival
}
}
}
class Direction {
var angle: OutAngle = OutAngle.AsDirection
var out: OutType = OutType.Lane
var roundabout: OutAngle = OutAngle.AsDirection var roundabout: OutAngle = OutAngle.AsDirection
) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false
@ -160,3 +122,39 @@ class Direction {
} }
} }
interface GarminModelItem {
fun merge(item: GarminModelItem)
}
class GarminManeuver : GarminModelItem {
lateinit var lanes: Lanes
lateinit var direction: Direction
lateinit var distance: Distance
var flag: Boolean = false // WTF?
override fun merge(item: GarminModelItem) {
TODO("Not yet implemented")
}
companion object {
val empty: () -> GarminManeuver = {
val manouver = GarminManeuver()
manouver.lanes = Lanes(Arrows(listOf()), Arrows(listOf()))
manouver.direction = Direction(out = OutType.Off)
manouver.distance = Distance(0.0, Unit.Any)
manouver
}
}
}
class GarminLocation : GarminModelItem {
override fun merge(item: GarminModelItem) {
TODO("Not yet implemented")
}
}

View file

@ -253,10 +253,8 @@ class GarminMapperTest {
} }
private fun linesTest(outlines: List<Lane>, arrows: List<Lane>, expectedRaw: IntArray, expectedBoxed: IntArray) { private fun linesTest(outlines: List<Lane>, arrows: List<Lane>, expectedRaw: IntArray, expectedBoxed: IntArray) {
val state = State() val lanes = Lanes(Arrows(arrows), Arrows(outlines))
state.lineOutlines = outlines makeAssertions(GarminMapper.map(lanes), expectedRaw, expectedBoxed)
state.lineArrows = arrows
makeAssertions(GarminMapper.setLines(state), expectedRaw, expectedBoxed)
} }
private fun directionTest(outAngle: OutAngle, expectedRaw: IntArray, expectedBoxed: IntArray) { private fun directionTest(outAngle: OutAngle, expectedRaw: IntArray, expectedBoxed: IntArray) {
@ -264,10 +262,8 @@ class GarminMapperTest {
} }
private fun directionTest(outAngle: OutAngle, outType: OutType, expectedRaw: IntArray, expectedBoxed: IntArray) { private fun directionTest(outAngle: OutAngle, outType: OutType, expectedRaw: IntArray, expectedBoxed: IntArray) {
val state = State() val direction = Direction(outAngle, outType)
state.direction.angle = outAngle makeAssertions(GarminMapper.map(direction), expectedRaw, expectedBoxed)
state.direction.out = outType
makeAssertions(GarminMapper.setDirection(state), expectedRaw, expectedBoxed)
} }
private fun makeAssertions(resultRaw: IntArray, expectedRaw: IntArray, expectedBoxed: IntArray) { private fun makeAssertions(resultRaw: IntArray, expectedRaw: IntArray, expectedBoxed: IntArray) {