Added map to lap recap
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
@@ -43,10 +43,12 @@ def _asset_path(relative_path: str) -> str:
|
|||||||
|
|
||||||
def run() -> None:
|
def run() -> None:
|
||||||
state: AppState = AppState()
|
state: AppState = AppState()
|
||||||
state.start_time = datetime.now()
|
state.start_time = datetime.now(timezone.utc)
|
||||||
|
|
||||||
dpgm.configure(
|
dpgm.configure(
|
||||||
user_agent="DataFlux/0.1 contact:h3cx@h3cx.dev", cache_dir="./.cache"
|
user_agent="DataFlux/0.1 contact:h3cx@h3cx.dev",
|
||||||
|
cache_dir="./.cache",
|
||||||
|
disk_cache_max_bytes=200_000_000,
|
||||||
)
|
)
|
||||||
|
|
||||||
dpg.create_context()
|
dpg.create_context()
|
||||||
@@ -56,7 +58,9 @@ def run() -> None:
|
|||||||
dpg.create_viewport(title="DataFlux", width=600, height=600)
|
dpg.create_viewport(title="DataFlux", width=600, height=600)
|
||||||
|
|
||||||
with dpg.font_registry():
|
with dpg.font_registry():
|
||||||
app_font = dpg.add_font(_asset_path("assets/fonts/Inter-Regular.ttf"), 18 * 2)
|
app_font = dpg.add_font(
|
||||||
|
_asset_path("assets/fonts/Inter-Regular.ttf"), 18 * 2
|
||||||
|
)
|
||||||
mono_font = dpg.add_font(
|
mono_font = dpg.add_font(
|
||||||
_asset_path("assets/fonts/JetBrainsMono-Regular.ttf"),
|
_asset_path("assets/fonts/JetBrainsMono-Regular.ttf"),
|
||||||
size=36,
|
size=36,
|
||||||
@@ -84,9 +88,7 @@ def run() -> None:
|
|||||||
state.telemetry_thread.start()
|
state.telemetry_thread.start()
|
||||||
|
|
||||||
state.ports_thread_running = True
|
state.ports_thread_running = True
|
||||||
state.ports_thread = Thread(
|
state.ports_thread = Thread()
|
||||||
target=dataflux.services.ports.ports_worker, args=(state,), daemon=True
|
|
||||||
)
|
|
||||||
state.ports_thread.start()
|
state.ports_thread.start()
|
||||||
|
|
||||||
ui_updater = dataflux.ui.worker.UiFrameUpdater()
|
ui_updater = dataflux.ui.worker.UiFrameUpdater()
|
||||||
|
|||||||
@@ -340,55 +340,83 @@ def build_windows(state: AppState) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
with dpg.group(tag=PAGE_LAP_RECAP, show=False):
|
with dpg.group(tag=PAGE_LAP_RECAP, show=False):
|
||||||
dpg.add_text("Lap Recap")
|
with dpg.group(horizontal=True):
|
||||||
dpg.add_separator()
|
with dpg.child_window(
|
||||||
|
# tag=SUB_PAGE_MAP,
|
||||||
with dpg.plot(label="Speed", height=250, width=-1, no_inputs=True):
|
width=1000,
|
||||||
dpg.add_plot_legend()
|
autosize_y=True,
|
||||||
dpg.add_plot_axis(
|
border=True,
|
||||||
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_SPEED_LR
|
show=True,
|
||||||
)
|
no_scrollbar=True,
|
||||||
y_axis_speed = dpg.add_plot_axis(
|
):
|
||||||
dpg.mvYAxis, label="Speed", tag=GRAPH_Y_AXIS_SPEED_LR
|
with dpg.plot(
|
||||||
)
|
label="Speed", height=250, width=-1, no_inputs=True
|
||||||
dpg.set_axis_limits(GRAPH_Y_AXIS_SPEED_LR, ymin=0, ymax=50)
|
):
|
||||||
dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=-30, ymax=0)
|
dpg.add_plot_legend()
|
||||||
dpg.add_line_series(
|
dpg.add_plot_axis(
|
||||||
[], [], parent=y_axis_speed, tag=GRAPH_SERIES_SPEED_LR
|
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_SPEED_LR
|
||||||
)
|
)
|
||||||
with dpg.plot(
|
y_axis_speed = dpg.add_plot_axis(
|
||||||
label="Battery Voltage",
|
dpg.mvYAxis, label="Speed", tag=GRAPH_Y_AXIS_SPEED_LR
|
||||||
height=250,
|
)
|
||||||
width=-1,
|
dpg.set_axis_limits(GRAPH_Y_AXIS_SPEED_LR, ymin=0, ymax=50)
|
||||||
no_inputs=True,
|
dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=-30, ymax=0)
|
||||||
):
|
dpg.add_line_series(
|
||||||
dpg.add_plot_legend()
|
[], [], parent=y_axis_speed, tag=GRAPH_SERIES_SPEED_LR
|
||||||
dpg.add_plot_axis(
|
)
|
||||||
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_VBAT_LR
|
with dpg.plot(
|
||||||
)
|
label="Battery Voltage",
|
||||||
y_axis_vbat = dpg.add_plot_axis(
|
height=250,
|
||||||
dpg.mvYAxis, label="Voltage", tag=GRAPH_Y_AXIS_VBAT_LR
|
width=-1,
|
||||||
)
|
no_inputs=True,
|
||||||
dpg.set_axis_limits(GRAPH_Y_AXIS_VBAT_LR, ymin=0, ymax=20)
|
):
|
||||||
dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=-30, ymax=0)
|
dpg.add_plot_legend()
|
||||||
dpg.add_line_series(
|
dpg.add_plot_axis(
|
||||||
[], [], parent=y_axis_vbat, tag=GRAPH_SERIES_VBAT_LR
|
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_VBAT_LR
|
||||||
)
|
)
|
||||||
with dpg.plot(
|
y_axis_vbat = dpg.add_plot_axis(
|
||||||
label="Engine Temp", height=250, width=-1, no_inputs=True
|
dpg.mvYAxis, label="Voltage", tag=GRAPH_Y_AXIS_VBAT_LR
|
||||||
):
|
)
|
||||||
dpg.add_plot_legend()
|
dpg.set_axis_limits(GRAPH_Y_AXIS_VBAT_LR, ymin=0, ymax=20)
|
||||||
dpg.add_plot_axis(
|
dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=-30, ymax=0)
|
||||||
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_TENG_LR
|
dpg.add_line_series(
|
||||||
)
|
[], [], parent=y_axis_vbat, tag=GRAPH_SERIES_VBAT_LR
|
||||||
y_axis_teng = dpg.add_plot_axis(
|
)
|
||||||
dpg.mvYAxis, label="Temperature", tag=GRAPH_Y_AXIS_TENG_LR
|
with dpg.plot(
|
||||||
)
|
label="Engine Temp", height=250, width=-1, no_inputs=True
|
||||||
dpg.set_axis_limits(GRAPH_Y_AXIS_TENG_LR, ymin=0, ymax=120)
|
):
|
||||||
dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=-30, ymax=0)
|
dpg.add_plot_legend()
|
||||||
dpg.add_line_series(
|
dpg.add_plot_axis(
|
||||||
[], [], parent=y_axis_teng, tag=GRAPH_SERIES_TENG_LR
|
dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_TENG_LR
|
||||||
)
|
)
|
||||||
|
y_axis_teng = dpg.add_plot_axis(
|
||||||
|
dpg.mvYAxis,
|
||||||
|
label="Temperature",
|
||||||
|
tag=GRAPH_Y_AXIS_TENG_LR,
|
||||||
|
)
|
||||||
|
dpg.set_axis_limits(GRAPH_Y_AXIS_TENG_LR, ymin=0, ymax=120)
|
||||||
|
dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=-30, ymax=0)
|
||||||
|
dpg.add_line_series(
|
||||||
|
[], [], parent=y_axis_teng, tag=GRAPH_SERIES_TENG_LR
|
||||||
|
)
|
||||||
|
with dpg.child_window(
|
||||||
|
# tag=SUB_PAGE_MAP,
|
||||||
|
autosize_x=True,
|
||||||
|
autosize_y=True,
|
||||||
|
border=True,
|
||||||
|
show=True,
|
||||||
|
no_scrollbar=True,
|
||||||
|
):
|
||||||
|
with dpgm.map_widget(
|
||||||
|
tag="recap_map",
|
||||||
|
center=(47.843834, 1.937727),
|
||||||
|
zoom=15,
|
||||||
|
width=-1,
|
||||||
|
height=-1,
|
||||||
|
):
|
||||||
|
dpgm.add_trajectory(tag="recap_trajectory", show=False)
|
||||||
|
# pass
|
||||||
|
# dpgm.add_trajectory("recap_trajectory")
|
||||||
|
|
||||||
with dpg.group(tag=PAGE_SERIAL_CONSOLE, show=False):
|
with dpg.group(tag=PAGE_SERIAL_CONSOLE, show=False):
|
||||||
with dpg.child_window(
|
with dpg.child_window(
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class UiFrameUpdater:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
flash_until = max(flash_until, now + float(duration))
|
flash_until = max(flash_until, now + float(duration))
|
||||||
except (TypeError, ValueError):
|
except TypeError, ValueError:
|
||||||
continue
|
continue
|
||||||
dpg.bind_item_theme(tag, THEME_STATUS_CONNECTED_BRIGHT)
|
dpg.bind_item_theme(tag, THEME_STATUS_CONNECTED_BRIGHT)
|
||||||
|
|
||||||
@@ -167,6 +167,13 @@ class UiFrameUpdater:
|
|||||||
dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=axis_min, ymax=axis_max)
|
dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=axis_min, ymax=axis_max)
|
||||||
dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=axis_min, ymax=axis_max)
|
dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=axis_min, ymax=axis_max)
|
||||||
dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=axis_min, ymax=axis_max)
|
dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=axis_min, ymax=axis_max)
|
||||||
|
dpgm.update_trajectory(
|
||||||
|
tag="recap_trajectory",
|
||||||
|
lats=state.lap_recap_buffers.lat,
|
||||||
|
lons=state.lap_recap_buffers.lng,
|
||||||
|
map_tag="recap_map",
|
||||||
|
)
|
||||||
|
dpgm.set_overlay_show(tag="recap_trajectory", show=True, map_tag="recap_map")
|
||||||
|
|
||||||
def _update_live_telemetry(self, state: AppState) -> None:
|
def _update_live_telemetry(self, state: AppState) -> None:
|
||||||
if not (state.lora_thread_running and state.telemetry_valid):
|
if not (state.lora_thread_running and state.telemetry_valid):
|
||||||
@@ -185,7 +192,7 @@ class UiFrameUpdater:
|
|||||||
veh_speed = float(state.latest_telemetry["speed"])
|
veh_speed = float(state.latest_telemetry["speed"])
|
||||||
vbat = float(state.latest_telemetry["vbat"])
|
vbat = float(state.latest_telemetry["vbat"])
|
||||||
teng = float(state.latest_telemetry["teng"])
|
teng = float(state.latest_telemetry["teng"])
|
||||||
except (KeyError, TypeError, ValueError):
|
except KeyError, TypeError, ValueError:
|
||||||
state.telemetry_valid = False
|
state.telemetry_valid = False
|
||||||
self._write_no_data()
|
self._write_no_data()
|
||||||
return
|
return
|
||||||
@@ -244,12 +251,12 @@ class UiFrameUpdater:
|
|||||||
with state.lock:
|
with state.lock:
|
||||||
try:
|
try:
|
||||||
lat = float(state.latest_telemetry.get("lat", DEFAULT_LAT))
|
lat = float(state.latest_telemetry.get("lat", DEFAULT_LAT))
|
||||||
except (TypeError, ValueError):
|
except TypeError, ValueError:
|
||||||
lat = DEFAULT_LAT
|
lat = DEFAULT_LAT
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lon = float(state.latest_telemetry.get("lng", DEFAULT_LNG))
|
lon = float(state.latest_telemetry.get("lng", DEFAULT_LNG))
|
||||||
except (TypeError, ValueError):
|
except TypeError, ValueError:
|
||||||
lon = DEFAULT_LNG
|
lon = DEFAULT_LNG
|
||||||
try:
|
try:
|
||||||
dpgm.set_center(lat=lat, lon=lon, map_tag="live_map")
|
dpgm.set_center(lat=lat, lon=lon, map_tag="live_map")
|
||||||
@@ -283,7 +290,7 @@ class UiFrameUpdater:
|
|||||||
try:
|
try:
|
||||||
lat = float(state.latest_telemetry["lat"])
|
lat = float(state.latest_telemetry["lat"])
|
||||||
lon = float(state.latest_telemetry["lng"])
|
lon = float(state.latest_telemetry["lng"])
|
||||||
except (KeyError, TypeError, ValueError):
|
except KeyError, TypeError, ValueError:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user