fix: Model rebuilt
This commit is contained in:
parent
75e10c1579
commit
785a35473e
6 changed files with 136 additions and 137 deletions
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue