mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 00:03:45 +08:00
Merge PR #90: Rivian Angle Support
Original PR by TonyJOM (Anthony Orta). Co-authored-by: TonyJOM <anthonyorta20@icloud.com>
This commit is contained in:
@@ -15,6 +15,7 @@ const HIDDEN_SETTING_KEYS = new Set(["HumanAcceleration", "ReverseCruise"])
|
||||
const GM_MAKES = ["Buick", "Cadillac", "Chevrolet", "GMC", "Holden"]
|
||||
const HKG_MAKES = ["Genesis", "Hyundai", "Kia"]
|
||||
const VEHICLE_SETTING_MAKES = {
|
||||
RivianAngleControl: ["Rivian"],
|
||||
TeslaCoopSteering: ["Tesla"],
|
||||
NAPRadarEnabled: ["Tesla"],
|
||||
NAPRadarBehindNosecone: ["Tesla"],
|
||||
@@ -105,6 +106,7 @@ function isVehicleSettingVisible(section, param) {
|
||||
function isSettingVisible(section, param) {
|
||||
// This policy controls Galaxy rendering only; hidden params retain their stored values.
|
||||
if (HIDDEN_SETTING_KEYS.has(param.key) || !isVehicleSettingVisible(section, param)) return false
|
||||
if (param.requires_capability && !state.values[param.requires_capability]) return false
|
||||
if (RADAR_REQUIRED_KEYS.has(param.key) && !state.values.HasRadar) return false
|
||||
if (param.key === "AlphaLongitudinalEnabled" && !state.values.AlphaLongitudinalAvailable) return false
|
||||
if (state.values[GALAXY_DEVELOPER_MODE_KEY]) return true
|
||||
|
||||
@@ -2703,6 +2703,16 @@
|
||||
"options_endpoint": "/api/fingerprints/models?make={CarMake}",
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "RivianAngleControl",
|
||||
"label": "Rivian Angle Steering",
|
||||
"description": "Use the Extreme harness angle channel with cooperative torque fallback.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle",
|
||||
"favorite_eligible": true,
|
||||
"requires_capability": "HasRivianAngleHarness",
|
||||
"settings_tier": "simple"
|
||||
},
|
||||
{
|
||||
"key": "ForceFingerprint",
|
||||
"label": "Disable Automatic Fingerprint Detection",
|
||||
|
||||
@@ -172,6 +172,17 @@ def test_human_acceleration_param_is_removed():
|
||||
assert '{"HumanAcceleration",' not in params_source
|
||||
|
||||
|
||||
def test_rivian_angle_control_is_live_favorite_and_harness_gated():
|
||||
sections = _params_by_section(_layout())
|
||||
setting = sections["Vehicle"]["RivianAngleControl"]
|
||||
|
||||
assert setting["ui_type"] == "toggle"
|
||||
assert setting["favorite_eligible"] is True
|
||||
assert setting["requires_capability"] == "HasRivianAngleHarness"
|
||||
assert "reboot" not in setting["description"].lower()
|
||||
assert _declared_default("RivianAngleControl") == "0"
|
||||
|
||||
|
||||
def test_vasm_is_default_off_and_configured_only_in_galaxy():
|
||||
sections = _params_by_section(_layout())
|
||||
lateral = sections["Lateral (Steering)"]
|
||||
|
||||
@@ -249,6 +249,23 @@ def test_favorite_slot_options_include_virtual_cruise_actions(monkeypatch):
|
||||
assert "__starpilot_favorite_action__:distance_increase" in option_keys
|
||||
|
||||
|
||||
def test_rivian_angle_favorite_requires_detected_extreme_harness(monkeypatch):
|
||||
options = [
|
||||
{"key": "RivianAngleControl", "requiresCapability": "HasRivianAngleHarness"},
|
||||
{"key": "NonGatedFavorite", "requiresCapability": ""},
|
||||
]
|
||||
monkeypatch.setattr(the_galaxy, "_get_favorite_slot_options", lambda: options)
|
||||
|
||||
monkeypatch.setattr(the_galaxy, "_get_has_rivian_angle_harness", lambda: False)
|
||||
assert [option["key"] for option in the_galaxy._get_available_favorite_slot_options()] == ["NonGatedFavorite"]
|
||||
|
||||
monkeypatch.setattr(the_galaxy, "_get_has_rivian_angle_harness", lambda: True)
|
||||
assert [option["key"] for option in the_galaxy._get_available_favorite_slot_options()] == [
|
||||
"RivianAngleControl",
|
||||
"NonGatedFavorite",
|
||||
]
|
||||
|
||||
|
||||
def test_favorite_action_endpoint_increments_virtual_button_counter(monkeypatch):
|
||||
client, _ = _params_client(monkeypatch, {}, "tici")
|
||||
fake_memory = WritableFakeParams()
|
||||
|
||||
@@ -99,6 +99,8 @@ from openpilot.starpilot.system.the_galaxy import flm_workspace, utilities
|
||||
from openpilot.starpilot.system.the_galaxy.update_recovery import inspect_interrupted_update, public_recovery_status, recover_interrupted_update
|
||||
|
||||
DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL")
|
||||
# Keep Galaxy independent of opendbc's generated car bindings while matching RivianFlags.ANGLE_HARNESS.
|
||||
RIVIAN_ANGLE_HARNESS_FLAG = 1 << 0
|
||||
|
||||
GITLAB_API = "https://gitlab.com/api/v4"
|
||||
GITLAB_SUBMISSIONS_PROJECT_ID = "71992109"
|
||||
@@ -2721,6 +2723,7 @@ def _get_favorite_slot_options():
|
||||
"label": str(param_data.get("label") or key),
|
||||
"description": str(param_data.get("description") or ""),
|
||||
"section": section_name,
|
||||
"requiresCapability": str(param_data.get("requires_capability") or ""),
|
||||
})
|
||||
except Exception:
|
||||
options = []
|
||||
@@ -2729,6 +2732,15 @@ def _get_favorite_slot_options():
|
||||
_favorite_slot_options = options
|
||||
return _favorite_slot_options
|
||||
|
||||
def _get_available_favorite_slot_options():
|
||||
capabilities = {
|
||||
"HasRivianAngleHarness": _get_has_rivian_angle_harness(),
|
||||
}
|
||||
return [
|
||||
option for option in _get_favorite_slot_options()
|
||||
if not option.get("requiresCapability") or capabilities.get(option["requiresCapability"], False)
|
||||
]
|
||||
|
||||
def _favorite_slot_values(options):
|
||||
return {
|
||||
option["key"]: _safe_params_get_bool(option["key"])
|
||||
@@ -3517,6 +3529,17 @@ def _get_alpha_longitudinal_available():
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _get_has_rivian_angle_harness():
|
||||
cp_bytes = _safe_params_get_live_raw("CarParamsPersistent")
|
||||
if not cp_bytes:
|
||||
return False
|
||||
|
||||
try:
|
||||
with car.CarParams.from_bytes(cp_bytes) as cp:
|
||||
return cp.brand == "rivian" and bool(int(getattr(cp, "flags", 0)) & RIVIAN_ANGLE_HARNESS_FLAG)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _get_hardware_snapshot_items():
|
||||
starpilot_toggles = _get_starpilot_toggles_snapshot()
|
||||
|
||||
@@ -4655,7 +4678,7 @@ def setup(app):
|
||||
|
||||
@app.route("/api/favorites/slots", methods=["GET", "PUT"])
|
||||
def favorite_slots():
|
||||
options = _get_favorite_slot_options()
|
||||
options = _get_available_favorite_slot_options()
|
||||
option_by_key = {option["key"]: option for option in options}
|
||||
eligible_keys = set(option_by_key)
|
||||
|
||||
@@ -4705,7 +4728,7 @@ def setup(app):
|
||||
|
||||
@app.route("/api/favorites/values", methods=["GET"])
|
||||
def favorite_values():
|
||||
options = _get_favorite_slot_options()
|
||||
options = _get_available_favorite_slot_options()
|
||||
eligible_keys = {option["key"] for option in options}
|
||||
slots = normalize_favorite_slots(params.get(FAVORITE_SLOTS_PARAM), params=params, eligible_keys=eligible_keys)
|
||||
return jsonify({"values": _configured_favorite_slot_values(slots)}), 200
|
||||
@@ -4736,7 +4759,7 @@ def setup(app):
|
||||
if not isinstance(raw_slots, list):
|
||||
return jsonify({"error": "Favorite slots must be configured with the Favorites editor."}), 400
|
||||
|
||||
options = _get_favorite_slot_options()
|
||||
options = _get_available_favorite_slot_options()
|
||||
option_by_key = {option["key"]: option for option in options}
|
||||
eligible_keys = set(option_by_key)
|
||||
slots = normalize_favorite_slots(raw_slots, params=params, eligible_keys=eligible_keys)
|
||||
@@ -5099,6 +5122,8 @@ def setup(app):
|
||||
update_starpilot_toggles()
|
||||
|
||||
response = {"message": f"Parameter '{key}' updated successfully."}
|
||||
if key == "RivianAngleControl":
|
||||
response["message"] = "Rivian steering mode updated. The safe channel handoff is in progress."
|
||||
updated = {}
|
||||
if key in PANDA_FIRMWARE_TOGGLE_KEYS:
|
||||
threading.Thread(target=_flash_panda_then_reboot, daemon=True).start()
|
||||
@@ -5178,6 +5203,7 @@ def setup(app):
|
||||
result["HasRadar"] = _get_has_radar()
|
||||
result["VehicleParked"] = _get_vehicle_parked()
|
||||
result["AlphaLongitudinalAvailable"] = _get_alpha_longitudinal_available()
|
||||
result["HasRivianAngleHarness"] = _get_has_rivian_angle_harness()
|
||||
|
||||
return jsonify(_sanitize_json_value(result)), 200
|
||||
|
||||
|
||||
Reference in New Issue
Block a user