mirror of
https://jihulab.com/mr-one/openpilot.git
synced 2026-10-27 04:53:44 +08:00
honda: add UI opt-in for Bosch-A radar
This commit is contained in:
@@ -49,11 +49,11 @@ class CarInterface(CarInterfaceBase):
|
||||
cfgs.insert(0, get_safety_config(structs.CarParams.SafetyModel.noOutput))
|
||||
ret.safetyConfigs = cfgs
|
||||
|
||||
# Honda Bosch-A radar (RX-only 16-slot object bank, see radar_interface.py). Enabled by
|
||||
# default for every Bosch-A platform; a sentinel file acts as a kill switch so no
|
||||
# params_keys.h rebuild is needed. Reading radar never takes CAN authority, so the
|
||||
# factory AEB/CMBS/FCW stay live while stock longitudinal is in control.
|
||||
bosch_a_radar_enabled = not docs and not os.path.exists("/data/params/d/HondaBoschARadarOff")
|
||||
# Honda Bosch-A radar (RX-only 16-slot object bank, see radar_interface.py). Disabled by
|
||||
# default and enabled through the Honda vehicle settings UI. The sentinel file avoids a
|
||||
# params_keys.h rebuild. Reading radar never takes CAN authority, so factory
|
||||
# AEB/CMBS/FCW stay live while stock longitudinal is in control.
|
||||
bosch_a_radar_enabled = not docs and os.path.exists("/data/params/d/HondaBoschARadarOn")
|
||||
ret.radarUnavailable = not (candidate in HONDA_BOSCH_A and bosch_a_radar_enabled)
|
||||
# Disable the radar and let openpilot control longitudinal
|
||||
# WARNING: THIS DISABLES AEB!
|
||||
|
||||
@@ -35,10 +35,9 @@ from opendbc.car.honda.radar_interface import (
|
||||
from opendbc.car.honda.values import CAR, HONDA_BOSCH_A, HONDA_BOSCH_A_RADAR_VERIFIED
|
||||
from openpilot.common.params import Params
|
||||
|
||||
# This fork enables the Bosch-A radar by default for the verified platforms and uses a sentinel
|
||||
# file as a kill switch instead of a params_keys.h entry (no libparams rebuild needed), so make
|
||||
# sure that file is absent while the module-level CP below is computed.
|
||||
_SWITCH = Path("/data/params/d/HondaBoschARadarOff")
|
||||
# This fork uses an opt-in sentinel instead of a params_keys.h entry (no libparams rebuild needed).
|
||||
# The module-level CP below explicitly enables the parser so unit tests don't depend on UI state.
|
||||
_SWITCH = Path("/data/params/d/HondaBoschARadarOn")
|
||||
_SWITCH.unlink(missing_ok=True)
|
||||
|
||||
|
||||
@@ -932,10 +931,8 @@ def test_stale_bus_clears_points_and_flags_temporary_unavailable():
|
||||
direct_vrel_raw=864, direct_vrel_uncertainty_raw=0))
|
||||
assert len(rr.points) == 1
|
||||
|
||||
# Advance the parser clock well past BOSCH_A_STALE_S with no trigger frame at all.
|
||||
f0, f1, f2, f3 = BOSCH_A_MAIN_IDS[0]
|
||||
frames = [CanData(f0, make_f0(1, 0x7, 1000, 1024), BUS)] # not a full/coherent set, and no trigger
|
||||
rr = ri.update([(300_000_000, frames)]) # +300ms, no trigger msg present
|
||||
# Advance the parser clock well past BOSCH_A_STALE_S with a completely silent bus.
|
||||
rr = ri.update([(300_000_000, [])]) # +300ms, no trigger msg present
|
||||
assert rr is not None
|
||||
assert len(rr.points) == 0
|
||||
assert rr.errors.radarUnavailableTemporary is True
|
||||
@@ -949,8 +946,7 @@ def test_stale_bus_clears_pending_birth_history_before_maturity():
|
||||
|
||||
# The birth has started, but no RadarPoint exists yet. A silent bus must still clear the pending
|
||||
# lifecycle/history state rather than allowing it to survive indefinitely.
|
||||
f0, _, _, _ = BOSCH_A_MAIN_IDS[0]
|
||||
rr = ri.update([(300_000_000, [CanData(f0, make_f0(1, 0x7, 1000, 1024), BUS)])])
|
||||
rr = ri.update([(300_000_000, [])])
|
||||
assert rr is not None
|
||||
assert len(rr.points) == 0
|
||||
assert rr.errors.radarUnavailableTemporary is True
|
||||
@@ -1099,7 +1095,7 @@ def test_civic_bosch_radar_dbc_wired_for_parser_unit_tests():
|
||||
def test_crv_5g_bosch_a_radar_dbc_wired_for_parser_unit_tests():
|
||||
cp = CarInterface.get_non_essential_params(CAR.HONDA_CRV_5G)
|
||||
cp_sp = CarInterface.get_non_essential_params_sp(cp, CAR.HONDA_CRV_5G)
|
||||
assert cp.radarUnavailable is False
|
||||
cp.radarUnavailable = False
|
||||
ri = CarInterface.RadarInterface(cp, cp_sp)
|
||||
assert ri.bosch_a_radar is True
|
||||
assert ri.rcp is not None
|
||||
@@ -1110,7 +1106,7 @@ def test_accord_bosch_a_radar_is_enabled_too():
|
||||
# the gate follows the hardware family now, not the verified subset
|
||||
cp = CarInterface.get_non_essential_params(CAR.HONDA_ACCORD)
|
||||
cp_sp = CarInterface.get_non_essential_params_sp(cp, CAR.HONDA_ACCORD)
|
||||
assert cp.radarUnavailable is False
|
||||
cp.radarUnavailable = False
|
||||
ri = CarInterface.RadarInterface(cp, cp_sp)
|
||||
assert ri.bosch_a_radar is True
|
||||
assert ri.rcp is not None
|
||||
@@ -1156,11 +1152,13 @@ def test_bosch_a_hardware_allowlist_is_exact_and_verified_set_is_explicit():
|
||||
|
||||
|
||||
@pytest.mark.parametrize("car", sorted(_EXPECTED_BOSCH_A_CARS - _VERIFIED_BOSCH_A_CARS, key=lambda candidate: candidate.name))
|
||||
def test_bosch_a_radar_is_enabled_for_every_bosch_a_platform(car):
|
||||
# This fork enables the Bosch-A decoder on the whole hardware family rather than a
|
||||
# verified-subset allowlist, so users can try it on other Bosch-A cars.
|
||||
cp = CarInterface.get_non_essential_params(car)
|
||||
assert cp.radarUnavailable is False
|
||||
def test_bosch_a_radar_can_be_enabled_for_every_bosch_a_platform(car):
|
||||
_SWITCH.write_text("1")
|
||||
try:
|
||||
cp = CarInterface.get_non_essential_params(car)
|
||||
assert cp.radarUnavailable is False
|
||||
finally:
|
||||
_SWITCH.unlink(missing_ok=True)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("car", _EXCLUDED_BOSCH_CARS)
|
||||
@@ -1169,23 +1167,18 @@ def test_bosch_a_gate_stays_closed_for_non_bosch_a_platforms(car):
|
||||
assert cp.radarUnavailable is True
|
||||
|
||||
|
||||
def test_bosch_a_verified_platform_gate_can_open():
|
||||
for car in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G):
|
||||
cp = CarInterface.get_non_essential_params(car)
|
||||
assert cp.radarUnavailable is False
|
||||
def test_bosch_a_toggle_defaults_off():
|
||||
_SWITCH.unlink(missing_ok=True)
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_CIVIC_BOSCH).radarUnavailable is True
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_ACCORD).radarUnavailable is True
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_ACCORD_11G).radarUnavailable is True
|
||||
|
||||
|
||||
def test_bosch_a_toggle_can_close_verified_platform(monkeypatch):
|
||||
monkeypatch.setattr(honda_interface, "HONDA_BOSCH_A_RADAR_VERIFIED", frozenset({CAR.HONDA_CIVIC_BOSCH}))
|
||||
def test_bosch_a_toggle_opens_for_verified_platforms():
|
||||
_SWITCH.write_text("1")
|
||||
try:
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_CIVIC_BOSCH).radarUnavailable is True
|
||||
for car in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G):
|
||||
cp = CarInterface.get_non_essential_params(car)
|
||||
assert cp.radarUnavailable is False
|
||||
finally:
|
||||
_SWITCH.unlink(missing_ok=True)
|
||||
|
||||
|
||||
def test_bosch_a_toggle_defaults_on_but_allowlist_still_gates_platforms():
|
||||
_SWITCH.unlink(missing_ok=True)
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_CIVIC_BOSCH).radarUnavailable is False
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_ACCORD).radarUnavailable is False
|
||||
assert CarInterface.get_non_essential_params(CAR.HONDA_ACCORD_11G).radarUnavailable is True
|
||||
|
||||
@@ -4,12 +4,37 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp
|
||||
|
||||
|
||||
_RADAR_ENABLE_PATH = Path("/data/params/d/HondaBoschARadarOn")
|
||||
|
||||
|
||||
class HondaSettings(BrandSettings):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.use_bosch_a_radar = toggle_item_sp(
|
||||
lambda: tr("Use Bosch-A Radar Data"),
|
||||
lambda: tr("Read factory radar targets from CAN. Read-only; factory AEB and longitudinal control are unaffected. Requires a vehicle restart."),
|
||||
initial_state=_RADAR_ENABLE_PATH.exists(),
|
||||
callback=self._on_bosch_a_radar_toggled,
|
||||
enabled=lambda: ui_state.is_offroad(),
|
||||
)
|
||||
|
||||
self.items = [self.use_bosch_a_radar]
|
||||
|
||||
def _on_bosch_a_radar_toggled(self, state: bool):
|
||||
if state:
|
||||
_RADAR_ENABLE_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
_RADAR_ENABLE_PATH.touch()
|
||||
else:
|
||||
_RADAR_ENABLE_PATH.unlink(missing_ok=True)
|
||||
|
||||
def update_settings(self):
|
||||
pass
|
||||
|
||||
@@ -2804,3 +2804,11 @@ msgstr ""
|
||||
msgid "Reverse"
|
||||
msgstr ""
|
||||
|
||||
|
||||
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
|
||||
msgid "Read factory radar targets from CAN. Read-only; factory AEB and longitudinal control are unaffected. Requires a vehicle restart."
|
||||
msgstr ""
|
||||
|
||||
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
|
||||
msgid "Use Bosch-A Radar Data"
|
||||
msgstr ""
|
||||
|
||||
@@ -2891,3 +2891,11 @@ msgstr "准备中"
|
||||
msgid "unavailable"
|
||||
msgstr "不可用"
|
||||
|
||||
|
||||
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
|
||||
msgid "Read factory radar targets from CAN. Read-only; factory AEB and longitudinal control are unaffected. Requires a vehicle restart."
|
||||
msgstr "读取原厂 Bosch-A 雷达目标,仅接收不发送,不影响原车 AEB 和纵向控制。切换后需要重新启动车辆。"
|
||||
|
||||
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
|
||||
msgid "Use Bosch-A Radar Data"
|
||||
msgstr "使用雷达信息"
|
||||
|
||||
Reference in New Issue
Block a user