mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-10-21 11:33:44 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ab7566394 | |||
| 273903b26e |
@@ -7,7 +7,6 @@ from functools import cached_property
|
|||||||
import os
|
import os
|
||||||
os.environ['GMMU'] = '0' # for chestnut fast loading, noop for qcom
|
os.environ['GMMU'] = '0' # for chestnut fast loading, noop for qcom
|
||||||
os.environ.setdefault('AM_POWER_LIMIT', '100')
|
os.environ.setdefault('AM_POWER_LIMIT', '100')
|
||||||
os.environ.setdefault('AM_PERF_LEVEL', 'high')
|
|
||||||
from tinygrad.device import Buffer, Device
|
from tinygrad.device import Buffer, Device
|
||||||
from tinygrad.dtype import DType, dtypes
|
from tinygrad.dtype import DType, dtypes
|
||||||
from tinygrad.engine.realize import lower_and_compile
|
from tinygrad.engine.realize import lower_and_compile
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from enum import IntEnum
|
|||||||
|
|
||||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.cruise_sub_layouts.speed_limit_settings import SpeedLimitSettingsLayout
|
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.cruise_sub_layouts.speed_limit_settings import SpeedLimitSettingsLayout
|
||||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||||
|
from openpilot.sunnypilot.mapd import MAPD_AVAILABLE
|
||||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||||
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp, option_item_sp, simple_button_item_sp
|
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp, option_item_sp, simple_button_item_sp
|
||||||
from openpilot.system.ui.widgets import Widget
|
from openpilot.system.ui.widgets import Widget
|
||||||
@@ -29,6 +30,7 @@ ACC_ENABLED_DESCRIPTION = tr_noop("Enable custom Short & Long press increments f
|
|||||||
ACC_NOLONG_DESCRIPTION = tr_noop("This feature can only be used with sunnypilot longitudinal control enabled.")
|
ACC_NOLONG_DESCRIPTION = tr_noop("This feature can only be used with sunnypilot longitudinal control enabled.")
|
||||||
ACC_PCMCRUISE_DISABLED_DESCRIPTION = tr_noop("This feature is not supported on this platform due to vehicle limitations.")
|
ACC_PCMCRUISE_DISABLED_DESCRIPTION = tr_noop("This feature is not supported on this platform due to vehicle limitations.")
|
||||||
ONROAD_ONLY_DESCRIPTION = tr_noop("Start the vehicle to check vehicle compatibility.")
|
ONROAD_ONLY_DESCRIPTION = tr_noop("Start the vehicle to check vehicle compatibility.")
|
||||||
|
MAP_UNAVAILABLE_DESCRIPTION = tr_noop("Map data is temporarily unavailable.")
|
||||||
|
|
||||||
|
|
||||||
class CruiseLayout(Widget):
|
class CruiseLayout(Widget):
|
||||||
@@ -54,7 +56,8 @@ class CruiseLayout(Widget):
|
|||||||
|
|
||||||
self.scc_m_toggle = toggle_item_sp(
|
self.scc_m_toggle = toggle_item_sp(
|
||||||
title=tr("Smart Cruise Control - Map"),
|
title=tr("Smart Cruise Control - Map"),
|
||||||
description=tr("Use map data to estimate the appropriate speed to drive through turns ahead."),
|
description=(f"<b>{tr(MAP_UNAVAILABLE_DESCRIPTION)}</b>\n\n" if not MAPD_AVAILABLE else "") +
|
||||||
|
tr("Use map data to estimate the appropriate speed to drive through turns ahead."),
|
||||||
param="SmartCruiseControlMap")
|
param="SmartCruiseControlMap")
|
||||||
|
|
||||||
self.custom_acc_toggle = toggle_item_sp(
|
self.custom_acc_toggle = toggle_item_sp(
|
||||||
@@ -139,7 +142,7 @@ class CruiseLayout(Widget):
|
|||||||
if has_long or has_icbm:
|
if has_long or has_icbm:
|
||||||
self.custom_acc_toggle.action_item.set_enabled(((has_long and not ui_state.CP.pcmCruise) or has_icbm) and ui_state.is_offroad())
|
self.custom_acc_toggle.action_item.set_enabled(((has_long and not ui_state.CP.pcmCruise) or has_icbm) and ui_state.is_offroad())
|
||||||
self.scc_v_toggle.action_item.set_enabled(True)
|
self.scc_v_toggle.action_item.set_enabled(True)
|
||||||
self.scc_m_toggle.action_item.set_enabled(True)
|
self.scc_m_toggle.action_item.set_enabled(MAPD_AVAILABLE)
|
||||||
else:
|
else:
|
||||||
ui_state.params.remove("CustomAccIncrementsEnabled")
|
ui_state.params.remove("CustomAccIncrementsEnabled")
|
||||||
ui_state.params.remove("SmartCruiseControlVision")
|
ui_state.params.remove("SmartCruiseControlVision")
|
||||||
|
|||||||
+6
@@ -8,6 +8,8 @@ from collections.abc import Callable
|
|||||||
|
|
||||||
import pyray as rl
|
import pyray as rl
|
||||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||||
|
from openpilot.sunnypilot.mapd import MAPD_AVAILABLE
|
||||||
|
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Policy
|
||||||
from openpilot.system.ui.lib.multilang import tr
|
from openpilot.system.ui.lib.multilang import tr
|
||||||
from openpilot.system.ui.sunnypilot.widgets.list_view import multiple_button_item_sp
|
from openpilot.system.ui.sunnypilot.widgets.list_view import multiple_button_item_sp
|
||||||
from openpilot.system.ui.widgets.network import NavButton
|
from openpilot.system.ui.widgets.network import NavButton
|
||||||
@@ -43,6 +45,8 @@ class SpeedLimitPolicyLayout(Widget):
|
|||||||
param="SpeedLimitPolicy",
|
param="SpeedLimitPolicy",
|
||||||
button_width=250,
|
button_width=250,
|
||||||
)
|
)
|
||||||
|
if not MAPD_AVAILABLE:
|
||||||
|
self._speed_limit_policy.action_item.set_enabled_buttons({Policy.car_state_only})
|
||||||
|
|
||||||
items = [
|
items = [
|
||||||
self._speed_limit_policy
|
self._speed_limit_policy
|
||||||
@@ -51,6 +55,8 @@ class SpeedLimitPolicyLayout(Widget):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_policy_description():
|
def _get_policy_description():
|
||||||
|
if not MAPD_AVAILABLE:
|
||||||
|
return f"<b>{tr('Map data is temporarily unavailable. Using Speed Limit data only from Car.')}</b>"
|
||||||
return get_highlighted_description(ui_state.params, "SpeedLimitPolicy", SPEED_LIMIT_POLICY_DESCRIPTIONS)
|
return get_highlighted_description(ui_state.params, "SpeedLimitPolicy", SPEED_LIMIT_POLICY_DESCRIPTIONS)
|
||||||
|
|
||||||
def _render(self, rect):
|
def _render(self, rect):
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define SUNNYPILOT_VERSION "2026.10.19-4956"
|
#define SUNNYPILOT_VERSION "2026.10.18-4943"
|
||||||
|
|||||||
@@ -3,3 +3,7 @@ from openpilot.common.basedir import BASEDIR
|
|||||||
|
|
||||||
MAPD_BIN_DIR = os.path.join(BASEDIR, 'openpilot', 'third_party/mapd_pfeiferj')
|
MAPD_BIN_DIR = os.path.join(BASEDIR, 'openpilot', 'third_party/mapd_pfeiferj')
|
||||||
MAPD_PATH = os.path.join(MAPD_BIN_DIR, 'mapd')
|
MAPD_PATH = os.path.join(MAPD_BIN_DIR, 'mapd')
|
||||||
|
|
||||||
|
# mapd still runs (OSM downloads) but has no position source since ubloxd owns LastGPSPosition;
|
||||||
|
# map-based features stay off until mapd is rebuilt
|
||||||
|
MAPD_AVAILABLE = False
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ 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.
|
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.
|
See the LICENSE.md file in the root directory for more details.
|
||||||
"""
|
"""
|
||||||
import json
|
|
||||||
import math
|
import math
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
@@ -27,21 +26,6 @@ class OsmMapData(BaseMapData):
|
|||||||
self.last_bearing = math.degrees(location.calibratedOrientationNED.value[2])
|
self.last_bearing = math.degrees(location.calibratedOrientationNED.value[2])
|
||||||
self.last_position = Coordinate(location.positionGeodetic.value[0], location.positionGeodetic.value[1])
|
self.last_position = Coordinate(location.positionGeodetic.value[0], location.positionGeodetic.value[1])
|
||||||
|
|
||||||
if self.last_position is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
params = {
|
|
||||||
"latitude": self.last_position.latitude,
|
|
||||||
"longitude": self.last_position.longitude,
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.last_bearing is not None:
|
|
||||||
params['bearing'] = self.last_bearing
|
|
||||||
|
|
||||||
# mapd reads its position from the memory params as JSON, so write it for the mapd binary.
|
|
||||||
# LastGPSPosition is registered as BYTES (ubloxd owns the persistent copy for pigeond),
|
|
||||||
# so the JSON payload has to be encoded here.
|
|
||||||
self.mem_params.put("LastGPSPosition", json.dumps(params).encode(), block=True)
|
|
||||||
|
|
||||||
def get_current_speed_limit(self) -> float:
|
def get_current_speed_limit(self) -> float:
|
||||||
return float(self.mem_params.get("MapSpeedLimit") or 0.0)
|
return float(self.mem_params.get("MapSpeedLimit") or 0.0)
|
||||||
|
|||||||
@@ -121,10 +121,6 @@ def update_osm_db() -> None:
|
|||||||
if not mem_params.get("OSMDownloadBounds"):
|
if not mem_params.get("OSMDownloadBounds"):
|
||||||
mem_params.put("OSMDownloadBounds", "", block=True)
|
mem_params.put("OSMDownloadBounds", "", block=True)
|
||||||
|
|
||||||
# mapd reads LastGPSPosition from the memory params as JSON, and it is registered as BYTES upstream
|
|
||||||
if not mem_params.get("LastGPSPosition"):
|
|
||||||
mem_params.put("LastGPSPosition", b"{}", block=True)
|
|
||||||
|
|
||||||
|
|
||||||
def main_thread():
|
def main_thread():
|
||||||
update_installed_version(VERSION, params)
|
update_installed_version(VERSION, params)
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
"""
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
import json
|
|
||||||
import math
|
|
||||||
import platform
|
|
||||||
|
|
||||||
import openpilot.cereal.messaging as messaging
|
|
||||||
from openpilot.cereal import log
|
|
||||||
from openpilot.common.params import Params
|
|
||||||
from openpilot.common.test import OpenpilotTestCase
|
|
||||||
from openpilot.sunnypilot.mapd.live_map_data.osm_map_data import OsmMapData
|
|
||||||
|
|
||||||
|
|
||||||
class TestOsmMapData(OpenpilotTestCase):
|
|
||||||
"""The mapd binary reads its position from the memory params as JSON, so mapd_manager has to feed it."""
|
|
||||||
|
|
||||||
LATITUDE = 32.875134
|
|
||||||
LONGITUDE = -117.209777
|
|
||||||
ALTITUDE = 42.0
|
|
||||||
BEARING = 90.0
|
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else Params()
|
|
||||||
self.mem_params.remove("LastGPSPosition")
|
|
||||||
self.map_data = OsmMapData()
|
|
||||||
self.pm = messaging.PubMaster(['liveLocationKalman'])
|
|
||||||
|
|
||||||
def location_message(self, status: log.LiveLocationKalman.Status, position_valid: bool):
|
|
||||||
msg = messaging.new_message('liveLocationKalman', valid=True)
|
|
||||||
location = msg.liveLocationKalman
|
|
||||||
location.status = status
|
|
||||||
location.positionGeodetic = {'value': [self.LATITUDE, self.LONGITUDE, self.ALTITUDE], 'valid': position_valid}
|
|
||||||
location.calibratedOrientationNED = {'value': [0.0, 0.0, math.radians(self.BEARING)], 'valid': True}
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def send_location(self, status: log.LiveLocationKalman.Status, position_valid: bool) -> None:
|
|
||||||
# the first exchange synchronizes the PUB/SUB connection, the second one is actually received
|
|
||||||
self.pm.send('liveLocationKalman', self.location_message(status, position_valid))
|
|
||||||
self.map_data.sm.update(1000)
|
|
||||||
self.pm.send('liveLocationKalman', self.location_message(status, position_valid))
|
|
||||||
self.map_data.sm.update(1000)
|
|
||||||
|
|
||||||
def read_position(self) -> dict:
|
|
||||||
value = self.mem_params.get("LastGPSPosition")
|
|
||||||
self.assertIsNotNone(value, "LastGPSPosition was not written for mapd")
|
|
||||||
return json.loads(value)
|
|
||||||
|
|
||||||
def test_writes_position_for_mapd(self):
|
|
||||||
self.send_location(log.LiveLocationKalman.Status.valid, True)
|
|
||||||
self.map_data.tick()
|
|
||||||
|
|
||||||
position = self.read_position()
|
|
||||||
self.assertAlmostEqual(position['latitude'], self.LATITUDE, delta=1e-6)
|
|
||||||
self.assertAlmostEqual(position['longitude'], self.LONGITUDE, delta=1e-6)
|
|
||||||
self.assertAlmostEqual(position['bearing'], self.BEARING, delta=1e-6)
|
|
||||||
|
|
||||||
def test_invalid_localizer_keeps_last_known_position(self):
|
|
||||||
self.send_location(log.LiveLocationKalman.Status.valid, True)
|
|
||||||
self.map_data.tick()
|
|
||||||
|
|
||||||
self.send_location(log.LiveLocationKalman.Status.uninitialized, False)
|
|
||||||
self.map_data.tick()
|
|
||||||
|
|
||||||
position = self.read_position()
|
|
||||||
self.assertAlmostEqual(position['latitude'], self.LATITUDE, delta=1e-6)
|
|
||||||
self.assertAlmostEqual(position['longitude'], self.LONGITUDE, delta=1e-6)
|
|
||||||
@@ -9,6 +9,7 @@ from openpilot.common.params import Params
|
|||||||
from openpilot.common.realtime import DT_MDL
|
from openpilot.common.realtime import DT_MDL
|
||||||
from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET
|
from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET
|
||||||
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD
|
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD
|
||||||
|
from openpilot.sunnypilot.mapd import MAPD_AVAILABLE
|
||||||
from openpilot.sunnypilot.navd.helpers import Coordinate
|
from openpilot.sunnypilot.navd.helpers import Coordinate
|
||||||
from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control import MIN_V
|
from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control import MIN_V
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ class SmartCruiseControlMap:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.params = Params()
|
self.params = Params()
|
||||||
self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else self.params
|
self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else self.params
|
||||||
self.enabled = self.params.get_bool("SmartCruiseControlMap")
|
self.enabled = MAPD_AVAILABLE and self.params.get_bool("SmartCruiseControlMap")
|
||||||
self.long_enabled = False
|
self.long_enabled = False
|
||||||
self.long_override = False
|
self.long_override = False
|
||||||
self.is_enabled = False
|
self.is_enabled = False
|
||||||
@@ -101,7 +102,7 @@ class SmartCruiseControlMap:
|
|||||||
|
|
||||||
def update_params(self):
|
def update_params(self):
|
||||||
if self.frame % int(PARAMS_UPDATE_PERIOD / DT_MDL) == 0:
|
if self.frame % int(PARAMS_UPDATE_PERIOD / DT_MDL) == 0:
|
||||||
self.enabled = self.params.get_bool("SmartCruiseControlMap")
|
self.enabled = MAPD_AVAILABLE and self.params.get_bool("SmartCruiseControlMap")
|
||||||
|
|
||||||
def update_calculations(self, sm: messaging.SubMaster) -> None:
|
def update_calculations(self, sm: messaging.SubMaster) -> None:
|
||||||
gps = sm[self.gps_location_service]
|
gps = sm[self.gps_location_service]
|
||||||
|
|||||||
+14
-1
@@ -8,7 +8,7 @@ import json
|
|||||||
import math
|
import math
|
||||||
import platform
|
import platform
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from openpilot.cereal import custom
|
from openpilot.cereal import custom
|
||||||
from openpilot.common.params import Params
|
from openpilot.common.params import Params
|
||||||
@@ -23,6 +23,8 @@ MapState = VisionState = custom.LongitudinalPlanSP.SmartCruiseControl.MapState
|
|||||||
class TestSmartCruiseControlMap(OpenpilotTestCase):
|
class TestSmartCruiseControlMap(OpenpilotTestCase):
|
||||||
|
|
||||||
def setup_method(self):
|
def setup_method(self):
|
||||||
|
self.mapd_patch = patch("openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control.map_controller.MAPD_AVAILABLE", True)
|
||||||
|
self.mapd_patch.start()
|
||||||
self.params = Params()
|
self.params = Params()
|
||||||
self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else self.params
|
self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else self.params
|
||||||
self.reset_params()
|
self.reset_params()
|
||||||
@@ -30,6 +32,9 @@ class TestSmartCruiseControlMap(OpenpilotTestCase):
|
|||||||
self.sm = MagicMock()
|
self.sm = MagicMock()
|
||||||
self.sm.__getitem__.return_value = SimpleNamespace(latitude=0.0, longitude=0.0)
|
self.sm.__getitem__.return_value = SimpleNamespace(latitude=0.0, longitude=0.0)
|
||||||
|
|
||||||
|
def teardown_method(self):
|
||||||
|
self.mapd_patch.stop()
|
||||||
|
|
||||||
def reset_params(self):
|
def reset_params(self):
|
||||||
self.params.put_bool("SmartCruiseControlMap", True, block=True)
|
self.params.put_bool("SmartCruiseControlMap", True, block=True)
|
||||||
|
|
||||||
@@ -50,6 +55,14 @@ class TestSmartCruiseControlMap(OpenpilotTestCase):
|
|||||||
assert self.scc_m.state == VisionState.disabled
|
assert self.scc_m.state == VisionState.disabled
|
||||||
assert not self.scc_m.is_active
|
assert not self.scc_m.is_active
|
||||||
|
|
||||||
|
def test_mapd_unavailable(self):
|
||||||
|
self.mapd_patch.stop()
|
||||||
|
self.scc_m = SmartCruiseControlMap()
|
||||||
|
for _ in range(int(10. / DT_MDL)):
|
||||||
|
self.scc_m.update(self.sm, True, False, 0., 0., 0.)
|
||||||
|
assert self.scc_m.state == VisionState.disabled
|
||||||
|
self.mapd_patch.start()
|
||||||
|
|
||||||
def test_disabled(self):
|
def test_disabled(self):
|
||||||
for _ in range(int(10. / DT_MDL)):
|
for _ in range(int(10. / DT_MDL)):
|
||||||
self.scc_m.update(self.sm, False, False, 0., 0., 0.)
|
self.scc_m.update(self.sm, False, False, 0., 0., 0.)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from openpilot.common.gps import get_gps_location_service
|
|||||||
from openpilot.common.params import Params
|
from openpilot.common.params import Params
|
||||||
from openpilot.common.realtime import DT_MDL
|
from openpilot.common.realtime import DT_MDL
|
||||||
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD, get_sanitize_int_param
|
from openpilot.sunnypilot import PARAMS_UPDATE_PERIOD, get_sanitize_int_param
|
||||||
|
from openpilot.sunnypilot.mapd import MAPD_AVAILABLE
|
||||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import LIMIT_MAX_MAP_DATA_AGE, LIMIT_ADAPT_ACC
|
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import LIMIT_MAX_MAP_DATA_AGE, LIMIT_ADAPT_ACC
|
||||||
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Policy, OffsetType
|
from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Policy, OffsetType
|
||||||
|
|
||||||
@@ -48,6 +49,8 @@ class SpeedLimitResolver:
|
|||||||
Policy.max().value,
|
Policy.max().value,
|
||||||
self.params
|
self.params
|
||||||
)
|
)
|
||||||
|
if not MAPD_AVAILABLE:
|
||||||
|
self.policy = Policy.car_state_only
|
||||||
self._policy_to_sources_map = {
|
self._policy_to_sources_map = {
|
||||||
Policy.car_state_only: [SpeedLimitSource.car],
|
Policy.car_state_only: [SpeedLimitSource.car],
|
||||||
Policy.map_data_only: [SpeedLimitSource.map],
|
Policy.map_data_only: [SpeedLimitSource.map],
|
||||||
@@ -91,7 +94,7 @@ class SpeedLimitResolver:
|
|||||||
|
|
||||||
def update_params(self):
|
def update_params(self):
|
||||||
if self.frame % int(PARAMS_UPDATE_PERIOD / DT_MDL) == 0:
|
if self.frame % int(PARAMS_UPDATE_PERIOD / DT_MDL) == 0:
|
||||||
self.policy = self.params.get("SpeedLimitPolicy", return_default=True)
|
self.policy = self.params.get("SpeedLimitPolicy", return_default=True) if MAPD_AVAILABLE else Policy.car_state_only
|
||||||
self.is_metric = self.params.get_bool("IsMetric")
|
self.is_metric = self.params.get_bool("IsMetric")
|
||||||
self.offset_type = self.params.get("SpeedLimitOffsetType", return_default=True)
|
self.offset_type = self.params.get("SpeedLimitOffsetType", return_default=True)
|
||||||
self.offset_value = self.params.get("SpeedLimitValueOffset", return_default=True)
|
self.offset_value = self.params.get("SpeedLimitValueOffset", return_default=True)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from opendbc.sunnypilot.car.tesla.values import TeslaFlagsSP
|
|||||||
from openpilot.common.params import Params
|
from openpilot.common.params import Params
|
||||||
from openpilot.common.swaglog import cloudlog
|
from openpilot.common.swaglog import cloudlog
|
||||||
from openpilot.common.hardware import HARDWARE
|
from openpilot.common.hardware import HARDWARE
|
||||||
|
from openpilot.sunnypilot.mapd import MAPD_AVAILABLE
|
||||||
|
|
||||||
|
|
||||||
# Wire-protocol version for the capabilities payload. Bump on breaking changes
|
# Wire-protocol version for the capabilities payload. Bump on breaking changes
|
||||||
@@ -43,6 +44,7 @@ CAPABILITY_FIELDS = (
|
|||||||
"device_type",
|
"device_type",
|
||||||
"subaru_has_sng",
|
"subaru_has_sng",
|
||||||
"hyundai_alpha_long_available",
|
"hyundai_alpha_long_available",
|
||||||
|
"mapd_available",
|
||||||
)
|
)
|
||||||
|
|
||||||
CAPABILITY_LABELS: dict[str, str] = {
|
CAPABILITY_LABELS: dict[str, str] = {
|
||||||
@@ -65,6 +67,7 @@ CAPABILITY_LABELS: dict[str, str] = {
|
|||||||
"device_type": "Device type",
|
"device_type": "Device type",
|
||||||
"subaru_has_sng": "Subaru Stop-and-Go available",
|
"subaru_has_sng": "Subaru Stop-and-Go available",
|
||||||
"hyundai_alpha_long_available": "Hyundai Alpha Longitudinal available",
|
"hyundai_alpha_long_available": "Hyundai Alpha Longitudinal available",
|
||||||
|
"mapd_available": "Map data available",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Explicit defaults for non-boolean capability fields
|
# Explicit defaults for non-boolean capability fields
|
||||||
@@ -132,6 +135,7 @@ def generate_capabilities(params: Params | None = None) -> dict:
|
|||||||
caps["is_sp_release"] = params.get_bool("IsReleaseSpBranch")
|
caps["is_sp_release"] = params.get_bool("IsReleaseSpBranch")
|
||||||
caps["is_development"] = params.get_bool("IsDevelopmentBranch")
|
caps["is_development"] = params.get_bool("IsDevelopmentBranch")
|
||||||
caps["stock_longitudinal"] = params.get_bool("ToyotaEnforceStockLongitudinal")
|
caps["stock_longitudinal"] = params.get_bool("ToyotaEnforceStockLongitudinal")
|
||||||
|
caps["mapd_available"] = MAPD_AVAILABLE
|
||||||
|
|
||||||
bundle = params.get("CarPlatformBundle")
|
bundle = params.get("CarPlatformBundle")
|
||||||
bundle_brand = _bundle_field(bundle, "brand")
|
bundle_brand = _bundle_field(bundle, "brand")
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ The tables below describe the **compiled** `settings_ui.json` schema — what th
|
|||||||
|
|
||||||
**Enablement rules**: Grayed out (disabled) when rules fail. Frontend shows a contextual badge explaining why.
|
**Enablement rules**: Grayed out (disabled) when rules fail. Frontend shows a contextual badge explaining why.
|
||||||
|
|
||||||
**Capability fields** (referenced in rules): `has_longitudinal_control`, `has_icbm`, `icbm_available`, `torque_allowed`, `brand`, `pcm_cruise`, `alpha_long_available`, `steer_control_type`, `has_bsm`, `is_release`, `is_sp_release`, `is_development`, `tesla_has_vehicle_bus`, `has_stop_and_go`, `stock_longitudinal`
|
**Capability fields** (referenced in rules): `has_longitudinal_control`, `has_icbm`, `icbm_available`, `torque_allowed`, `brand`, `pcm_cruise`, `alpha_long_available`, `steer_control_type`, `has_bsm`, `is_release`, `is_sp_release`, `is_development`, `tesla_has_vehicle_bus`, `has_stop_and_go`, `stock_longitudinal`, `mapd_available`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -857,19 +857,47 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 1,
|
"value": 1,
|
||||||
"label": "Map Data Only"
|
"label": "Map Data Only",
|
||||||
|
"enablement": [
|
||||||
|
{
|
||||||
|
"type": "capability",
|
||||||
|
"field": "mapd_available",
|
||||||
|
"equals": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 2,
|
"value": 2,
|
||||||
"label": "Car State Priority"
|
"label": "Car State Priority",
|
||||||
|
"enablement": [
|
||||||
|
{
|
||||||
|
"type": "capability",
|
||||||
|
"field": "mapd_available",
|
||||||
|
"equals": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 3,
|
"value": 3,
|
||||||
"label": "Map Data Priority"
|
"label": "Map Data Priority",
|
||||||
|
"enablement": [
|
||||||
|
{
|
||||||
|
"type": "capability",
|
||||||
|
"field": "mapd_available",
|
||||||
|
"equals": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 4,
|
"value": 4,
|
||||||
"label": "Combined"
|
"label": "Combined",
|
||||||
|
"enablement": [
|
||||||
|
{
|
||||||
|
"type": "capability",
|
||||||
|
"field": "mapd_available",
|
||||||
|
"equals": true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1001,6 +1029,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"enablement": [
|
"enablement": [
|
||||||
|
{
|
||||||
|
"type": "capability",
|
||||||
|
"field": "mapd_available",
|
||||||
|
"equals": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "any",
|
"type": "any",
|
||||||
"conditions": [
|
"conditions": [
|
||||||
|
|||||||
@@ -167,12 +167,28 @@ sections:
|
|||||||
label: Car State Only
|
label: Car State Only
|
||||||
- value: 1
|
- value: 1
|
||||||
label: Map Data Only
|
label: Map Data Only
|
||||||
|
enablement:
|
||||||
|
- type: capability
|
||||||
|
field: mapd_available
|
||||||
|
equals: true
|
||||||
- value: 2
|
- value: 2
|
||||||
label: Car State Priority
|
label: Car State Priority
|
||||||
|
enablement:
|
||||||
|
- type: capability
|
||||||
|
field: mapd_available
|
||||||
|
equals: true
|
||||||
- value: 3
|
- value: 3
|
||||||
label: Map Data Priority
|
label: Map Data Priority
|
||||||
|
enablement:
|
||||||
|
- type: capability
|
||||||
|
field: mapd_available
|
||||||
|
equals: true
|
||||||
- value: 4
|
- value: 4
|
||||||
label: Combined
|
label: Combined
|
||||||
|
enablement:
|
||||||
|
- type: capability
|
||||||
|
field: mapd_available
|
||||||
|
equals: true
|
||||||
- key: SpeedLimitOffsetType
|
- key: SpeedLimitOffsetType
|
||||||
widget: multiple_button
|
widget: multiple_button
|
||||||
title: Speed Limit Offset Type
|
title: Speed Limit Offset Type
|
||||||
@@ -246,6 +262,9 @@ sections:
|
|||||||
field: has_icbm
|
field: has_icbm
|
||||||
equals: true
|
equals: true
|
||||||
enablement:
|
enablement:
|
||||||
|
- type: capability
|
||||||
|
field: mapd_available
|
||||||
|
equals: true
|
||||||
- type: any
|
- type: any
|
||||||
conditions:
|
conditions:
|
||||||
- type: capability
|
- type: capability
|
||||||
|
|||||||
Reference in New Issue
Block a user