mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-25 01:12:04 +08:00
Merge remote-tracking branch 'origin/master' into only-chubbs
# Conflicts: # common/params_keys.h # opendbc_repo # selfdrive/ui/mici/onroad/model_renderer.py # selfdrive/ui/onroad/model_renderer.py # sunnypilot/modeld_v2/camera_offset_helper.py # sunnypilot/modeld_v2/tests/test_camera_offset_helper.py # sunnypilot/sunnylink/params_metadata.json
This commit is contained in:
@@ -221,7 +221,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"BlindSpot", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
|
||||
// sunnypilot model params
|
||||
{"PlanplusControl", {PERSISTENT | BACKUP, FLOAT, "1.0"}},
|
||||
{"CameraOffset", {PERSISTENT | BACKUP, FLOAT, "0.0"}},
|
||||
{"LagdToggle", {PERSISTENT | BACKUP, BOOL, "1"}},
|
||||
{"LagdToggleDelay", {PERSISTENT | BACKUP, FLOAT, "0.2"}},
|
||||
|
||||
@@ -9,6 +9,8 @@ from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.sidebar import SidebarSP
|
||||
|
||||
SIDEBAR_WIDTH = 300
|
||||
METRIC_HEIGHT = 126
|
||||
METRIC_WIDTH = 240
|
||||
@@ -62,9 +64,10 @@ class MetricData:
|
||||
self.color = color
|
||||
|
||||
|
||||
class Sidebar(Widget):
|
||||
class Sidebar(Widget, SidebarSP):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
Widget.__init__(self)
|
||||
SidebarSP.__init__(self)
|
||||
self._net_type = NETWORK_TYPES.get(NetworkType.none)
|
||||
self._net_strength = 0
|
||||
|
||||
@@ -112,6 +115,7 @@ class Sidebar(Widget):
|
||||
self._update_temperature_status(device_state)
|
||||
self._update_connection_status(device_state)
|
||||
self._update_panda_status()
|
||||
SidebarSP._update_sunnylink_status(self)
|
||||
|
||||
def _update_network_status(self, device_state):
|
||||
self._net_type = NETWORK_TYPES.get(device_state.networkType.raw, tr_noop("Unknown"))
|
||||
@@ -200,6 +204,13 @@ class Sidebar(Widget):
|
||||
rl.draw_text_ex(self._font_regular, tr(self._net_type), text_pos, FONT_SIZE, 0, Colors.WHITE)
|
||||
|
||||
def _draw_metrics(self, rect: rl.Rectangle):
|
||||
if gui_app.sunnypilot_ui():
|
||||
metrics, start_y, spacing = SidebarSP._draw_metrics_w_sunnylink(self, rect, self._temp_status, self._panda_status, self._connect_status)
|
||||
for idx, metric in enumerate(metrics):
|
||||
self._draw_metric(rect, metric, start_y + idx * spacing)
|
||||
|
||||
return
|
||||
|
||||
metrics = [(self._temp_status, 338), (self._panda_status, 496), (self._connect_status, 654)]
|
||||
|
||||
for metric, y_offset in metrics:
|
||||
|
||||
@@ -81,9 +81,7 @@ class ModelRenderer(Widget):
|
||||
self._clip_region = None
|
||||
|
||||
self._counter = -1
|
||||
self._camera_offset = 0.0
|
||||
if camera_offset := ui_state.params.get("CameraOffset"):
|
||||
self._camera_offset = float(camera_offset)
|
||||
self._camera_offset = ui_state.params.get("CameraOffset", return_default=True) if ui_state.active_bundle else 0.0
|
||||
|
||||
self._exp_gradient = Gradient(
|
||||
start=(0.0, 1.0), # Bottom of path
|
||||
@@ -104,9 +102,8 @@ class ModelRenderer(Widget):
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
sm = ui_state.sm
|
||||
|
||||
if self._counter % 180 == 0: # This mf runs at 60fps, so every 3 seconds...
|
||||
if camera_offset := ui_state.params.get("CameraOffset"):
|
||||
self._camera_offset = float(camera_offset)
|
||||
if self._counter % 180 == 0: # This runs at 60fps, so we query every 3 seconds
|
||||
self._camera_offset = ui_state.params.get("CameraOffset", return_default=True) if ui_state.active_bundle else 0.0
|
||||
self._counter += 1
|
||||
|
||||
self._torque_filter.update(-ui_state.sm['carOutput'].actuatorsOutput.torque)
|
||||
|
||||
@@ -57,10 +57,7 @@ class ModelRenderer(Widget, ChevronMetrics, ModelRendererSP):
|
||||
self._lead_vehicles = [LeadVehicle(), LeadVehicle()]
|
||||
self._path_offset_z = HEIGHT_INIT[0]
|
||||
self._counter = -1
|
||||
self._camera_offset = 0.0
|
||||
if camera_offset := ui_state.params.get("CameraOffset"):
|
||||
self._camera_offset = float(camera_offset)
|
||||
|
||||
self._camera_offset = ui_state.params.get("CameraOffset", return_default=True) if ui_state.active_bundle else 0.0
|
||||
# Initialize ModelPoints objects
|
||||
self._path = ModelPoints()
|
||||
self._lane_lines = [ModelPoints() for _ in range(4)]
|
||||
@@ -108,8 +105,7 @@ class ModelRenderer(Widget, ChevronMetrics, ModelRendererSP):
|
||||
self._path_offset_z = live_calib.height[0] if live_calib.height else HEIGHT_INIT[0]
|
||||
|
||||
if self._counter % 60 == 0:
|
||||
if camera_offset := ui_state.params.get("CameraOffset"):
|
||||
self._camera_offset = float(camera_offset)
|
||||
self._camera_offset = ui_state.params.get("CameraOffset", return_default=True) if ui_state.active_bundle else 0.0
|
||||
self._counter += 1
|
||||
|
||||
if sm.updated['carParams']:
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
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 pyray as rl
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.sunnypilot.sunnylink.api import UNREGISTERED_SUNNYLINK_DONGLE_ID
|
||||
from openpilot.system.ui.lib.multilang import tr_noop
|
||||
|
||||
|
||||
PING_TIMEOUT_NS = 80_000_000_000 # 80 seconds in nanoseconds
|
||||
METRIC_HEIGHT = 126
|
||||
METRIC_MARGIN = 30
|
||||
METRIC_START_Y = 300
|
||||
HOME_BTN = rl.Rectangle(60, 860, 180, 180)
|
||||
|
||||
|
||||
# Color scheme
|
||||
class Colors:
|
||||
WHITE = rl.WHITE
|
||||
WHITE_DIM = rl.Color(255, 255, 255, 85)
|
||||
GRAY = rl.Color(84, 84, 84, 255)
|
||||
|
||||
# Status colors
|
||||
GOOD = rl.WHITE
|
||||
WARNING = rl.Color(218, 202, 37, 255)
|
||||
DANGER = rl.Color(201, 34, 49, 255)
|
||||
PROGRESS = rl.Color(0, 134, 233, 255)
|
||||
DISABLED = rl.Color(128, 128, 128, 255)
|
||||
|
||||
# UI elements
|
||||
METRIC_BORDER = rl.Color(255, 255, 255, 85)
|
||||
BUTTON_NORMAL = rl.WHITE
|
||||
BUTTON_PRESSED = rl.Color(255, 255, 255, 166)
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class MetricData:
|
||||
label: str
|
||||
value: str
|
||||
color: rl.Color
|
||||
|
||||
def update(self, label: str, value: str, color: rl.Color):
|
||||
self.label = label
|
||||
self.value = value
|
||||
self.color = color
|
||||
|
||||
|
||||
class SidebarSP:
|
||||
def __init__(self):
|
||||
self._sunnylink_status = MetricData(tr_noop("SUNNYLINK"), tr_noop("OFFLINE"), Colors.WARNING)
|
||||
|
||||
def _update_sunnylink_status(self):
|
||||
if not ui_state.params.get_bool("SunnylinkEnabled"):
|
||||
self._sunnylink_status.update(tr_noop("SUNNYLINK"), tr_noop("DISABLED"), Colors.DISABLED)
|
||||
return
|
||||
|
||||
last_ping = ui_state.params.get("LastSunnylinkPingTime") or 0
|
||||
dongle_id = ui_state.params.get("SunnylinkDongleId")
|
||||
|
||||
is_online = last_ping and (time.monotonic_ns() - last_ping) < PING_TIMEOUT_NS
|
||||
is_temp_fault = ui_state.params.get_bool("SunnylinkTempFault")
|
||||
is_registering = not is_temp_fault and dongle_id in (None, "", UNREGISTERED_SUNNYLINK_DONGLE_ID)
|
||||
|
||||
# Determine status/color pair based on priority
|
||||
if last_ping:
|
||||
status, color = (tr_noop("ONLINE"), Colors.GOOD) if is_online else (tr_noop("ERROR"), Colors.DANGER)
|
||||
elif is_temp_fault:
|
||||
status, color = (tr_noop("FAULT"), Colors.WARNING)
|
||||
elif is_registering:
|
||||
status, color = (tr_noop("REGIST..."), Colors.PROGRESS)
|
||||
else:
|
||||
status, color = (tr_noop("OFFLINE"), Colors.DANGER)
|
||||
|
||||
self._sunnylink_status.update(tr_noop("SUNNYLINK"), status, color)
|
||||
|
||||
def _draw_metrics_w_sunnylink(self, rect: rl.Rectangle, _temp, _panda, _connect):
|
||||
metrics = [_temp, _panda, _connect, self._sunnylink_status]
|
||||
start_y = int(rect.y) + METRIC_START_Y
|
||||
available_height = max(0, int(HOME_BTN.y) - METRIC_MARGIN - METRIC_HEIGHT - start_y)
|
||||
spacing = available_height / max(1, len(metrics) - 1)
|
||||
|
||||
return metrics, start_y, spacing
|
||||
@@ -37,6 +37,9 @@ class UIStateSP:
|
||||
def on_param_change(self, param_name):
|
||||
self.changed_params.add(param_name)
|
||||
|
||||
self.custom_interactive_timeout: int = self.params.get("InteractivityTimeout", return_default=True)
|
||||
self.global_brightness_override: int = self.params.get("Brightness", return_default=True)
|
||||
|
||||
def update(self) -> None:
|
||||
if self.sunnylink_enabled:
|
||||
self.sunnylink_state.start()
|
||||
@@ -100,6 +103,9 @@ class UIStateSP:
|
||||
self.developer_ui = self.params.get("DevUIInfo")
|
||||
self.rainbow_path = self.params.get_bool("RainbowMode")
|
||||
self.chevron_metrics = self.params.get("ChevronInfo")
|
||||
self.active_bundle = self.params.get("ModelManager_ActiveBundle")
|
||||
self.custom_interactive_timeout = self.params.get("InteractivityTimeout", return_default=True)
|
||||
self.global_brightness_override = self.params.get("Brightness", return_default=True)
|
||||
|
||||
|
||||
class DeviceSP:
|
||||
|
||||
@@ -219,6 +219,9 @@ class Device(DeviceSP):
|
||||
if self._override_interactive_timeout is not None:
|
||||
return self._override_interactive_timeout
|
||||
|
||||
if gui_app.sunnypilot_ui() and ui_state.custom_interactive_timeout != 0:
|
||||
return ui_state.custom_interactive_timeout
|
||||
|
||||
ignition_timeout = 10 if gui_app.big_ui() else 5
|
||||
return ignition_timeout if ui_state.ignition else 30
|
||||
|
||||
@@ -253,9 +256,18 @@ class Device(DeviceSP):
|
||||
else:
|
||||
clipped_brightness = ((clipped_brightness + 16.0) / 116.0) ** 3.0
|
||||
|
||||
clipped_brightness = float(np.interp(clipped_brightness, [0, 1], [30, 100]))
|
||||
if gui_app.sunnypilot_ui():
|
||||
if ui_state.global_brightness_override <= 0:
|
||||
min_global_brightness = 1 if ui_state.global_brightness_override < 0 else 30
|
||||
clipped_brightness = float(np.interp(clipped_brightness, [0, 1], [min_global_brightness, 100]))
|
||||
else:
|
||||
clipped_brightness = float(np.interp(clipped_brightness, [0, 1], [30, 100]))
|
||||
|
||||
brightness = round(self._brightness_filter.update(clipped_brightness))
|
||||
|
||||
if gui_app.sunnypilot_ui() and ui_state.global_brightness_override > 0:
|
||||
brightness = ui_state.global_brightness_override
|
||||
|
||||
if not self._awake:
|
||||
brightness = 0
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
"""
|
||||
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 numpy as np
|
||||
|
||||
from openpilot.common.transformations.camera import DEVICE_CAMERAS
|
||||
|
||||
@@ -288,6 +288,7 @@ def main(demo=False):
|
||||
model.lat_delay = get_lat_delay(params, sm["liveDelay"].lateralDelay)
|
||||
camera_offset_helper.set_offset(params.get("CameraOffset", return_default=True))
|
||||
model.PLANPLUS_CONTROL = params.get("PlanplusControl", return_default=True)
|
||||
camera_offset_helper.set_offset(params.get("CameraOffset", return_default=True))
|
||||
lat_delay = model.lat_delay + model.LAT_SMOOTH_SECONDS
|
||||
if sm.updated["liveCalibration"] and sm.seen['roadCameraState'] and sm.seen['deviceState']:
|
||||
device_from_calib_euler = np.array(sm["liveCalibration"].rpyCalib, dtype=np.float32)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""
|
||||
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 numpy as np
|
||||
|
||||
from openpilot.common.transformations.camera import DEVICE_CAMERAS
|
||||
from openpilot.common.transformations.model import get_warp_matrix
|
||||
|
||||
from openpilot.sunnypilot.modeld_v2.camera_offset_helper import CameraOffsetHelper
|
||||
|
||||
|
||||
@@ -31,22 +36,18 @@ class TestCameraOffset:
|
||||
|
||||
intrinsics_main = self.dc.fcam.intrinsics
|
||||
intrinsics_extra = self.dc.ecam.intrinsics
|
||||
|
||||
device_from_calib_euler = np.array([0.0, 0.0, 0.0], dtype=np.float32)
|
||||
|
||||
main_transform = get_warp_matrix(device_from_calib_euler, intrinsics_main, False).astype(np.float32)
|
||||
extra_transform = get_warp_matrix(device_from_calib_euler, intrinsics_extra, True).astype(np.float32)
|
||||
|
||||
self.camera_offset.update(main_transform, extra_transform, sm, False)
|
||||
np.testing.assert_almost_equal(self.camera_offset.actual_camera_offset, 0.02)
|
||||
|
||||
self.camera_offset.update(main_transform, extra_transform, sm, False)
|
||||
np.testing.assert_almost_equal(self.camera_offset.actual_camera_offset, 0.038)
|
||||
|
||||
def test_camera_offset_(self):
|
||||
intrinsics = self.dc.fcam.intrinsics
|
||||
transform = np.eye(3, dtype=np.float32)
|
||||
|
||||
height = 1.22
|
||||
offset = 0.1
|
||||
|
||||
@@ -58,7 +59,7 @@ class TestCameraOffset:
|
||||
result = CameraOffsetHelper.apply_camera_offset(transform, intrinsics, height, offset)
|
||||
np.testing.assert_array_almost_equal(result, expected_shear)
|
||||
|
||||
def test_integration_update(self):
|
||||
def test_update(self):
|
||||
sm = MockStruct(
|
||||
deviceState=MockStruct(deviceType='mici'),
|
||||
roadCameraState=MockStruct(sensor='os04c10'),
|
||||
@@ -66,17 +67,18 @@ class TestCameraOffset:
|
||||
)
|
||||
intrinsics_main = self.dc.fcam.intrinsics
|
||||
intrinsics_extra = self.dc.ecam.intrinsics
|
||||
|
||||
device_from_calib_euler = np.array([0.0, 0.0, 0.0], dtype=np.float32)
|
||||
main_transform = get_warp_matrix(device_from_calib_euler, intrinsics_main, False).astype(np.float32)
|
||||
extra_transform = get_warp_matrix(device_from_calib_euler, intrinsics_extra, True).astype(np.float32)
|
||||
|
||||
self.camera_offset.set_offset(0.2)
|
||||
|
||||
self.camera_offset.set_offset(0.0) # test default offset doesn't change transformation
|
||||
main_out, extra_out = self.camera_offset.update(main_transform, extra_transform, sm, False)
|
||||
np.testing.assert_array_equal(main_out, main_transform)
|
||||
np.testing.assert_array_equal(extra_out, extra_transform)
|
||||
|
||||
self.camera_offset.set_offset(0.2) # test valid offset changes transformation
|
||||
main_out, extra_out = self.camera_offset.update(main_transform, extra_transform, sm, False)
|
||||
assert not np.array_equal(main_out, main_transform)
|
||||
assert not np.array_equal(extra_out, extra_transform)
|
||||
|
||||
assert main_out[0, 1] != 0.0
|
||||
assert main_out[0, 2] != 0.0
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
},
|
||||
"CameraOffset": {
|
||||
"title": "Adjust Camera Offset",
|
||||
"description": "Adjust this to center the car in its lane by virtually shifting the camera's perspective. Negative Values: Shears the image to the left, moving the model's center to the Right; Positive Values: Shears the image to the right, moving the model's center to the Left. Note: these values are in meters.",
|
||||
"description": "Virtually shift camera's perspective to move model's center to Left(+ values) or Right (- values)",
|
||||
"min": -0.35,
|
||||
"max": 0.35,
|
||||
"step": 0.01
|
||||
@@ -193,7 +193,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"CustomAccIncrementsEnabled": {
|
||||
"title": "Custom ACC Increments Enabled",
|
||||
"title": "Custom ACC Increments",
|
||||
"description": ""
|
||||
},
|
||||
"CustomAccLongPressIncrement": {
|
||||
@@ -211,8 +211,8 @@
|
||||
"step": 1
|
||||
},
|
||||
"CustomTorqueParams": {
|
||||
"title": "Custom Torque Params",
|
||||
"description": ""
|
||||
"title": "Enable Custom Torque Tuning",
|
||||
"description": "Enables custom tuning for Torque lateral control"
|
||||
},
|
||||
"DevUIInfo": {
|
||||
"title": "Developer UI Info",
|
||||
@@ -286,7 +286,7 @@
|
||||
},
|
||||
"EnforceTorqueControl": {
|
||||
"title": "Enforce Torque Control",
|
||||
"description": ""
|
||||
"description": "Enable this to enforce sunnypilot to steer with Torque lateral control."
|
||||
},
|
||||
"ExperimentalMode": {
|
||||
"title": "Experimental Mode",
|
||||
@@ -451,12 +451,15 @@
|
||||
"description": ""
|
||||
},
|
||||
"LagdToggle": {
|
||||
"title": "LaGD Toggle",
|
||||
"description": ""
|
||||
"title": "Live Learning Steer Delay",
|
||||
"description": "Allow device to learn and adapt car's steering response time"
|
||||
},
|
||||
"LagdToggleDelay": {
|
||||
"title": "LaGD Toggle Delay",
|
||||
"description": ""
|
||||
"title": "Manual Software Delay",
|
||||
"description": "Software delay to use when Live Learning Steer Delay is toggled off",
|
||||
"min": 0.05,
|
||||
"max": 0.5,
|
||||
"step": 0.01
|
||||
},
|
||||
"LagdValueCache": {
|
||||
"title": "LaGD Value Cache",
|
||||
@@ -464,11 +467,11 @@
|
||||
},
|
||||
"LaneTurnDesire": {
|
||||
"title": "Lane Turn Desire",
|
||||
"description": ""
|
||||
"description": "Force model to plan an intent to turn based on blinker"
|
||||
},
|
||||
"LaneTurnValue": {
|
||||
"title": "Lane Turn Value",
|
||||
"description": "",
|
||||
"title": "Lane Turn Speed",
|
||||
"description": "Maximum speed for lane turn desire",
|
||||
"min": 0,
|
||||
"max": 20,
|
||||
"step": 1
|
||||
@@ -546,12 +549,12 @@
|
||||
"description": ""
|
||||
},
|
||||
"LiveTorqueParamsRelaxedToggle": {
|
||||
"title": "Live Torque Params Relaxed Toggle",
|
||||
"description": ""
|
||||
"title": "Less Restrict Settings for Self-Tune (Beta)",
|
||||
"description": "Less strict settings when using Self-Tune. This allows torqued to be more forgiving when learning values."
|
||||
},
|
||||
"LiveTorqueParamsToggle": {
|
||||
"title": "Live Torque Params Toggle",
|
||||
"description": ""
|
||||
"title": "Self-Tune",
|
||||
"description": "Enables self-tune for Torque lateral control"
|
||||
},
|
||||
"LocationFilterInitialState": {
|
||||
"title": "Location Filter Initial State",
|
||||
@@ -704,7 +707,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"OffroadMode": {
|
||||
"title": "Offroad Mode",
|
||||
"title": "Force Offroad Mode",
|
||||
"description": ""
|
||||
},
|
||||
"Offroad_CarUnrecognized": {
|
||||
@@ -768,18 +771,18 @@
|
||||
"description": ""
|
||||
},
|
||||
"OnroadScreenOffBrightness": {
|
||||
"title": "Onroad Screen Off Brightness",
|
||||
"title": "Onroad Brightness",
|
||||
"description": "",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"step": 5
|
||||
},
|
||||
"OnroadScreenOffControl": {
|
||||
"title": "Onroad Screen Off Control",
|
||||
"description": ""
|
||||
"title": "Onroad Screen: Reduced Brightness",
|
||||
"description": "Turn off device screen or reduce brightness after driving starts"
|
||||
},
|
||||
"OnroadScreenOffTimer": {
|
||||
"title": "Onroad Screen Off Timer",
|
||||
"title": "Onroad Brightness Delay",
|
||||
"description": "",
|
||||
"min": 0,
|
||||
"max": 60,
|
||||
@@ -885,7 +888,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"RoadNameToggle": {
|
||||
"title": "Road Name Toggle",
|
||||
"title": "Display Road Name",
|
||||
"description": ""
|
||||
},
|
||||
"RouteCount": {
|
||||
@@ -898,7 +901,7 @@
|
||||
},
|
||||
"ShowAdvancedControls": {
|
||||
"title": "Show Advanced Controls",
|
||||
"description": ""
|
||||
"description": "Enable to show advanced controls on device"
|
||||
},
|
||||
"ShowDebugInfo": {
|
||||
"title": "UI Debug Mode",
|
||||
@@ -909,11 +912,11 @@
|
||||
"description": ""
|
||||
},
|
||||
"SmartCruiseControlMap": {
|
||||
"title": "Smart Cruise Control Map",
|
||||
"title": "Smart Cruise Control - Map",
|
||||
"description": ""
|
||||
},
|
||||
"SmartCruiseControlVision": {
|
||||
"title": "Smart Cruise Control Vision",
|
||||
"title": "Smart Cruise Control - Vision",
|
||||
"description": ""
|
||||
},
|
||||
"SnoozeUpdate": {
|
||||
@@ -921,7 +924,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"SpeedLimitMode": {
|
||||
"title": "Speed Limit Mode",
|
||||
"title": "Speed Limit Assist Mode",
|
||||
"description": "",
|
||||
"options": [
|
||||
{
|
||||
@@ -961,7 +964,7 @@
|
||||
]
|
||||
},
|
||||
"SpeedLimitPolicy": {
|
||||
"title": "Speed Limit Policy",
|
||||
"title": "Speed Limit Source",
|
||||
"description": "",
|
||||
"options": [
|
||||
{
|
||||
@@ -987,7 +990,7 @@
|
||||
]
|
||||
},
|
||||
"SpeedLimitValueOffset": {
|
||||
"title": "Speed Limit Value Offset",
|
||||
"title": "Speed Limit Offset Value",
|
||||
"description": "",
|
||||
"min": -30,
|
||||
"max": 30,
|
||||
@@ -1042,18 +1045,18 @@
|
||||
"description": ""
|
||||
},
|
||||
"TorqueParamsOverrideEnabled": {
|
||||
"title": "Torque Params Override Enabled",
|
||||
"title": "Manual Real-Time Tuning",
|
||||
"description": ""
|
||||
},
|
||||
"TorqueParamsOverrideFriction": {
|
||||
"title": "Torque Params Override Friction",
|
||||
"title": "Manual Tune - Friction",
|
||||
"description": "",
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
},
|
||||
"TorqueParamsOverrideLatAccelFactor": {
|
||||
"title": "Torque Params Override Lat Accel Factor",
|
||||
"title": "Manual Tune - Lateral Acceleration Factor",
|
||||
"description": "",
|
||||
"min": 0.1,
|
||||
"max": 5.0,
|
||||
|
||||
Reference in New Issue
Block a user