Hallo zusammen
Ich habe ein LLM auf die Probleme mit der SimRa-App angesetzt. Und es ist allenfalls gelöst, jedenfalls scheint es in der angepassten SimRa-App, die ich nun verwendet habe, zu funktionieren.
Es gabe diese Probleme,
- Die eingestellte Lenkerbreite (links) wurde in der Live-Ansicht falsch verwendet.
- Die eingestellte Lenkerbreite (links) wurde im Event falsch verwendet.
- Einstellung der Lenkerbreite (rechts) hatte den gleichen Einfluss wie die linke Seite, siehe OBS-lite distance reading calculation errors · Issue #35 · simra-project/simra-android · GitHub
Ich habe dann dem LML gesagt, dass die Anpassungen zusammengefasst werden sollen, damit es nachvollziehbar ist. Et voila:
OBSLiteActivity.kt
a) Berechnung der Distanz + Lenkerbreite (im handleEvent())
Original
// event is distance event
if (event.hasDistanceMeasurement() && event.distanceMeasurement.distance < 5) {
// convert distance to cm + handlebar width
val distance = ((event.distanceMeasurement.distance * 100) +
SharedPref.Settings.Ride.OvertakeWidth.getHandlebarWidth(this)).toInt()
// left sensor event
if (event.distanceMeasurement.sourceId == 1) {
binding.leftSensorTextView.text = this@OBSLiteActivity.getString(
R.string.obs_lite_text_last_distance_left,
distance
)
setColePassBarColor(distance, binding.leftSensorProgressBar)
val eventTime = event.getTime(0).seconds
if (startTime == -1L) {
startTime = eventTime
}
// calculate minimal moving median for when the user presses obs lite button
movingMedian.newValue(distance)
// right sensor event
} else {
binding.rightSensorTextView.text = this@OBSLiteActivity.getString(
R.string.obs_lite_text_last_distance_right,
distance
)
setColePassBarColor(distance, binding.rightSensorProgressBar)
}
// event is user input event
} else if (event.hasUserInput()) {
...
}
Geänderte Version
// event is distance event
if (event.hasDistanceMeasurement() && event.distanceMeasurement.distance < 5) {
// Rohwert (Meter -> cm)
val rawDistanceCm = (event.distanceMeasurement.distance * 100).toInt()
// left sensor event
if (event.distanceMeasurement.sourceId == 1) {
// Linker Sensor -> linke Lenkerbreite verwenden
val handlebarWidthLeftCm =
SharedPref.Settings.Ride.OvertakeWidth.getHandlebarWidthLeft(this)
val correctedDistanceLeft =
(rawDistanceCm - handlebarWidthLeftCm).coerceAtLeast(0)
binding.leftSensorTextView.text = this@OBSLiteActivity.getString(
R.string.obs_lite_text_last_distance_left,
correctedDistanceLeft
)
setColePassBarColor(correctedDistanceLeft, binding.leftSensorProgressBar)
val eventTime = event.getTime(0).seconds
if (startTime == -1L) {
startTime = eventTime
}
// calculate minimal moving median for when the user presses obs lite button
// Moving-Median arbeitet mit bereits korrigiertem Abstand (cm)
movingMedian.newValue(correctedDistanceLeft)
// right sensor event
} else {
// Rechter Sensor -> rechte Lenkerbreite verwenden
val handlebarWidthRightCm =
SharedPref.Settings.Ride.OvertakeWidth.getHandlebarWidthRight(this)
val correctedDistanceRight =
(rawDistanceCm - handlebarWidthRightCm).coerceAtLeast(0)
binding.rightSensorTextView.text = this@OBSLiteActivity.getString(
R.string.obs_lite_text_last_distance_right,
correctedDistanceRight
)
setColePassBarColor(correctedDistanceRight, binding.rightSensorProgressBar)
}
// event is user input event
} else if (event.hasUserInput()) {
...
}
b) Event beim User-Input (Button) (ebenfalls in handleEvent())
Original
// event is user input event
} else if (event.hasUserInput()) {
val dm: DistanceMeasurement = DistanceMeasurement.newBuilder()
.setDistance(movingMedian.median.toFloat()).build()
event = event.toBuilder().setDistanceMeasurement(dm).build()
binding.userInputProgressbarTextView.text =
this@OBSLiteActivity.getString(
R.string.overtake_distance_left,
movingMedian.median
)
setColePassBarColor(
movingMedian.median,
binding.leftSensorUserInputProgressBar
)
binding.userInputTextView.text =
this@OBSLiteActivity.getString(R.string.overtake_press_button) + event
}
Geänderte Version
// event is user input event
} else if (event.hasUserInput()) {
// Der Median enthält bereits den korrigierten Abstand in cm
val dm: DistanceMeasurement = DistanceMeasurement.newBuilder()
.setDistance(movingMedian.median.toFloat()) // cm
.build()
event = event.toBuilder().setDistanceMeasurement(dm).build()
binding.userInputProgressbarTextView.text =
this@OBSLiteActivity.getString(
R.string.overtake_distance_left,
movingMedian.median
)
setColePassBarColor(
movingMedian.median,
binding.leftSensorUserInputProgressBar
)
binding.userInputTextView.text =
this@OBSLiteActivity.getString(R.string.overtake_press_button) + event
}
RecorderService.java
1. Kommentar im InsertHandler
Original
@SuppressLint("MissingPermission")
public void run() {
/*
How is this Working?
We are collecting GPS, Accelerometer, Gyroscope (and OpenBikeSensor) Data, those are updated as following;
- GPS (lat, lon, accuracy) roughly every 3 seconds
- accelerometer data (x,y,z) roughly 50 times a second
- gyroscope data (a,b,c) roughly every 3 seconds
<p>
Every Data Type is given asynchronously via its Callback function.
In order to synchronize the accelerometer interval ist used as baseline.
1. We wait till there are 30 values generated
2. We write a Log Entry every {@link Constants.MVG_AVG_STEP}
as this number of values is removed at the end of this function
and we wait again till there are 30
*/
Angepasst
@SuppressLint("MissingPermission")
public void run() {
/*
How is this Working?
We are collecting GPS, Accelerometer, Gyroscope (and OpenBikeSensor) Data, those are updated as following;
- GPS (lat, lon, accuracy) roughly every 3 seconds
- accelerometer data (x,y,z) roughly 50 times a second
- gyroscope data (a,b,c) roughly every 3 seconds
Every Data Type is given asynchronously via its Callback function.
In order to synchronize the accelerometer interval the accelerometer interval is used as baseline.
*/
Änderungen:
- Tippfehler korrigiert:
ist → the accelerometer interval.
- Der alte 1./2.-Erklärungsteil entfernt (Struktur vereinfacht).
2. OBS-Lite-Distanzlogik im InsertHandler
Original
if (obsLiteEvent != null && lastLocation != null) {
double handleBarLength = SharedPref.Settings.Ride.OvertakeWidth.getHandlebarWidth(RecorderService.this);
double eventDistance = obsLiteEvent.getDistanceMeasurement().getDistance() * 100.0;
double realDistance = handleBarLength + eventDistance;
if (realDistance >= 150) {
Log.d(TAG, "Adding hidden Close Pass with TS: " + lastAccUpdate + " realLeftDistance: " + realDistance);
incidentLog.updateOrAddIncident(IncidentLogEntry.newBuilder().withBaseInformation(lastAccUpdate,lastLocation.getLatitude(),lastLocation.getLongitude()).withIncidentType(IncidentLogEntry.INCIDENT_TYPE.OBS_LITE).withDescription(getString(R.string.overtake_distance_left,((int)obsLiteEvent.getDistanceMeasurement().getDistance()))).withKey(5000).build());
} else {
Log.d(TAG, "Adding visible Close Pass with TS: " + lastAccUpdate + " realLeftDistance: " + realDistance);
incidentLog.updateOrAddIncident(IncidentLogEntry.newBuilder().withBaseInformation(lastAccUpdate,lastLocation.getLatitude(),lastLocation.getLongitude()).withIncidentType(IncidentLogEntry.INCIDENT_TYPE.CLOSE_PASS).withDescription(getString(R.string.overtake_distance_left,obsLiteEvent.getDistanceMeasurement().getDistance())).withKey(4000).build());
}
obsLiteEvent = null;
}
Angepasst
// OBS-Lite Ereignisse (Knopf) – Distanz ist bereits korrigiert (cm) in DistanceMeasurement.distance
if (obsLiteEvent != null && lastLocation != null) {
double realDistanceCm = obsLiteEvent.getDistanceMeasurement().getDistance(); // bereits in cm
if (realDistanceCm < 0) {
realDistanceCm = 0;
}
int realDistanceInt = (int) Math.round(realDistanceCm);
if (realDistanceCm >= 150) {
Log.d(TAG, "Adding hidden Close Pass with TS: " + lastAccUpdate + " realLeftDistance(cm): " + realDistanceCm);
incidentLog.updateOrAddIncident(
IncidentLogEntry.newBuilder()
.withBaseInformation(lastAccUpdate, lastLocation.getLatitude(), lastLocation.getLongitude())
.withIncidentType(IncidentLogEntry.INCIDENT_TYPE.OBS_LITE)
.withDescription(getString(R.string.overtake_distance_left, realDistanceInt))
.withKey(5000)
.build()
);
} else {
Log.d(TAG, "Adding visible Close Pass with TS: " + lastAccUpdate + " realLeftDistance(cm): " + realDistanceCm);
incidentLog.updateOrAddIncident(
IncidentLogEntry.newBuilder()
.withBaseInformation(lastAccUpdate, lastLocation.getLatitude(), lastLocation.getLongitude())
.withIncidentType(IncidentLogEntry.INCIDENT_TYPE.CLOSE_PASS)
.withDescription(getString(R.string.overtake_distance_left, realDistanceInt))
.withKey(4000)
.build()
);
}
obsLiteEvent = null;
}
Änderungen im Verhalten:
-
getDistance() wird jetzt als bereits korrigierte Distanz in cm interpretiert:
- Kein
* 100.0 mehr.
- Keine Addition von Lenkerbreite + 13 cm mehr.
- Negative Werte werden auf
0 gekappt.
- Beschreibungstext nutzt den aufgerundeten Integer-Wert
realDistanceInt.
- Logs sind explizit mit „(cm)“ gekennzeichnet.