fix: BUG-22 smooth GPS-derived speeds in trip max (trailing window)
This commit is contained in:
+26
-1
@@ -7,6 +7,7 @@ GPS_MOTION_METERS = 8
|
||||
MIN_GPS_MOTION_SAMPLES = 3
|
||||
MAX_GPS_SAMPLE_GAP_SECONDS = 30
|
||||
MAX_PLAUSIBLE_SPEED_KMH = 220
|
||||
GPS_SPEED_WINDOW = 6 # ~30 s at 5 s logging — smooths GPS position jitter
|
||||
EARTH_RADIUS_KM = 6371.0088
|
||||
|
||||
|
||||
@@ -180,6 +181,7 @@ def build_trip_summaries(raw_rows):
|
||||
distance_km = 0
|
||||
segment_speeds = []
|
||||
obd_speeds = []
|
||||
gps_speeds = []
|
||||
has_obd_motion = any(event["obd"] for event in events)
|
||||
for previous, row in zip(trip_rows, trip_rows[1:]):
|
||||
segment_km, segment_speed = _segment(row, previous)
|
||||
@@ -189,6 +191,29 @@ def build_trip_summaries(raw_rows):
|
||||
segment_speeds.append(segment_speed)
|
||||
if row["speed"] > 0:
|
||||
obd_speeds.append(row["speed"])
|
||||
# Smoothed GPS-derived speeds for the max — a trailing ~30s window
|
||||
# averages out GPS position jitter (raw 5s segments can spike).
|
||||
for index in range(1, len(trip_rows)):
|
||||
if trip_rows[index]["speed"] > 0:
|
||||
continue # OBD present here — already counted in obd_speeds
|
||||
window_start = max(0, index - GPS_SPEED_WINDOW)
|
||||
start_row = trip_rows[window_start]
|
||||
end_row = trip_rows[index]
|
||||
if (
|
||||
start_row["latitude"] is not None
|
||||
and end_row["latitude"] is not None
|
||||
):
|
||||
seconds = (
|
||||
end_row["datetime"] - start_row["datetime"]
|
||||
).total_seconds()
|
||||
window_km = haversine_km(
|
||||
(start_row["latitude"], start_row["longitude"]),
|
||||
(end_row["latitude"], end_row["longitude"]),
|
||||
)
|
||||
if seconds > 0 and window_km * 1000 >= GPS_MOTION_METERS:
|
||||
window_speed = window_km / seconds * 3600
|
||||
if window_speed <= MAX_PLAUSIBLE_SPEED_KMH:
|
||||
gps_speeds.append(window_speed)
|
||||
|
||||
start = trip_rows[0]
|
||||
end = trip_rows[-1]
|
||||
@@ -227,7 +252,7 @@ def build_trip_summaries(raw_rows):
|
||||
distance_km / duration_seconds * 3600, 1
|
||||
) if duration_seconds else 0,
|
||||
"max_speed_kmh": round(
|
||||
max((obd_speeds + segment_speeds) or [0]), 1
|
||||
max((obd_speeds + gps_speeds) or [0]), 1
|
||||
),
|
||||
"start_odometer": next((r["odometer"] for r in trip_rows if r.get("odometer")), None),
|
||||
"end_odometer": next((r["odometer"] for r in reversed(trip_rows) if r.get("odometer")), None),
|
||||
|
||||
Reference in New Issue
Block a user