mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-29 19:03:59 +08:00
patches
This commit is contained in:
@@ -311,11 +311,14 @@ sync_worktree() {
|
||||
"msgq_repo/msgq/visionipc/visionipc_pyx.so"
|
||||
"rednose_repo/rednose/helpers/ekf_sym_pyx.so"
|
||||
"selfdrive/modeld/models/commonmodel_pyx.so"
|
||||
"selfdrive/pandad/libcan_list_to_can_capnp.a"
|
||||
"selfdrive/pandad/pandad_api_impl.so"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.dylib"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.dylib"
|
||||
"third_party/libjson11.a"
|
||||
"third_party/libkaitai.a"
|
||||
)
|
||||
|
||||
@@ -64,6 +64,14 @@ runtime_artifacts=(
|
||||
"msgq/ipc_pyx.so"
|
||||
"msgq/visionipc/visionipc_pyx.so"
|
||||
"common/transformations/transformations.so"
|
||||
"selfdrive/pandad/pandad_api_impl.so"
|
||||
"selfdrive/pandad/pandad_api_impl.o"
|
||||
"selfdrive/pandad/can_list_to_can_capnp.o"
|
||||
"selfdrive/pandad/libcan_list_to_can_capnp.a"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.dylib"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.dylib"
|
||||
)
|
||||
|
||||
collect_tracked_dirty() {
|
||||
@@ -181,16 +189,27 @@ prepare_msgq_host_artifacts() {
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_pandad_host_artifacts() {
|
||||
remove_if_elf "selfdrive/pandad/pandad_api_impl.so"
|
||||
remove_if_elf "selfdrive/pandad/pandad_api_impl.o"
|
||||
remove_if_elf "selfdrive/pandad/can_list_to_can_capnp.o"
|
||||
|
||||
# Host builds always regenerate this small archive locally. Device-built
|
||||
# variants are not reusable across platforms and can poison the link step.
|
||||
rm -f "${ROOT_DIR}/selfdrive/pandad/libcan_list_to_can_capnp.a"
|
||||
}
|
||||
|
||||
python_ui_runtime_ok() {
|
||||
"${PY_BIN}" - <<'PY'
|
||||
import pyray # noqa: F401
|
||||
import openpilot.common.params_pyx # noqa: F401
|
||||
import openpilot.common.transformations.transformations # noqa: F401
|
||||
import openpilot.selfdrive.pandad.pandad_api_impl # noqa: F401
|
||||
import msgq.ipc_pyx # noqa: F401
|
||||
import msgq.visionipc.visionipc_pyx # noqa: F401
|
||||
import openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
import openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
PY
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]]
|
||||
}
|
||||
|
||||
sync_deps() {
|
||||
@@ -253,17 +272,21 @@ if ! python_ui_runtime_ok >/dev/null 2>&1; then
|
||||
sync_raylib
|
||||
prepare_common_host_artifacts
|
||||
prepare_msgq_host_artifacts
|
||||
prepare_pandad_host_artifacts
|
||||
remove_if_elf "common/params_pyx.so"
|
||||
remove_if_elf "common/transformations/transformations.so"
|
||||
remove_if_elf "msgq/ipc_pyx.so"
|
||||
remove_if_elf "msgq/visionipc/visionipc_pyx.so"
|
||||
remove_if_elf "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
remove_if_elf "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
|
||||
run_scons "${jobs}" common/params_pyx.so common/transformations/transformations.so
|
||||
# Building the Cython module pulls in the platform-specific acados solver
|
||||
# library via SCons dependencies, so the host path does not need to name the
|
||||
# solver shared library extension explicitly.
|
||||
run_scons "${jobs}" \
|
||||
selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so \
|
||||
selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so \
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so \
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so
|
||||
(
|
||||
cd "${ROOT_DIR}/msgq_repo"
|
||||
local_scons_bin="${ROOT_DIR}/.venv/bin/scons"
|
||||
|
||||
@@ -64,6 +64,14 @@ runtime_artifacts=(
|
||||
"msgq/ipc_pyx.so"
|
||||
"msgq/visionipc/visionipc_pyx.so"
|
||||
"common/transformations/transformations.so"
|
||||
"selfdrive/pandad/pandad_api_impl.so"
|
||||
"selfdrive/pandad/pandad_api_impl.o"
|
||||
"selfdrive/pandad/can_list_to_can_capnp.o"
|
||||
"selfdrive/pandad/libcan_list_to_can_capnp.a"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.dylib"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
"selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.dylib"
|
||||
)
|
||||
|
||||
collect_tracked_dirty() {
|
||||
@@ -181,16 +189,27 @@ prepare_msgq_host_artifacts() {
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_pandad_host_artifacts() {
|
||||
remove_if_elf "selfdrive/pandad/pandad_api_impl.so"
|
||||
remove_if_elf "selfdrive/pandad/pandad_api_impl.o"
|
||||
remove_if_elf "selfdrive/pandad/can_list_to_can_capnp.o"
|
||||
|
||||
# Host builds always regenerate this small archive locally. Device-built
|
||||
# variants are not reusable across platforms and can poison the link step.
|
||||
rm -f "${ROOT_DIR}/selfdrive/pandad/libcan_list_to_can_capnp.a"
|
||||
}
|
||||
|
||||
python_ui_runtime_ok() {
|
||||
"${PY_BIN}" - <<'PY'
|
||||
import pyray # noqa: F401
|
||||
import openpilot.common.params_pyx # noqa: F401
|
||||
import openpilot.common.transformations.transformations # noqa: F401
|
||||
import openpilot.selfdrive.pandad.pandad_api_impl # noqa: F401
|
||||
import msgq.ipc_pyx # noqa: F401
|
||||
import msgq.visionipc.visionipc_pyx # noqa: F401
|
||||
import openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
import openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
PY
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]]
|
||||
}
|
||||
|
||||
sync_deps() {
|
||||
@@ -253,17 +272,21 @@ if ! python_ui_runtime_ok >/dev/null 2>&1; then
|
||||
sync_raylib
|
||||
prepare_common_host_artifacts
|
||||
prepare_msgq_host_artifacts
|
||||
prepare_pandad_host_artifacts
|
||||
remove_if_elf "common/params_pyx.so"
|
||||
remove_if_elf "common/transformations/transformations.so"
|
||||
remove_if_elf "msgq/ipc_pyx.so"
|
||||
remove_if_elf "msgq/visionipc/visionipc_pyx.so"
|
||||
remove_if_elf "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
remove_if_elf "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
|
||||
run_scons "${jobs}" common/params_pyx.so common/transformations/transformations.so
|
||||
# Building the Cython module pulls in the platform-specific acados solver
|
||||
# library via SCons dependencies, so the host path does not need to name the
|
||||
# solver shared library extension explicitly.
|
||||
run_scons "${jobs}" \
|
||||
selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so \
|
||||
selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so \
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so \
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so
|
||||
(
|
||||
cd "${ROOT_DIR}/msgq_repo"
|
||||
local_scons_bin="${ROOT_DIR}/.venv/bin/scons"
|
||||
|
||||
@@ -6,7 +6,6 @@ from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout
|
||||
from openpilot.selfdrive.ui.mici.layouts.settings.settings import SettingsLayout
|
||||
from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts
|
||||
from openpilot.selfdrive.ui.mici.onroad.augmented_road_view import AugmentedRoadView
|
||||
from openpilot.selfdrive.ui.mici.onroad.driver_camera_dialog import DriverCameraDialog
|
||||
from openpilot.selfdrive.ui.ui_state import device, ui_state
|
||||
from openpilot.selfdrive.ui.mici.layouts.onboarding import OnboardingWindow
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
@@ -15,7 +14,6 @@ from openpilot.system.ui.lib.application import gui_app
|
||||
|
||||
|
||||
ONROAD_DELAY = 2.5 # seconds
|
||||
REVERSE_DRIVER_CAMERA_DELAY = 0.5 # seconds
|
||||
|
||||
|
||||
class MainState(IntEnum):
|
||||
@@ -33,8 +31,6 @@ class MiciMainLayout(Widget):
|
||||
self._prev_onroad = False
|
||||
self._prev_standstill = False
|
||||
self._onroad_time_delay: float | None = None
|
||||
self._reverse_started_time: float | None = None
|
||||
self._reverse_driver_camera: DriverCameraDialog | None = None
|
||||
self._setup = False
|
||||
|
||||
# Initialize widgets
|
||||
@@ -65,7 +61,6 @@ class MiciMainLayout(Widget):
|
||||
|
||||
# Set callbacks
|
||||
self._setup_callbacks()
|
||||
gui_app.set_modal_overlay_tick(self._modal_overlay_tick)
|
||||
|
||||
# Skip onboarding on desktop; keep normal flow on device.
|
||||
self._onboarding_window = None
|
||||
@@ -89,8 +84,6 @@ class MiciMainLayout(Widget):
|
||||
if self._current_mode is None:
|
||||
self._set_mode(MainState.MAIN)
|
||||
|
||||
self._update_reverse_driver_camera()
|
||||
|
||||
if not self._setup:
|
||||
if self._alerts_layout.active_alerts() > 0:
|
||||
self._scroller.scroll_to(self._alerts_layout.rect.x)
|
||||
@@ -115,8 +108,6 @@ class MiciMainLayout(Widget):
|
||||
self._current_mode = mode
|
||||
|
||||
def _handle_transitions(self):
|
||||
self._update_reverse_driver_camera()
|
||||
|
||||
if ui_state.started != self._prev_onroad:
|
||||
self._prev_onroad = ui_state.started
|
||||
|
||||
@@ -159,38 +150,3 @@ class MiciMainLayout(Widget):
|
||||
user_bookmark = messaging.new_message('bookmarkButton')
|
||||
user_bookmark.valid = True
|
||||
self._pm.send('bookmarkButton', user_bookmark)
|
||||
|
||||
def _modal_overlay_tick(self):
|
||||
self._update_reverse_driver_camera()
|
||||
|
||||
def _update_reverse_driver_camera(self):
|
||||
current_overlay = gui_app._modal_overlay.overlay
|
||||
reverse_overlay = self._reverse_driver_camera
|
||||
should_show = ui_state.started and ui_state.params.get_bool("DriverCamera") and self._onroad_layout.is_in_reverse()
|
||||
|
||||
if not should_show:
|
||||
self._reverse_started_time = None
|
||||
if current_overlay is reverse_overlay:
|
||||
gui_app.set_modal_overlay(None)
|
||||
self._reverse_driver_camera = None
|
||||
return
|
||||
|
||||
now = rl.get_time()
|
||||
if self._reverse_started_time is None:
|
||||
self._reverse_started_time = now
|
||||
return
|
||||
|
||||
if now - self._reverse_started_time < REVERSE_DRIVER_CAMERA_DELAY:
|
||||
return
|
||||
|
||||
if current_overlay is reverse_overlay:
|
||||
return
|
||||
|
||||
if current_overlay is not None:
|
||||
return
|
||||
|
||||
if reverse_overlay is None:
|
||||
self._reverse_driver_camera = DriverCameraDialog(no_escape=True)
|
||||
reverse_overlay = self._reverse_driver_camera
|
||||
|
||||
gui_app.set_modal_overlay(reverse_overlay)
|
||||
|
||||
@@ -2,6 +2,7 @@ import time
|
||||
import numpy as np
|
||||
import pyray as rl
|
||||
from cereal import messaging, car, log
|
||||
from opendbc.car import structs
|
||||
from msgq.visionipc import VisionStreamType
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
@@ -32,6 +33,7 @@ CALIBRATED = log.LiveCalibrationData.Status.calibrated
|
||||
ROAD_CAM = VisionStreamType.VISION_STREAM_ROAD
|
||||
WIDE_CAM = VisionStreamType.VISION_STREAM_WIDE_ROAD
|
||||
DRIVER_CAM = VisionStreamType.VISION_STREAM_DRIVER
|
||||
GEAR_SHIFTER_REVERSE = structs.CarState.GearShifter.reverse
|
||||
DEFAULT_DEVICE_CAMERA = DEVICE_CAMERAS["tici", "ar0231"]
|
||||
|
||||
CAMERA_VIEW_AUTO = 0
|
||||
@@ -49,6 +51,7 @@ WIDE_CAM_MAX_SPEED = 10.0 # m/s
|
||||
ROAD_CAM_MIN_SPEED = 15.0 # m/s
|
||||
|
||||
CAM_Y_OFFSET = 20
|
||||
REVERSE_DRIVER_CAMERA_DELAY_FRAMES = max(1, int(round(gui_app.target_fps * 0.5)))
|
||||
|
||||
|
||||
class BookmarkIcon(Widget):
|
||||
@@ -367,6 +370,13 @@ class StandstillTimerOverlay:
|
||||
rl.draw_text_ex(font, text, shadow_pos, font_size, 0, rl.Color(0, 0, 0, 170))
|
||||
rl.draw_text_ex(font, text, text_pos, font_size, 0, color)
|
||||
|
||||
@staticmethod
|
||||
def _fit_font_size(font: rl.Font, text: str, initial_size: int, max_width: float, minimum_size: int) -> int:
|
||||
font_size = max(initial_size, minimum_size)
|
||||
while font_size > minimum_size and rl.measure_text_ex(font, text, font_size, 0).x > max_width:
|
||||
font_size -= 2
|
||||
return font_size
|
||||
|
||||
def render(self, rect: rl.Rectangle, in_reverse: bool) -> bool:
|
||||
self._update_state(in_reverse)
|
||||
if self._standstill_duration == 0:
|
||||
@@ -374,8 +384,11 @@ class StandstillTimerOverlay:
|
||||
|
||||
minute_text, second_text = self._format_duration_text(self._standstill_duration)
|
||||
duration_color = self._get_duration_color()
|
||||
self._draw_centered_text(rect, minute_text, 210, self._font_bold, 176, duration_color)
|
||||
self._draw_centered_text(rect, second_text, 290, self._font_medium, 66, rl.Color(255, 255, 255, 242))
|
||||
max_text_width = max(rect.width - 36, 120)
|
||||
minute_font_size = self._fit_font_size(self._font_bold, minute_text, int(rect.height * 0.34), max_text_width, 28)
|
||||
second_font_size = self._fit_font_size(self._font_medium, second_text, int(rect.height * 0.15), max_text_width, 16)
|
||||
self._draw_centered_text(rect, minute_text, rect.height * 0.42, self._font_bold, minute_font_size, duration_color)
|
||||
self._draw_centered_text(rect, second_text, rect.height * 0.62, self._font_medium, second_font_size, rl.Color(255, 255, 255, 242))
|
||||
return True
|
||||
|
||||
|
||||
@@ -395,6 +408,8 @@ class AugmentedRoadView(CameraView):
|
||||
self._cached_matrix: np.ndarray | None = None
|
||||
self._content_rect = rl.Rectangle()
|
||||
self._last_click_time = 0.0
|
||||
self._reverse_driver_camera_frames = 0
|
||||
self._reverse_driver_camera_active = False
|
||||
|
||||
# Bookmark icon with swipe gesture
|
||||
self._bookmark_icon = BookmarkIcon(bookmark_callback)
|
||||
@@ -421,6 +436,17 @@ class AugmentedRoadView(CameraView):
|
||||
def _controls_ready() -> bool:
|
||||
return ui_state.sm.recv_frame["selfdriveState"] >= ui_state.started_frame
|
||||
|
||||
def _update_reverse_driver_camera_state(self) -> bool:
|
||||
should_force_driver = ui_state.started and ui_state.params.get_bool("DriverCamera") and self._is_in_reverse()
|
||||
if not should_force_driver:
|
||||
self._reverse_driver_camera_frames = 0
|
||||
self._reverse_driver_camera_active = False
|
||||
return False
|
||||
|
||||
self._reverse_driver_camera_frames = min(self._reverse_driver_camera_frames + 1, REVERSE_DRIVER_CAMERA_DELAY_FRAMES)
|
||||
self._reverse_driver_camera_active = self._reverse_driver_camera_frames >= REVERSE_DRIVER_CAMERA_DELAY_FRAMES
|
||||
return self._reverse_driver_camera_active
|
||||
|
||||
def is_swiping_left(self) -> bool:
|
||||
"""Check if currently swiping left (for scroller to disable)."""
|
||||
return self._bookmark_icon.is_swiping_left()
|
||||
@@ -503,7 +529,7 @@ class AugmentedRoadView(CameraView):
|
||||
)
|
||||
self._driver_state_renderer.set_should_draw(should_draw_dmoji)
|
||||
self._driver_state_renderer.set_position(self._rect.x + 16, self._rect.y + 10)
|
||||
if not in_reverse:
|
||||
if is_driver_stream or not in_reverse:
|
||||
self._driver_state_renderer.render()
|
||||
|
||||
self._hud_renderer.set_can_draw_top_icons((not in_reverse) and (not is_driver_stream) and (alert_to_render is None))
|
||||
@@ -529,7 +555,7 @@ class AugmentedRoadView(CameraView):
|
||||
# Use self._content_rect for positioning within camera bounds
|
||||
if not in_reverse and not is_driver_stream:
|
||||
self._confidence_ball.render(self.rect)
|
||||
if not in_reverse:
|
||||
if is_driver_stream or not in_reverse:
|
||||
self._draw_border()
|
||||
|
||||
self._bookmark_icon.render(self.rect)
|
||||
@@ -557,21 +583,33 @@ class AugmentedRoadView(CameraView):
|
||||
|
||||
@staticmethod
|
||||
def _is_in_reverse() -> bool:
|
||||
if ui_state.sm.recv_frame["carState"] < ui_state.started_frame:
|
||||
return False
|
||||
|
||||
try:
|
||||
gear = ui_state.sm["carState"].gearShifter
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
if gear == GEAR_SHIFTER_REVERSE:
|
||||
return True
|
||||
|
||||
reverse_enum = getattr(car.CarState.GearShifter, "reverse", None)
|
||||
if reverse_enum is not None and gear == reverse_enum:
|
||||
return True
|
||||
|
||||
return str(gear).lower().endswith("reverse")
|
||||
return str(gear).split(".")[-1].lower() == "reverse"
|
||||
|
||||
def is_in_reverse(self) -> bool:
|
||||
return self._is_in_reverse()
|
||||
|
||||
def _switch_stream_if_needed(self, sm):
|
||||
if self._update_reverse_driver_camera_state():
|
||||
target = DRIVER_CAM
|
||||
if self.stream_type != target:
|
||||
self.switch_stream(target)
|
||||
return
|
||||
|
||||
camera_view = ui_state.params.get_int("CameraView", return_default=True, default=CAMERA_VIEW_WIDE)
|
||||
if camera_view not in (CAMERA_VIEW_AUTO, CAMERA_VIEW_DRIVER, CAMERA_VIEW_STANDARD, CAMERA_VIEW_WIDE):
|
||||
camera_view = CAMERA_VIEW_WIDE
|
||||
|
||||
Reference in New Issue
Block a user