Debounce implemented
This commit is contained in:
parent
801d00c6d0
commit
5a72d447cb
@ -4,6 +4,7 @@ import android.Manifest
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowInsetsController
|
import android.view.WindowInsetsController
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
@ -69,6 +70,7 @@ class DumonGeolocation : Plugin() {
|
|||||||
|
|
||||||
// private val emitIntervalMs: Long = 500L
|
// private val emitIntervalMs: Long = 500L
|
||||||
private val emitIntervalMs: Long = 1000L // hard debounce
|
private val emitIntervalMs: Long = 1000L // hard debounce
|
||||||
|
// private val emitIntervalMs: Long = 500L
|
||||||
|
|
||||||
override fun load() {
|
override fun load() {
|
||||||
gpsManager = GpsStatusManager(
|
gpsManager = GpsStatusManager(
|
||||||
@ -91,6 +93,7 @@ class DumonGeolocation : Plugin() {
|
|||||||
onImuUpdate = {
|
onImuUpdate = {
|
||||||
latestImu = it
|
latestImu = it
|
||||||
emitPositionUpdate()
|
emitPositionUpdate()
|
||||||
|
fusionManager?.updateMotionEstimate(it.speed.toDouble(), it.directionRad.toDouble())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -265,6 +268,19 @@ class DumonGeolocation : Plugin() {
|
|||||||
|
|
||||||
notifyListeners("onPositionUpdate", buildPositionData())
|
notifyListeners("onPositionUpdate", buildPositionData())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback prediksi jika tidak ada GNSS update > 1.5 detik
|
||||||
|
if (System.currentTimeMillis() - latestTimestamp > 1500 && latestImu != null) {
|
||||||
|
val (predLat, predLon) = fusionManager?.predictForwardPosition(1.0) ?: return
|
||||||
|
latestLatitude = predLat
|
||||||
|
latestLongitude = predLon
|
||||||
|
latestAccuracy = 10.0
|
||||||
|
latestSource = "PREDICTED"
|
||||||
|
latestTimestamp = System.currentTimeMillis()
|
||||||
|
|
||||||
|
Log.d("DUMON_PREDICTION", "Predicted position: $predLat, $predLon")
|
||||||
|
notifyListeners("onPositionUpdate", buildPositionData())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun degToRad(deg: Double): Double {
|
private fun degToRad(deg: Double): Double {
|
||||||
@ -300,6 +316,8 @@ class DumonGeolocation : Plugin() {
|
|||||||
obj.put("directionRad", it.directionRad)
|
obj.put("directionRad", it.directionRad)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj.put("predicted", latestSource == "PREDICTED")
|
||||||
|
|
||||||
// === Full Detail (commented out for future use) ===
|
// === Full Detail (commented out for future use) ===
|
||||||
/*
|
/*
|
||||||
satelliteStatus?.let {
|
satelliteStatus?.let {
|
||||||
|
|||||||
@ -18,6 +18,9 @@ class SensorFusionManager(
|
|||||||
private var isFirstUpdate = true
|
private var isFirstUpdate = true
|
||||||
private var lastUpdateTimestamp: Long = 0L
|
private var lastUpdateTimestamp: Long = 0L
|
||||||
|
|
||||||
|
private var lastSpeed = 0.0
|
||||||
|
private var lastHeadingRad = 0.0
|
||||||
|
|
||||||
fun updateGpsPosition(lat: Double, lon: Double) {
|
fun updateGpsPosition(lat: Double, lon: Double) {
|
||||||
val currentTimestamp = System.currentTimeMillis()
|
val currentTimestamp = System.currentTimeMillis()
|
||||||
val dtSeconds = if (lastUpdateTimestamp > 0) {
|
val dtSeconds = if (lastUpdateTimestamp > 0) {
|
||||||
@ -50,6 +53,24 @@ class SensorFusionManager(
|
|||||||
onFusedPositionUpdate(latEstimate, lonEstimate)
|
onFusedPositionUpdate(latEstimate, lonEstimate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateMotionEstimate(speed: Double, headingRad: Double) {
|
||||||
|
lastSpeed = speed
|
||||||
|
lastHeadingRad = headingRad
|
||||||
|
}
|
||||||
|
|
||||||
|
fun predictForwardPosition(secondsAhead: Double): Pair<Double, Double> {
|
||||||
|
val distance = lastSpeed * secondsAhead
|
||||||
|
val R = 6371000.0
|
||||||
|
|
||||||
|
val deltaLat = (distance * cos(lastHeadingRad)) / R
|
||||||
|
val deltaLon = (distance * sin(lastHeadingRad)) / (R * cos(Math.toRadians(latEstimate)))
|
||||||
|
|
||||||
|
val predictedLat = latEstimate + Math.toDegrees(deltaLat)
|
||||||
|
val predictedLon = lonEstimate + Math.toDegrees(deltaLon)
|
||||||
|
|
||||||
|
return Pair(predictedLat, predictedLon)
|
||||||
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
latEstimate = 0.0
|
latEstimate = 0.0
|
||||||
lonEstimate = 0.0
|
lonEstimate = 0.0
|
||||||
|
|||||||
7
dist/docs.json
vendored
7
dist/docs.json
vendored
@ -162,6 +162,13 @@
|
|||||||
"docs": "",
|
"docs": "",
|
||||||
"complexTypes": [],
|
"complexTypes": [],
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "predicted",
|
||||||
|
"tags": [],
|
||||||
|
"docs": "",
|
||||||
|
"complexTypes": [],
|
||||||
|
"type": "boolean | undefined"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
1
dist/esm/definitions.d.ts
vendored
1
dist/esm/definitions.d.ts
vendored
@ -9,6 +9,7 @@ export interface PositioningData {
|
|||||||
acceleration: number;
|
acceleration: number;
|
||||||
directionRad: number;
|
directionRad: number;
|
||||||
isMocked: boolean;
|
isMocked: boolean;
|
||||||
|
predicted?: boolean;
|
||||||
}
|
}
|
||||||
export interface PermissionStatus {
|
export interface PermissionStatus {
|
||||||
location: 'granted' | 'denied';
|
location: 'granted' | 'denied';
|
||||||
|
|||||||
2
dist/esm/definitions.js.map
vendored
2
dist/esm/definitions.js.map
vendored
@ -1 +1 @@
|
|||||||
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// export interface SatelliteStatus {\n// satellitesInView: number;\n// usedInFix: number;\n// constellationCounts: { [key: string]: number };\n// }\n\n// export interface WifiAp {\n// ssid: string;\n// bssid: string;\n// rssi: number;\n// distance?: number;\n// }\n\n// export interface WifiScanResult {\n// apCount: number;\n// aps: WifiAp[];\n// }\n\n// export interface ImuData {\n// accelX: number;\n// accelY: number;\n// accelZ: number;\n// gyroX: number;\n// gyroY: number;\n// gyroZ: number;\n// speed?: number;\n// acceleration?: number;\n// directionRad?: number;\n// }\n\n// export interface GpsData {\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n// satellitesInView?: number;\n// usedInFix?: number;\n// constellationCounts?: { [key: string]: number };\n// }\n\n// export interface PositioningData {\n// source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n// timestamp: number;\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n\n// gnssData?: SatelliteStatus;\n// wifiData?: WifiAp[];\n// imuData?: ImuData;\n// }\n\nexport interface PositioningData {\n source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n timestamp: number;\n latitude: number;\n longitude: number;\n accuracy: number;\n speed: number;\n acceleration: number;\n directionRad: number;\n isMocked: boolean;\n}\n\nexport interface PermissionStatus {\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n}\n\nexport interface DumonGeolocationPlugin {\n startPositioning(): Promise<void>;\n stopPositioning(): Promise<void>;\n getLatestPosition(): Promise<PositioningData>;\n checkAndRequestPermissions(): Promise<PermissionStatus>;\n\n configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise<void>;\n\n addListener(\n eventName: 'onPositionUpdate',\n listenerFunc: (data: PositioningData) => void\n ): PluginListenerHandle;\n}"]}
|
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// export interface SatelliteStatus {\n// satellitesInView: number;\n// usedInFix: number;\n// constellationCounts: { [key: string]: number };\n// }\n\n// export interface WifiAp {\n// ssid: string;\n// bssid: string;\n// rssi: number;\n// distance?: number;\n// }\n\n// export interface WifiScanResult {\n// apCount: number;\n// aps: WifiAp[];\n// }\n\n// export interface ImuData {\n// accelX: number;\n// accelY: number;\n// accelZ: number;\n// gyroX: number;\n// gyroY: number;\n// gyroZ: number;\n// speed?: number;\n// acceleration?: number;\n// directionRad?: number;\n// }\n\n// export interface GpsData {\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n// satellitesInView?: number;\n// usedInFix?: number;\n// constellationCounts?: { [key: string]: number };\n// }\n\n// export interface PositioningData {\n// source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n// timestamp: number;\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n\n// gnssData?: SatelliteStatus;\n// wifiData?: WifiAp[];\n// imuData?: ImuData;\n// }\n\nexport interface PositioningData {\n source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n timestamp: number;\n latitude: number;\n longitude: number;\n accuracy: number;\n speed: number;\n acceleration: number;\n directionRad: number;\n isMocked: boolean;\n predicted?: boolean;\n}\n\nexport interface PermissionStatus {\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n}\n\nexport interface DumonGeolocationPlugin {\n startPositioning(): Promise<void>;\n stopPositioning(): Promise<void>;\n getLatestPosition(): Promise<PositioningData>;\n checkAndRequestPermissions(): Promise<PermissionStatus>;\n\n configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise<void>;\n\n addListener(\n eventName: 'onPositionUpdate',\n listenerFunc: (data: PositioningData) => void\n ): PluginListenerHandle;\n}"]}
|
||||||
@ -61,6 +61,7 @@ export interface PositioningData {
|
|||||||
acceleration: number;
|
acceleration: number;
|
||||||
directionRad: number;
|
directionRad: number;
|
||||||
isMocked: boolean;
|
isMocked: boolean;
|
||||||
|
predicted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PermissionStatus {
|
export interface PermissionStatus {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user