mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-31 21:23:49 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e90e13d8a0 | |||
| 562e8b11fd |
Binary file not shown.
@@ -676,7 +676,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"SubaruSNG", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
{"SubaruSNG", {PERSISTENT, BOOL, "1", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SubaruSNGManualParkingBrake", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
{"SubaruSNGManualParkingBrake", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SubaruStopStartOff", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
{"SubaruStopStartOff", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"SubaruAvhOnAtStartup", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
|
||||||
{"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}},
|
{"TacoTune", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||||
{"TeslaCoopSteering", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
{"TeslaCoopSteering", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}},
|
||||||
{"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
{"TestAlert", {CLEAR_ON_MANAGER_START, STRING, "", ""}},
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -76,7 +76,7 @@ A supported vehicle is one that just works when you install a comma device. All
|
|||||||
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt 2019">Buy Here</a></sub></details>|||
|
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM SDGM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 USB-C coupler<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt 2019">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt ASCM Harness 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt ASCM Harness 2017-18">Buy Here</a></sub></details>|<a href="https://youtu.be/QeMCN_4TFfQ" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>||
|
||||||
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|openpilot available[<sup>1</sup>](#footnotes)|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt Camera Harness 2017-18">Buy Here</a></sub></details>|||
|
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|openpilot available[<sup>1</sup>](#footnotes)|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 GM connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt Camera Harness 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Chevrolet|Volt No-ACC 2016-18 (OBD Harness)|Redneck ACC|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-II connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt No-ACC 2016-18 (OBD Harness)">Buy Here</a></sub></details>|||
|
|Chevrolet|Volt No-ACC 2016-18 (OBD-C / L&P Harness)|Redneck ACC|openpilot|0 mph|7 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-II connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chevrolet Volt No-ACC 2016-18 (OBD-C / L&P Harness)">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2017-18">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2017-18">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2019-20">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2019-20">Buy Here</a></sub></details>|||
|
||||||
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2021-23">Buy Here</a></sub></details>|||
|
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Chrysler Pacifica 2021-23">Buy Here</a></sub></details>|||
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
exec python3 "$DIR/scripts/model_release.py" "$@"
|
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
|Chevrolet|Volt 2019|Adaptive Cruise Control (ACC) & LKAS|[Upstream](#upstream)|
|
||||||
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chevrolet|Volt ASCM Harness 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|[Upstream](#upstream)|
|
|Chevrolet|Volt Camera Harness 2017-18|Flashed camera-forward integration with ACC|[Upstream](#upstream)|
|
||||||
|Chevrolet|Volt No-ACC 2016-18 (OBD Harness)|Redneck ACC|[Upstream](#upstream)|
|
|Chevrolet|Volt No-ACC 2016-18 (OBD-C / L&P Harness)|Redneck ACC|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|[Upstream](#upstream)|
|
||||||
|Chrysler|Pacifica 2021-23|All|[Upstream](#upstream)|
|
|Chrysler|Pacifica 2021-23|All|[Upstream](#upstream)|
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class CAR(Platforms):
|
|||||||
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
||||||
)
|
)
|
||||||
CHEVROLET_VOLT_CC = GMPlatformConfig(
|
CHEVROLET_VOLT_CC = GMPlatformConfig(
|
||||||
[GMCarDocs("Chevrolet Volt No-ACC 2016-18 (OBD Harness)", "Redneck ACC", min_enable_speed=0)],
|
[GMCarDocs("Chevrolet Volt No-ACC 2016-18 (OBD-C / L&P Harness)", "Redneck ACC", min_enable_speed=0)],
|
||||||
CHEVROLET_VOLT.specs,
|
CHEVROLET_VOLT.specs,
|
||||||
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
dbc_dict=CHEVROLET_VOLT.dbc_dict,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -128,20 +128,6 @@ def get_test_toggles() -> SimpleNamespace:
|
|||||||
|
|
||||||
|
|
||||||
class TestHyundaiFingerprint:
|
class TestHyundaiFingerprint:
|
||||||
def test_carnival_hev_low_speed_torque_rate_limits(self):
|
|
||||||
CP = CarInterface.get_params(CAR.KIA_CARNIVAL_HEV_4TH_GEN, gen_empty_fingerprint(), [],
|
|
||||||
False, False, False, None)
|
|
||||||
carnival_2025_cp = CarInterface.get_params(CAR.KIA_CARNIVAL_2025, gen_empty_fingerprint(), [],
|
|
||||||
False, False, False, None)
|
|
||||||
|
|
||||||
low_speed = CarControllerParams(CP, 10.0)
|
|
||||||
high_speed = CarControllerParams(CP, 20.0)
|
|
||||||
carnival_2025_low_speed = CarControllerParams(carnival_2025_cp, 10.0)
|
|
||||||
|
|
||||||
assert (low_speed.STEER_DELTA_UP, low_speed.STEER_DELTA_DOWN) == (2, 3)
|
|
||||||
assert (high_speed.STEER_DELTA_UP, high_speed.STEER_DELTA_DOWN) == (2, 3)
|
|
||||||
assert (carnival_2025_low_speed.STEER_DELTA_UP, carnival_2025_low_speed.STEER_DELTA_DOWN) == (10, 8)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("candidate", (CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_CARNIVAL_2025, CAR.KIA_CARNIVAL_HEV_4TH_GEN))
|
@pytest.mark.parametrize("candidate", (CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_CARNIVAL_2025, CAR.KIA_CARNIVAL_HEV_4TH_GEN))
|
||||||
def test_carnival_uses_clean_canfd_lfa_status(self, candidate):
|
def test_carnival_uses_clean_canfd_lfa_status(self, candidate):
|
||||||
assert not preserve_stock_canfd_lfa_status(candidate)
|
assert not preserve_stock_canfd_lfa_status(candidate)
|
||||||
|
|||||||
@@ -45,12 +45,8 @@ class CarControllerParams:
|
|||||||
self.STEER_DRIVER_MULTIPLIER = 2
|
self.STEER_DRIVER_MULTIPLIER = 2
|
||||||
self.STEER_THRESHOLD = 100
|
self.STEER_THRESHOLD = 100
|
||||||
if vEgoRaw < 15.0: # below ~34 mph - more aggressive for tight turns
|
if vEgoRaw < 15.0: # below ~34 mph - more aggressive for tight turns
|
||||||
if CP.carFingerprint == CAR.KIA_CARNIVAL_HEV_4TH_GEN:
|
self.STEER_DELTA_UP = 10
|
||||||
self.STEER_DELTA_UP = 2
|
self.STEER_DELTA_DOWN = 8
|
||||||
self.STEER_DELTA_DOWN = 3
|
|
||||||
else:
|
|
||||||
self.STEER_DELTA_UP = 10
|
|
||||||
self.STEER_DELTA_DOWN = 8
|
|
||||||
else:
|
else:
|
||||||
self.STEER_DELTA_UP = 2
|
self.STEER_DELTA_UP = 2
|
||||||
self.STEER_DELTA_DOWN = 3
|
self.STEER_DELTA_DOWN = 3
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from opendbc.car import Bus, DT_CTRL, make_tester_present_msg, structs
|
|||||||
from opendbc.car.lateral import apply_driver_steer_torque_limits, apply_std_steer_angle_limits, apply_steer_angle_limits_vm, common_fault_avoidance
|
from opendbc.car.lateral import apply_driver_steer_torque_limits, apply_std_steer_angle_limits, apply_steer_angle_limits_vm, common_fault_avoidance
|
||||||
from opendbc.car.interfaces import CarControllerBase
|
from opendbc.car.interfaces import CarControllerBase
|
||||||
from opendbc.car.subaru import subarucan
|
from opendbc.car.subaru import subarucan
|
||||||
from opendbc.car.subaru.values import CAR, DBC, GLOBAL_ES_ADDR, SUBARU_AVH_CARS, SUBARU_STOP_START_CARS, CanBus, CarControllerParams, SubaruFlags
|
from opendbc.car.subaru.values import CAR, DBC, GLOBAL_ES_ADDR, SUBARU_STOP_START_CARS, CanBus, CarControllerParams, SubaruFlags
|
||||||
from opendbc.car.vehicle_model import VehicleModel
|
from opendbc.car.vehicle_model import VehicleModel
|
||||||
|
|
||||||
# FIXME: These limits aren't exact. The real limit is more than likely over a larger time period and
|
# FIXME: These limits aren't exact. The real limit is more than likely over a larger time period and
|
||||||
@@ -37,10 +37,6 @@ _STOP_START_STARTUP_DELAY_FRAMES = 100
|
|||||||
_STOP_START_STARTUP_DEADLINE_FRAMES = 1000
|
_STOP_START_STARTUP_DEADLINE_FRAMES = 1000
|
||||||
_STOP_START_PULSE_FRAMES = 30
|
_STOP_START_PULSE_FRAMES = 30
|
||||||
_STOP_START_PULSE_PERIOD_FRAMES = 5
|
_STOP_START_PULSE_PERIOD_FRAMES = 5
|
||||||
_AVH_STARTUP_DELAY_FRAMES = _STOP_START_STARTUP_DELAY_FRAMES
|
|
||||||
_AVH_STARTUP_DEADLINE_FRAMES = _STOP_START_STARTUP_DEADLINE_FRAMES
|
|
||||||
_AVH_PULSE_FRAMES = _STOP_START_PULSE_FRAMES
|
|
||||||
_AVH_PULSE_PERIOD_FRAMES = _STOP_START_PULSE_PERIOD_FRAMES
|
|
||||||
|
|
||||||
|
|
||||||
def get_safety_CP():
|
def get_safety_CP():
|
||||||
@@ -91,10 +87,6 @@ class CarController(CarControllerBase):
|
|||||||
self.stop_start_initial_state = None
|
self.stop_start_initial_state = None
|
||||||
self.stop_start_counter = 0
|
self.stop_start_counter = 0
|
||||||
self.stop_start_acknowledged = False
|
self.stop_start_acknowledged = False
|
||||||
self.avh_attempted = False
|
|
||||||
self.avh_request_started = False
|
|
||||||
self.avh_request_frame = 0
|
|
||||||
self.avh_counter = 0
|
|
||||||
|
|
||||||
def _stop_start_off_request(self, CC, CS, starpilot_toggles):
|
def _stop_start_off_request(self, CC, CS, starpilot_toggles):
|
||||||
"""Send one bounded Subaru Stop/Start OFF request after ignition.
|
"""Send one bounded Subaru Stop/Start OFF request after ignition.
|
||||||
@@ -151,55 +143,6 @@ class CarController(CarControllerBase):
|
|||||||
self.stop_start_counter = (self.stop_start_counter + 1) % 0x10
|
self.stop_start_counter = (self.stop_start_counter + 1) % 0x10
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def _avh_on_request(self, CC, CS, starpilot_toggles):
|
|
||||||
"""Send one bounded Subaru AVH ON request after ignition.
|
|
||||||
|
|
||||||
The AVH button frame was identified on the 2025 Legacy only. Keep this
|
|
||||||
independent from Stop/Start so the existing Outback request is unchanged.
|
|
||||||
"""
|
|
||||||
if self.CP.carFingerprint not in SUBARU_AVH_CARS or \
|
|
||||||
not getattr(starpilot_toggles, "subaru_avh_on", False) or self.avh_attempted:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if self.frame > _AVH_STARTUP_DEADLINE_FRAMES or getattr(CC, "enabled", False):
|
|
||||||
self.avh_attempted = True
|
|
||||||
return None
|
|
||||||
|
|
||||||
if self.frame < _AVH_STARTUP_DELAY_FRAMES or not getattr(getattr(CS, "out", None), "canValid", True):
|
|
||||||
return None
|
|
||||||
|
|
||||||
out = CS.out
|
|
||||||
if not getattr(out, "standstill", False) or out.gearShifter not in (
|
|
||||||
structs.CarState.GearShifter.park,
|
|
||||||
structs.CarState.GearShifter.neutral,
|
|
||||||
):
|
|
||||||
return None
|
|
||||||
|
|
||||||
avh_msg = getattr(CS, "avh_msg", None)
|
|
||||||
avh_dat = getattr(CS, "avh_dat", None)
|
|
||||||
if not avh_msg or not avh_dat:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not self.avh_request_started:
|
|
||||||
self.avh_request_started = True
|
|
||||||
self.avh_request_frame = self.frame
|
|
||||||
self.avh_counter = (int(avh_msg.get("COUNTER", 0)) + 1) % 0x10
|
|
||||||
|
|
||||||
elapsed = self.frame - self.avh_request_frame
|
|
||||||
if elapsed >= _AVH_PULSE_FRAMES:
|
|
||||||
self.avh_attempted = True
|
|
||||||
return None
|
|
||||||
|
|
||||||
if elapsed % _AVH_PULSE_PERIOD_FRAMES != 0:
|
|
||||||
return None
|
|
||||||
|
|
||||||
msg = subarucan.create_avh_control(
|
|
||||||
self.packer, avh_msg, raw_dat=avh_dat,
|
|
||||||
counter=self.avh_counter, bus=CanBus.alt_for_cp(self.CP),
|
|
||||||
)
|
|
||||||
self.avh_counter = (self.avh_counter + 1) % 0x10
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def _reset_legacy_2025_handoff(self):
|
def _reset_legacy_2025_handoff(self):
|
||||||
self.driver_override = False
|
self.driver_override = False
|
||||||
self.angle_override_confirm_frames = 0
|
self.angle_override_confirm_frames = 0
|
||||||
@@ -473,10 +416,6 @@ class CarController(CarControllerBase):
|
|||||||
if stop_start_msg is not None:
|
if stop_start_msg is not None:
|
||||||
can_sends.append(stop_start_msg)
|
can_sends.append(stop_start_msg)
|
||||||
|
|
||||||
avh_msg = self._avh_on_request(CC, CS, starpilot_toggles)
|
|
||||||
if avh_msg is not None:
|
|
||||||
can_sends.append(avh_msg)
|
|
||||||
|
|
||||||
# *** steering ***
|
# *** steering ***
|
||||||
if (self.frame % self.p.STEER_STEP) == 0:
|
if (self.frame % self.p.STEER_STEP) == 0:
|
||||||
if self.CP.flags & SubaruFlags.LKAS_ANGLE:
|
if self.CP.flags & SubaruFlags.LKAS_ANGLE:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from opendbc.can import CANDefine, CANParser
|
|||||||
from opendbc.car import Bus, structs
|
from opendbc.car import Bus, structs
|
||||||
from opendbc.car.common.conversions import Conversions as CV
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
from opendbc.car.interfaces import CarStateBase
|
from opendbc.car.interfaces import CarStateBase
|
||||||
from opendbc.car.subaru.values import DBC, CanBus, SUBARU_AVH_CARS, SUBARU_STOP_START_CARS, SubaruFlags
|
from opendbc.car.subaru.values import DBC, CanBus, SUBARU_STOP_START_CARS, SubaruFlags
|
||||||
from opendbc.car import CanSignalRateCalculator
|
from opendbc.car import CanSignalRateCalculator
|
||||||
|
|
||||||
|
|
||||||
@@ -18,8 +18,6 @@ class CarState(CarStateBase):
|
|||||||
self.dashlights_msg = {}
|
self.dashlights_msg = {}
|
||||||
self.dashlights_dat = b""
|
self.dashlights_dat = b""
|
||||||
self.stop_start_state = 0
|
self.stop_start_state = 0
|
||||||
self.avh_msg = {}
|
|
||||||
self.avh_dat = b""
|
|
||||||
|
|
||||||
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
|
||||||
cp = can_parsers[Bus.pt]
|
cp = can_parsers[Bus.pt]
|
||||||
@@ -35,11 +33,6 @@ class CarState(CarStateBase):
|
|||||||
self.dashlights_dat = stop_start_cp.vl_raw["Dashlights"]
|
self.dashlights_dat = stop_start_cp.vl_raw["Dashlights"]
|
||||||
self.stop_start_state = stop_start_cp.vl["Engine_Stop_Start"]["STOP_START_STATE"]
|
self.stop_start_state = stop_start_cp.vl["Engine_Stop_Start"]["STOP_START_STATE"]
|
||||||
|
|
||||||
if self.CP.carFingerprint in SUBARU_AVH_CARS:
|
|
||||||
avh_cp = cp_alt if self.CP.flags & SubaruFlags.GLOBAL_GEN2 else cp
|
|
||||||
self.avh_msg = copy.copy(avh_cp.vl["AVH"])
|
|
||||||
self.avh_dat = avh_cp.vl_raw["AVH"]
|
|
||||||
|
|
||||||
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_alt.vl["Throttle_Hybrid"]
|
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_alt.vl["Throttle_Hybrid"]
|
||||||
ret.gasPressed = throttle_msg["Throttle_Pedal"] > 1e-5
|
ret.gasPressed = throttle_msg["Throttle_Pedal"] > 1e-5
|
||||||
if self.CP.flags & SubaruFlags.PREGLOBAL:
|
if self.CP.flags & SubaruFlags.PREGLOBAL:
|
||||||
@@ -163,11 +156,10 @@ class CarState(CarStateBase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_can_parsers(CP):
|
def get_can_parsers(CP):
|
||||||
avh_messages = [("AVH", 0)] if CP.carFingerprint in SUBARU_AVH_CARS else []
|
|
||||||
parsers = {
|
parsers = {
|
||||||
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main_for_cp(CP)),
|
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main_for_cp(CP)),
|
||||||
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.camera),
|
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.camera),
|
||||||
Bus.alt: CANParser(DBC[CP.carFingerprint][Bus.pt], avh_messages, CanBus.alt_for_cp(CP))
|
Bus.alt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.alt_for_cp(CP))
|
||||||
}
|
}
|
||||||
if CP.flags & SubaruFlags.D_PLATFORM:
|
if CP.flags & SubaruFlags.D_PLATFORM:
|
||||||
parsers[Bus.main] = CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main)
|
parsers[Bus.main] = CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from opendbc.car.disable_ecu import disable_ecu
|
|||||||
from opendbc.car.interfaces import CarInterfaceBase
|
from opendbc.car.interfaces import CarInterfaceBase
|
||||||
from opendbc.car.subaru.carcontroller import CarController
|
from opendbc.car.subaru.carcontroller import CarController
|
||||||
from opendbc.car.subaru.carstate import CarState
|
from opendbc.car.subaru.carstate import CarState
|
||||||
from opendbc.car.subaru.values import CAR, CanBus, GLOBAL_ES_ADDR, SUBARU_AVH_CARS, SUBARU_STOP_START_CARS, SubaruFlags, SubaruSafetyFlags
|
from opendbc.car.subaru.values import CAR, CanBus, GLOBAL_ES_ADDR, SUBARU_STOP_START_CARS, SubaruFlags, SubaruSafetyFlags
|
||||||
|
|
||||||
|
|
||||||
class CarInterface(CarInterfaceBase):
|
class CarInterface(CarInterfaceBase):
|
||||||
@@ -42,8 +42,6 @@ class CarInterface(CarInterfaceBase):
|
|||||||
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.D_PLATFORM_CAMERA.value
|
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.D_PLATFORM_CAMERA.value
|
||||||
if candidate in SUBARU_STOP_START_CARS:
|
if candidate in SUBARU_STOP_START_CARS:
|
||||||
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.STOP_START_BUTTON.value
|
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.STOP_START_BUTTON.value
|
||||||
if candidate in SUBARU_AVH_CARS:
|
|
||||||
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.AVH_BUTTON.value
|
|
||||||
if candidate in (CAR.SUBARU_LEGACY_2025, CAR.SUBARU_ASCENT_2023):
|
if candidate in (CAR.SUBARU_LEGACY_2025, CAR.SUBARU_ASCENT_2023):
|
||||||
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.FIXED_ANGLE_LIMITS.value
|
ret.safetyConfigs[0].safetyParam |= SubaruSafetyFlags.FIXED_ANGLE_LIMITS.value
|
||||||
|
|
||||||
|
|||||||
@@ -208,31 +208,6 @@ def create_stop_start_control(packer, dashlights_msg, raw_dat=None, counter=None
|
|||||||
return packer.make_can_msg("Dashlights", bus, values)
|
return packer.make_can_msg("Dashlights", bus, values)
|
||||||
|
|
||||||
|
|
||||||
def create_avh_control(packer, avh_msg, raw_dat=None, counter=None, bus=CanBus.alt):
|
|
||||||
"""Create the supported Subaru Legacy AVH ON request.
|
|
||||||
|
|
||||||
AVH is carried in the live 0x32b frame. Preserve the other bytes and update
|
|
||||||
only the rolling counter, AVH bit, and Subaru additive checksum.
|
|
||||||
"""
|
|
||||||
if raw_dat:
|
|
||||||
dat = bytearray(raw_dat)
|
|
||||||
if len(dat) != 8:
|
|
||||||
raise ValueError(f"AVH frame must be 8 bytes, got {len(dat)}")
|
|
||||||
if counter is None:
|
|
||||||
counter = (int(avh_msg.get("COUNTER", 0)) + 1) % 0x10
|
|
||||||
dat[1] = (dat[1] & 0xF0) | (counter % 0x10)
|
|
||||||
dat[5] |= 0x20 # AVH, big-endian bit 45
|
|
||||||
dat[0] = ((0x32B & 0xFF) + ((0x32B >> 8) & 0xFF) + sum(dat[1:])) & 0xFF
|
|
||||||
return 0x32B, bytes(dat), bus
|
|
||||||
|
|
||||||
values = dict(avh_msg)
|
|
||||||
if counter is None:
|
|
||||||
counter = (int(values.get("COUNTER", 0)) + 1) % 0x10
|
|
||||||
values["COUNTER"] = counter % 0x10
|
|
||||||
values["AVH"] = 1
|
|
||||||
return packer.make_can_msg("AVH", bus, values)
|
|
||||||
|
|
||||||
|
|
||||||
def create_es_brake(packer, frame, es_brake_msg, long_enabled, long_active, brake_value, bus=CanBus.main):
|
def create_es_brake(packer, frame, es_brake_msg, long_enabled, long_active, brake_value, bus=CanBus.main):
|
||||||
values = {s: es_brake_msg[s] for s in [
|
values = {s: es_brake_msg[s] for s in [
|
||||||
"CHECKSUM",
|
"CHECKSUM",
|
||||||
|
|||||||
@@ -194,7 +194,6 @@ def test_outback_2023_uses_d_platform_bus_layout():
|
|||||||
assert CP.flags & SubaruFlags.D_PLATFORM
|
assert CP.flags & SubaruFlags.D_PLATFORM
|
||||||
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM
|
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM
|
||||||
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.STOP_START_BUTTON
|
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.STOP_START_BUTTON
|
||||||
assert not (CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.AVH_BUTTON)
|
|
||||||
assert not (CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.LEGACY_2025_ANGLE_LIMITS)
|
assert not (CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.LEGACY_2025_ANGLE_LIMITS)
|
||||||
assert CanBus.main_for_cp(CP) == CanBus.alt
|
assert CanBus.main_for_cp(CP) == CanBus.alt
|
||||||
assert CanBus.angle_for_cp(CP) == CanBus.main
|
assert CanBus.angle_for_cp(CP) == CanBus.main
|
||||||
@@ -225,21 +224,6 @@ def test_stop_start_inputs_are_captured_for_supported_models(platform):
|
|||||||
assert car_state.stop_start_state == 3
|
assert car_state.stop_start_state == 3
|
||||||
|
|
||||||
|
|
||||||
def test_avh_inputs_are_captured_for_legacy_2025():
|
|
||||||
CP = CarInterface.get_non_essential_params(CAR.SUBARU_LEGACY_2025)
|
|
||||||
car_state = CarState(CP, None)
|
|
||||||
parsers = car_state.get_can_parsers(CP)
|
|
||||||
raw_avh = bytes.fromhex("230f1c4208800000")
|
|
||||||
parsers[Bus.alt].vl["AVH"]["COUNTER"] = 15
|
|
||||||
parsers[Bus.alt].vl["AVH"]["AVH"] = 0
|
|
||||||
parsers[Bus.alt].vl_raw["AVH"] = raw_avh
|
|
||||||
|
|
||||||
car_state.update(parsers, SimpleNamespace(subaru_sng=False))
|
|
||||||
|
|
||||||
assert car_state.avh_msg["COUNTER"] == 15
|
|
||||||
assert car_state.avh_dat == raw_avh
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("platform, expected_bus, start_frame", [
|
@pytest.mark.parametrize("platform, expected_bus, start_frame", [
|
||||||
(CAR.SUBARU_OUTBACK_2023, CanBus.alt, 101),
|
(CAR.SUBARU_OUTBACK_2023, CanBus.alt, 101),
|
||||||
(CAR.SUBARU_LEGACY_2025, CanBus.alt, 401),
|
(CAR.SUBARU_LEGACY_2025, CanBus.alt, 401),
|
||||||
@@ -292,51 +276,6 @@ def test_stop_start_request_is_bounded_and_uses_live_dashlights(platform, expect
|
|||||||
assert controller.stop_start_acknowledged
|
assert controller.stop_start_acknowledged
|
||||||
|
|
||||||
|
|
||||||
def test_avh_request_sets_observed_bit_and_is_bounded():
|
|
||||||
CP = CarInterface.get_non_essential_params(CAR.SUBARU_LEGACY_2025)
|
|
||||||
controller = CarController({}, CP)
|
|
||||||
controller.frame = 101
|
|
||||||
|
|
||||||
class TestActuators:
|
|
||||||
steeringAngleDeg = 0.0
|
|
||||||
|
|
||||||
def as_builder(self):
|
|
||||||
return SimpleNamespace(steeringAngleDeg=self.steeringAngleDeg)
|
|
||||||
|
|
||||||
CC = SimpleNamespace(
|
|
||||||
enabled=False,
|
|
||||||
latActive=False,
|
|
||||||
longActive=False,
|
|
||||||
actuators=TestActuators(),
|
|
||||||
hudControl=SimpleNamespace(leadVisible=False),
|
|
||||||
cruiseControl=SimpleNamespace(cancel=False),
|
|
||||||
)
|
|
||||||
CS = SimpleNamespace(
|
|
||||||
canValid=True,
|
|
||||||
avh_msg={"COUNTER": 15, "AVH": 0},
|
|
||||||
avh_dat=bytes.fromhex("230f1c4208800000"),
|
|
||||||
out=SimpleNamespace(
|
|
||||||
standstill=True,
|
|
||||||
gearShifter=structs.CarState.GearShifter.park,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
toggles = SimpleNamespace(subaru_stop_start_off=False, subaru_avh_on=True, subaru_sng=False)
|
|
||||||
|
|
||||||
_, can_sends = controller.update(CC, CS, 0, toggles)
|
|
||||||
avh_msgs = [msg for msg in can_sends if msg[0] == 0x32b]
|
|
||||||
assert avh_msgs == [(0x32b, bytes.fromhex("34001c4208a00000"), CanBus.alt)]
|
|
||||||
|
|
||||||
parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("AVH", 0)], CanBus.alt)
|
|
||||||
parser.update([(CanBus.alt, avh_msgs)])
|
|
||||||
assert parser.vl["AVH"]["AVH"] == 1
|
|
||||||
assert parser.vl["AVH"]["COUNTER"] == 0
|
|
||||||
|
|
||||||
controller.frame = 131
|
|
||||||
_, can_sends = controller.update(CC, CS, 0, toggles)
|
|
||||||
assert not any(msg[0] == 0x32b for msg in can_sends)
|
|
||||||
assert controller.avh_attempted
|
|
||||||
|
|
||||||
|
|
||||||
def test_legacy_2025_uses_gen2_angle_bus_layout():
|
def test_legacy_2025_uses_gen2_angle_bus_layout():
|
||||||
CP = CarInterface.get_non_essential_params(CAR.SUBARU_LEGACY_2025)
|
CP = CarInterface.get_non_essential_params(CAR.SUBARU_LEGACY_2025)
|
||||||
parsers = CarState.get_can_parsers(CP)
|
parsers = CarState.get_can_parsers(CP)
|
||||||
@@ -348,7 +287,6 @@ def test_legacy_2025_uses_gen2_angle_bus_layout():
|
|||||||
assert not (CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM_CAMERA)
|
assert not (CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM_CAMERA)
|
||||||
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.FIXED_ANGLE_LIMITS
|
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.FIXED_ANGLE_LIMITS
|
||||||
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.STOP_START_BUTTON
|
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.STOP_START_BUTTON
|
||||||
assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.AVH_BUTTON
|
|
||||||
assert CanBus.main_for_cp(CP) == CanBus.main
|
assert CanBus.main_for_cp(CP) == CanBus.main
|
||||||
assert CanBus.angle_for_cp(CP) == CanBus.main
|
assert CanBus.angle_for_cp(CP) == CanBus.main
|
||||||
assert parsers[Bus.pt].bus == CanBus.main
|
assert parsers[Bus.pt].bus == CanBus.main
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ class SubaruSafetyFlags(IntFlag):
|
|||||||
D_PLATFORM_CAMERA = 64
|
D_PLATFORM_CAMERA = 64
|
||||||
FIXED_ANGLE_LIMITS = 128
|
FIXED_ANGLE_LIMITS = 128
|
||||||
STOP_START_BUTTON = 256
|
STOP_START_BUTTON = 256
|
||||||
AVH_BUTTON = 512
|
|
||||||
LEGACY_2025_ANGLE_LIMITS = FIXED_ANGLE_LIMITS
|
LEGACY_2025_ANGLE_LIMITS = FIXED_ANGLE_LIMITS
|
||||||
|
|
||||||
|
|
||||||
@@ -276,10 +275,6 @@ SUBARU_STOP_START_CARS = (
|
|||||||
CAR.SUBARU_LEGACY_2025,
|
CAR.SUBARU_LEGACY_2025,
|
||||||
)
|
)
|
||||||
|
|
||||||
SUBARU_AVH_CARS = (
|
|
||||||
CAR.SUBARU_LEGACY_2025,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||||
p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION)
|
p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION)
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ TransmissionType = structs.CarParams.TransmissionType
|
|||||||
# main-bus SPEED (0x60) is raw counts in the DBC; measured against GPS ground speed.
|
# main-bus SPEED (0x60) is raw counts in the DBC; measured against GPS ground speed.
|
||||||
# Must match VOLVO_SPEED_TO_MS in opendbc/safety/modes/volvo.h.
|
# Must match VOLVO_SPEED_TO_MS in opendbc/safety/modes/volvo.h.
|
||||||
SPEED_TO_MS = 0.003977
|
SPEED_TO_MS = 0.003977
|
||||||
STEERING_PRESSED_THRESHOLD = 2
|
|
||||||
STEERING_DISENGAGE_THRESHOLD = 5
|
|
||||||
|
|
||||||
|
|
||||||
class CarState(CarStateBase):
|
class CarState(CarStateBase):
|
||||||
@@ -77,9 +75,7 @@ class CarState(CarStateBase):
|
|||||||
|
|
||||||
# Driver steering torque feedback (used for driver override detection)
|
# Driver steering torque feedback (used for driver override detection)
|
||||||
ret.steeringTorque = -cp_party.vl['DRIVER_INPUT']['STEERING_DRIVER_INPUT'] # Car right turn is negative, openpilot right turn is positive
|
ret.steeringTorque = -cp_party.vl['DRIVER_INPUT']['STEERING_DRIVER_INPUT'] # Car right turn is negative, openpilot right turn is positive
|
||||||
driver_input = abs(cp_party.vl['DRIVER_INPUT']['STEERING_DRIVER_INPUT'])
|
ret.steeringPressed = abs(cp_party.vl['DRIVER_INPUT']['STEERING_DRIVER_INPUT']) > 2
|
||||||
ret.steeringPressed = driver_input > STEERING_PRESSED_THRESHOLD
|
|
||||||
ret.steeringDisengage = driver_input > STEERING_DISENGAGE_THRESHOLD
|
|
||||||
|
|
||||||
# EPS status - placeholder until actual signal is found
|
# EPS status - placeholder until actual signal is found
|
||||||
self.eps_active = True # Assume EPS is active for now
|
self.eps_active = True # Assume EPS is active for now
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
CM_ "IMPORT _subaru_global.dbc";
|
CM_ "IMPORT _subaru_global.dbc";
|
||||||
|
|
||||||
BO_ 811 AVH: 8 XXX
|
|
||||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
|
||||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
|
||||||
SG_ AVH : 45|1@0+ (1,0) [0|1] "" XXX
|
|
||||||
|
|
||||||
BO_ 72 Transmission: 8 XXX
|
BO_ 72 Transmission: 8 XXX
|
||||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
|||||||
@@ -307,11 +307,6 @@ VAL_ 544 AEB_Status 12 "AEB related" 8 "AEB actuation" 4 "AEB related" 0 "No AEB
|
|||||||
|
|
||||||
CM_ "subaru_global_2017.dbc starts here";
|
CM_ "subaru_global_2017.dbc starts here";
|
||||||
|
|
||||||
BO_ 811 AVH: 8 XXX
|
|
||||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
|
||||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
|
||||||
SG_ AVH : 45|1@0+ (1,0) [0|1] "" XXX
|
|
||||||
|
|
||||||
BO_ 72 Transmission: 8 XXX
|
BO_ 72 Transmission: 8 XXX
|
||||||
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
|
||||||
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
#define MSG_SUBARU_ES_STATIC_1 0x22aU
|
#define MSG_SUBARU_ES_STATIC_1 0x22aU
|
||||||
#define MSG_SUBARU_ES_STATIC_2 0x325U
|
#define MSG_SUBARU_ES_STATIC_2 0x325U
|
||||||
#define MSG_SUBARU_Dashlights 0x390U
|
#define MSG_SUBARU_Dashlights 0x390U
|
||||||
#define MSG_SUBARU_AVH 0x32bU
|
|
||||||
|
|
||||||
#define SUBARU_MAIN_BUS 0U
|
#define SUBARU_MAIN_BUS 0U
|
||||||
#define SUBARU_ALT_BUS 1U
|
#define SUBARU_ALT_BUS 1U
|
||||||
@@ -66,13 +65,6 @@
|
|||||||
#define SUBARU_STOP_START_TX_MSGS(bus) \
|
#define SUBARU_STOP_START_TX_MSGS(bus) \
|
||||||
{MSG_SUBARU_Dashlights, bus, 8, .check_relay = false}, \
|
{MSG_SUBARU_Dashlights, bus, 8, .check_relay = false}, \
|
||||||
|
|
||||||
#define SUBARU_AVH_TX_MSGS(bus) \
|
|
||||||
{MSG_SUBARU_AVH, bus, 8, .check_relay = false}, \
|
|
||||||
|
|
||||||
#define SUBARU_STOP_START_AVH_TX_MSGS(bus) \
|
|
||||||
SUBARU_STOP_START_TX_MSGS(bus) \
|
|
||||||
SUBARU_AVH_TX_MSGS(bus)
|
|
||||||
|
|
||||||
#define SUBARU_COMMON_LONG_TX_MSGS(alt_bus) \
|
#define SUBARU_COMMON_LONG_TX_MSGS(alt_bus) \
|
||||||
{MSG_SUBARU_ES_Distance, alt_bus, 8, .check_relay = true}, \
|
{MSG_SUBARU_ES_Distance, alt_bus, 8, .check_relay = true}, \
|
||||||
{MSG_SUBARU_ES_Brake, alt_bus, 8, .check_relay = true}, \
|
{MSG_SUBARU_ES_Brake, alt_bus, 8, .check_relay = true}, \
|
||||||
@@ -121,7 +113,6 @@ static bool subaru_lkas_angle = false;
|
|||||||
static bool subaru_d_platform = false;
|
static bool subaru_d_platform = false;
|
||||||
static bool subaru_fixed_angle_limits = false;
|
static bool subaru_fixed_angle_limits = false;
|
||||||
static bool subaru_stop_start_button = false;
|
static bool subaru_stop_start_button = false;
|
||||||
static bool subaru_avh_button = false;
|
|
||||||
|
|
||||||
static uint32_t subaru_get_checksum(const CANPacket_t *msg) {
|
static uint32_t subaru_get_checksum(const CANPacket_t *msg) {
|
||||||
return (uint8_t)msg->data[0];
|
return (uint8_t)msg->data[0];
|
||||||
@@ -306,13 +297,6 @@ static bool subaru_tx_hook(const CANPacket_t *msg) {
|
|||||||
violation |= subaru_get_checksum(msg) != subaru_compute_checksum(msg);
|
violation |= subaru_get_checksum(msg) != subaru_compute_checksum(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->addr == MSG_SUBARU_AVH) {
|
|
||||||
violation |= !subaru_avh_button;
|
|
||||||
violation |= msg->bus != (subaru_gen2 ? SUBARU_ALT_BUS : SUBARU_MAIN_BUS);
|
|
||||||
violation |= !GET_BIT(msg, 45U);
|
|
||||||
violation |= subaru_get_checksum(msg) != subaru_compute_checksum(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (violation){
|
if (violation){
|
||||||
tx = false;
|
tx = false;
|
||||||
}
|
}
|
||||||
@@ -363,12 +347,6 @@ static safety_config subaru_init(uint16_t param) {
|
|||||||
SUBARU_STOP_START_TX_MSGS(SUBARU_ALT_BUS)
|
SUBARU_STOP_START_TX_MSGS(SUBARU_ALT_BUS)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CanMsg SUBARU_GEN2_LKAS_ANGLE_STOP_START_AVH_TX_MSGS[] = {
|
|
||||||
SUBARU_BASE_TX_MSGS(SUBARU_ALT_BUS, MSG_SUBARU_ES_LKAS_ANGLE)
|
|
||||||
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
|
||||||
SUBARU_STOP_START_AVH_TX_MSGS(SUBARU_ALT_BUS)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const CanMsg SUBARU_D_PLATFORM_ANGLE_MAIN_TX_MSGS[] = {
|
static const CanMsg SUBARU_D_PLATFORM_ANGLE_MAIN_TX_MSGS[] = {
|
||||||
SUBARU_D_PLATFORM_ANGLE_TX_MSGS(SUBARU_MAIN_BUS)
|
SUBARU_D_PLATFORM_ANGLE_TX_MSGS(SUBARU_MAIN_BUS)
|
||||||
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
||||||
@@ -380,12 +358,6 @@ static safety_config subaru_init(uint16_t param) {
|
|||||||
SUBARU_STOP_START_TX_MSGS(SUBARU_ALT_BUS)
|
SUBARU_STOP_START_TX_MSGS(SUBARU_ALT_BUS)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CanMsg SUBARU_D_PLATFORM_ANGLE_STOP_START_AVH_MAIN_TX_MSGS[] = {
|
|
||||||
SUBARU_D_PLATFORM_ANGLE_TX_MSGS(SUBARU_MAIN_BUS)
|
|
||||||
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
|
||||||
SUBARU_STOP_START_AVH_TX_MSGS(SUBARU_ALT_BUS)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const CanMsg SUBARU_D_PLATFORM_ANGLE_CAMERA_TX_MSGS[] = {
|
static const CanMsg SUBARU_D_PLATFORM_ANGLE_CAMERA_TX_MSGS[] = {
|
||||||
SUBARU_D_PLATFORM_ANGLE_TX_MSGS(SUBARU_CAM_BUS)
|
SUBARU_D_PLATFORM_ANGLE_TX_MSGS(SUBARU_CAM_BUS)
|
||||||
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS)
|
||||||
@@ -433,9 +405,6 @@ static safety_config subaru_init(uint16_t param) {
|
|||||||
const uint16_t SUBARU_PARAM_STOP_START_BUTTON = 256;
|
const uint16_t SUBARU_PARAM_STOP_START_BUTTON = 256;
|
||||||
subaru_stop_start_button = GET_FLAG(param, SUBARU_PARAM_STOP_START_BUTTON);
|
subaru_stop_start_button = GET_FLAG(param, SUBARU_PARAM_STOP_START_BUTTON);
|
||||||
|
|
||||||
const uint16_t SUBARU_PARAM_AVH_BUTTON = 512;
|
|
||||||
subaru_avh_button = GET_FLAG(param, SUBARU_PARAM_AVH_BUTTON);
|
|
||||||
|
|
||||||
#ifdef ALLOW_DEBUG
|
#ifdef ALLOW_DEBUG
|
||||||
const uint16_t SUBARU_PARAM_LONGITUDINAL = 2;
|
const uint16_t SUBARU_PARAM_LONGITUDINAL = 2;
|
||||||
subaru_longitudinal = GET_FLAG(param, SUBARU_PARAM_LONGITUDINAL);
|
subaru_longitudinal = GET_FLAG(param, SUBARU_PARAM_LONGITUDINAL);
|
||||||
@@ -443,12 +412,10 @@ static safety_config subaru_init(uint16_t param) {
|
|||||||
|
|
||||||
safety_config ret;
|
safety_config ret;
|
||||||
if (subaru_lkas_angle) {
|
if (subaru_lkas_angle) {
|
||||||
ret = subaru_d_platform ? (subaru_stop_start_button ? (subaru_avh_button ? BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_STOP_START_AVH_MAIN_TX_MSGS) : \
|
ret = subaru_d_platform ? (subaru_stop_start_button ? BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_STOP_START_MAIN_TX_MSGS) : \
|
||||||
BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_STOP_START_MAIN_TX_MSGS)) : \
|
|
||||||
(subaru_d_platform_camera ? BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_CAMERA_TX_MSGS) : \
|
(subaru_d_platform_camera ? BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_CAMERA_TX_MSGS) : \
|
||||||
BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_MAIN_TX_MSGS))) : \
|
BUILD_SAFETY_CFG(subaru_d_platform_angle_rx_checks, SUBARU_D_PLATFORM_ANGLE_MAIN_TX_MSGS))) : \
|
||||||
subaru_gen2 ? (subaru_stop_start_button ? (subaru_avh_button ? BUILD_SAFETY_CFG(subaru_gen2_lkas_angle_rx_checks, SUBARU_GEN2_LKAS_ANGLE_STOP_START_AVH_TX_MSGS) : \
|
subaru_gen2 ? (subaru_stop_start_button ? BUILD_SAFETY_CFG(subaru_gen2_lkas_angle_rx_checks, SUBARU_GEN2_LKAS_ANGLE_STOP_START_TX_MSGS) : \
|
||||||
BUILD_SAFETY_CFG(subaru_gen2_lkas_angle_rx_checks, SUBARU_GEN2_LKAS_ANGLE_STOP_START_TX_MSGS)) : \
|
|
||||||
BUILD_SAFETY_CFG(subaru_gen2_lkas_angle_rx_checks, SUBARU_GEN2_LKAS_ANGLE_TX_MSGS)) : \
|
BUILD_SAFETY_CFG(subaru_gen2_lkas_angle_rx_checks, SUBARU_GEN2_LKAS_ANGLE_TX_MSGS)) : \
|
||||||
BUILD_SAFETY_CFG(subaru_lkas_angle_rx_checks, SUBARU_LKAS_ANGLE_TX_MSGS);
|
BUILD_SAFETY_CFG(subaru_lkas_angle_rx_checks, SUBARU_LKAS_ANGLE_TX_MSGS);
|
||||||
} else if (subaru_gen2) {
|
} else if (subaru_gen2) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#define VOLVO_ANGLE_DEG_TO_CAN 17.869907f
|
#define VOLVO_ANGLE_DEG_TO_CAN 17.869907f
|
||||||
#define VOLVO_MAX_ANGLE_CAN 9650
|
#define VOLVO_MAX_ANGLE_CAN 9650
|
||||||
#define VOLVO_RELAY_ANGLE_TOLERANCE 54 // approximately 3 degrees
|
#define VOLVO_RELAY_ANGLE_TOLERANCE 54 // approximately 3 degrees
|
||||||
#define VOLVO_DRIVER_OVERRIDE 5
|
#define VOLVO_DRIVER_OVERRIDE 2
|
||||||
|
|
||||||
|
|
||||||
// CAN bus definitions for Volvo
|
// CAN bus definitions for Volvo
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class SubaruMsg(enum.IntEnum):
|
|||||||
ES_STATIC_1 = 0x22a
|
ES_STATIC_1 = 0x22a
|
||||||
ES_STATIC_2 = 0x325
|
ES_STATIC_2 = 0x325
|
||||||
Dashlights = 0x390
|
Dashlights = 0x390
|
||||||
AVH = 0x32b
|
|
||||||
|
|
||||||
|
|
||||||
SUBARU_MAIN_BUS = 0
|
SUBARU_MAIN_BUS = 0
|
||||||
@@ -386,20 +385,6 @@ class TestSubaruGen2FixedAngleStopStartSafety(TestSubaruGen2FixedAngleSafety):
|
|||||||
self.assertFalse(self._tx(self._stop_start_msg(False)))
|
self.assertFalse(self._tx(self._stop_start_msg(False)))
|
||||||
|
|
||||||
|
|
||||||
class TestSubaruGen2FixedAngleStopStartAvhSafety(TestSubaruGen2FixedAngleStopStartSafety):
|
|
||||||
FLAGS = TestSubaruGen2FixedAngleStopStartSafety.FLAGS | SubaruSafetyFlags.AVH_BUTTON
|
|
||||||
TX_MSGS = TestSubaruGen2FixedAngleStopStartSafety.TX_MSGS + [[SubaruMsg.AVH, SUBARU_ALT_BUS]]
|
|
||||||
|
|
||||||
def _avh_msg(self, pressed):
|
|
||||||
return self.packer.make_can_msg_safety(
|
|
||||||
"AVH", SUBARU_ALT_BUS, {"COUNTER": 0, "AVH": pressed},
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_avh_tx_requires_pressed_bit(self):
|
|
||||||
self.assertTrue(self._tx(self._avh_msg(True)))
|
|
||||||
self.assertFalse(self._tx(self._avh_msg(False)))
|
|
||||||
|
|
||||||
|
|
||||||
class TestSubaruDPlatformAngleSafety(TestSubaruStockLongitudinalSafetyBase, TestSubaruAngleSafetyBase):
|
class TestSubaruDPlatformAngleSafety(TestSubaruStockLongitudinalSafetyBase, TestSubaruAngleSafetyBase):
|
||||||
FLAGS = SubaruSafetyFlags.GEN2 | SubaruSafetyFlags.LKAS_ANGLE | SubaruSafetyFlags.D_PLATFORM
|
FLAGS = SubaruSafetyFlags.GEN2 | SubaruSafetyFlags.LKAS_ANGLE | SubaruSafetyFlags.D_PLATFORM
|
||||||
ALT_MAIN_BUS = SUBARU_ALT_BUS
|
ALT_MAIN_BUS = SUBARU_ALT_BUS
|
||||||
|
|||||||
@@ -201,19 +201,10 @@ class TestVolvoSafetyBase(common.CarSafetyTest):
|
|||||||
self.assertFalse(self._tx(invalid))
|
self.assertFalse(self._tx(invalid))
|
||||||
|
|
||||||
def test_driver_override_disengages_controls(self):
|
def test_driver_override_disengages_controls(self):
|
||||||
def driver_input_msg(value):
|
|
||||||
return self.mid_packer.make_can_msg_safety(
|
|
||||||
"DRIVER_INPUT", VOLVO_PARTY_BUS, {"STEERING_DRIVER_INPUT": value})
|
|
||||||
|
|
||||||
for value in (2, 3, 5):
|
|
||||||
self._rx(driver_input_msg(0))
|
|
||||||
self.safety.set_controls_allowed(True)
|
|
||||||
self._rx(driver_input_msg(value))
|
|
||||||
self.assertTrue(self.safety.get_controls_allowed(), f"unexpected disengage at {value=}")
|
|
||||||
|
|
||||||
self._rx(driver_input_msg(0))
|
|
||||||
self.safety.set_controls_allowed(True)
|
self.safety.set_controls_allowed(True)
|
||||||
self._rx(driver_input_msg(6))
|
msg = self.mid_packer.make_can_msg_safety(
|
||||||
|
"DRIVER_INPUT", VOLVO_PARTY_BUS, {"STEERING_DRIVER_INPUT": 6})
|
||||||
|
self._rx(msg)
|
||||||
self.assertFalse(self.safety.get_controls_allowed())
|
self.assertFalse(self.safety.get_controls_allowed())
|
||||||
|
|
||||||
# ---- Volvo-specific consistency tests ----
|
# ---- Volvo-specific consistency tests ----
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
|||||||
extern const uint8_t gitversion[19];
|
extern const uint8_t gitversion[19];
|
||||||
const uint8_t gitversion[19] = "DEV-3fb2bcdc-DEBUG";
|
const uint8_t gitversion[19] = "DEV-ec64617f-DEBUG";
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
DEV-3fb2bcdc-DEBUG
|
DEV-ec64617f-DEBUG
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# Model Release Tool
|
|
||||||
|
|
||||||
`./scripts/model_release.py` automates the single-supercombo release path:
|
|
||||||
|
|
||||||
1. Paste the model bot message.
|
|
||||||
2. The tool parses the branch, ONNX path, model name, release date, model ID, and commit SHAs.
|
|
||||||
3. It scans every listed upstream commit for `tinygrad`, `modeld`, or Chestnut runtime changes.
|
|
||||||
4. It downloads the Git LFS object without loading it into shell variables.
|
|
||||||
5. It asks for the comma IP, transfers the ONNX, and runs the device compiler.
|
|
||||||
6. It verifies the returned PKL or multipart checksum.
|
|
||||||
7. It uploads `models/<id>/`, `onnx/<id>/`, and `manifests/` to Hugging Face.
|
|
||||||
8. It pushes GitHub one artifact part per commit and the manifest last.
|
|
||||||
|
|
||||||
Run interactively:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./scripts/model_release.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Paste the complete bot message, press `Ctrl-D`, then enter the comma IP. The
|
|
||||||
default runtime behavior version is `v16`; the `Model vN` line is treated as
|
|
||||||
the model iteration/name, not the runtime behavior version. Override an
|
|
||||||
ambiguous ID with `--model-id`, or the runtime contract with
|
|
||||||
`--behavior-version v15`.
|
|
||||||
|
|
||||||
For the normal model bot flow, a commit SHA alone is also accepted:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./modelgrab f877d7a0ccc3cce943c76e285214c020cd65c899
|
|
||||||
```
|
|
||||||
|
|
||||||
The tool resolves the commit's changed driving ONNX, associated pull-request
|
|
||||||
branch/title, GPU status, and commit date through GitHub. If GitHub cannot
|
|
||||||
associate a human model title with the SHA, it derives the name from the ONNX
|
|
||||||
filename; use `--model-id` when an exact local naming convention is required.
|
|
||||||
|
|
||||||
Useful non-interactive form:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./scripts/model_release.py \
|
|
||||||
--text-file release-message.txt \
|
|
||||||
--ip 192.168.3.110
|
|
||||||
```
|
|
||||||
|
|
||||||
The tool refuses `192.168.3.109`. It also stops before downloading or compiling
|
|
||||||
if any supplied commit changes runtime code. Review the warning first, then
|
|
||||||
rerun with `--allow-runtime-changes` only after Firestar approves it.
|
|
||||||
|
|
||||||
The default resources checkout is `~/StarPilot-Resources` on branch `Models`.
|
|
||||||
It must be clean and synchronized before starting. The default Hugging Face
|
|
||||||
bucket is `firestar4430/StarPilot-Resources`; authenticate with `hf auth login`
|
|
||||||
before use. Use `--dry-run` to test parsing and the runtime scan without
|
|
||||||
touching the device or either resource store.
|
|
||||||
|
|
||||||
Failed runs leave the source, compiled parts, logs, and result JSON in the
|
|
||||||
workspace so the cause can be inspected. A rerun requires `--force` when the
|
|
||||||
same source path already exists.
|
|
||||||
@@ -1,786 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Release one upstream model through the device compiler and resource stores.
|
|
||||||
|
|
||||||
The command is intentionally fail-closed when the supplied upstream commits
|
|
||||||
touch tinygrad or modeld runtime code. A model source update is safe to build
|
|
||||||
only after that runtime change has been reviewed separately.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import datetime as dt
|
|
||||||
import hashlib
|
|
||||||
import ipaddress
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import shlex
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import urllib.error
|
|
||||||
import urllib.parse
|
|
||||||
import urllib.request
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from typing import Any
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
OPENPILOT_REPO = "commaai/openpilot"
|
|
||||||
RESOURCES_REPO = os.environ.get("STARPILOT_RESOURCES_REPO", "firestar5683/StarPilot-Resources")
|
|
||||||
HF_BUCKET = os.environ.get("STARPILOT_HF_BUCKET", "firestar4430/StarPilot-Resources")
|
|
||||||
RESOURCE_BRANCH = "Models"
|
|
||||||
MANIFEST_VERSION = "v24"
|
|
||||||
DEFAULT_BEHAVIOR_VERSION = "v16"
|
|
||||||
DEVICE_ROOT = "/data/openpilot"
|
|
||||||
REPOSITORY_FILE_LIMIT = 100_000_000
|
|
||||||
LFS_POINTER_PREFIX = b"version https://git-lfs.github.com/spec/v1"
|
|
||||||
CHUNK_SUFFIX_RE = re.compile(r"\.p\d{2}$")
|
|
||||||
SHA_RE = re.compile(r"(?<![0-9a-f])([0-9a-f]{40})(?![0-9a-f])", re.IGNORECASE)
|
|
||||||
DATE_RE = re.compile(r"([A-Za-z]+\s+\d{1,2},\s+\d{4})")
|
|
||||||
MODEL_ID_RE = re.compile(r"^[a-z0-9][a-z0-9_-]*$")
|
|
||||||
|
|
||||||
RUNTIME_PATH_PREFIXES = (
|
|
||||||
"tinygrad/",
|
|
||||||
"tinygrad_repo/",
|
|
||||||
"openpilot/tinygrad/",
|
|
||||||
"openpilot/tinygrad_repo/",
|
|
||||||
"selfdrive/modeld/",
|
|
||||||
"openpilot/selfdrive/modeld/",
|
|
||||||
"system/hardware/chestnut/",
|
|
||||||
"openpilot/system/hardware/chestnut/",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ReleaseError(RuntimeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ReleaseInfo:
|
|
||||||
model_id: str
|
|
||||||
display_name: str
|
|
||||||
release_date: str
|
|
||||||
branch: str
|
|
||||||
source_ref: str
|
|
||||||
source_path: str
|
|
||||||
input_format: str
|
|
||||||
behavior_version: str
|
|
||||||
uses_external_gpu: bool
|
|
||||||
commits: list[str]
|
|
||||||
model_iteration: str
|
|
||||||
|
|
||||||
|
|
||||||
def default_workspace() -> Path:
|
|
||||||
t5 = Path("/Volumes/T5")
|
|
||||||
if t5.is_dir():
|
|
||||||
return t5 / "StarPilot-Model-Releases"
|
|
||||||
return Path.home() / "Desktop" / "StarPilot-Model-Releases"
|
|
||||||
|
|
||||||
|
|
||||||
def run(command: list[str], *, cwd: Path | None = None, capture: bool = False) -> subprocess.CompletedProcess:
|
|
||||||
print("$ " + " ".join(shlex.quote(part) for part in command))
|
|
||||||
return subprocess.run(
|
|
||||||
command,
|
|
||||||
cwd=cwd,
|
|
||||||
check=True,
|
|
||||||
text=capture,
|
|
||||||
capture_output=capture,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def sha256_file(path: Path) -> str:
|
|
||||||
digest = hashlib.sha256()
|
|
||||||
with path.open("rb") as source:
|
|
||||||
for chunk in iter(lambda: source.read(1024 * 1024), b""):
|
|
||||||
digest.update(chunk)
|
|
||||||
return digest.hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def http_request(url: str, *, method: str = "GET", payload: bytes | None = None, headers: dict[str, str] | None = None):
|
|
||||||
request_headers = {"User-Agent": "StarPilot-model-release/1.0", **(headers or {})}
|
|
||||||
token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
|
|
||||||
if token and "api.github.com" in url:
|
|
||||||
request_headers["Authorization"] = f"Bearer {token}"
|
|
||||||
request = urllib.request.Request(url, data=payload, headers=request_headers, method=method)
|
|
||||||
try:
|
|
||||||
return urllib.request.urlopen(request, timeout=30)
|
|
||||||
except urllib.error.HTTPError as error:
|
|
||||||
detail = error.read(500).decode("utf-8", errors="replace")
|
|
||||||
raise ReleaseError(f"HTTP {error.code} from {url}: {detail}") from error
|
|
||||||
except urllib.error.URLError as error:
|
|
||||||
raise ReleaseError(f"Unable to reach {url}: {error.reason}") from error
|
|
||||||
|
|
||||||
|
|
||||||
def get_json_value(url: str) -> Any:
|
|
||||||
with http_request(url, headers={"Accept": "application/vnd.github+json"}) as response:
|
|
||||||
try:
|
|
||||||
return json.loads(response.read().decode("utf-8"))
|
|
||||||
except json.JSONDecodeError as error:
|
|
||||||
raise ReleaseError(f"Invalid JSON response from {url}") from error
|
|
||||||
|
|
||||||
|
|
||||||
def get_json(url: str) -> dict:
|
|
||||||
payload = get_json_value(url)
|
|
||||||
if not isinstance(payload, dict):
|
|
||||||
raise ReleaseError(f"Unexpected JSON response from {url}")
|
|
||||||
return payload
|
|
||||||
|
|
||||||
|
|
||||||
def parse_lfs_pointer(data: bytes) -> tuple[str, int] | None:
|
|
||||||
if not data.startswith(LFS_POINTER_PREFIX):
|
|
||||||
return None
|
|
||||||
fields: dict[str, str] = {}
|
|
||||||
for line in data.decode("ascii", errors="strict").splitlines():
|
|
||||||
if " " in line:
|
|
||||||
key, value = line.split(" ", 1)
|
|
||||||
fields[key] = value
|
|
||||||
oid = fields.get("oid", "").removeprefix("sha256:")
|
|
||||||
size = fields.get("size", "")
|
|
||||||
if not re.fullmatch(r"[0-9a-f]{64}", oid) or not size.isdigit():
|
|
||||||
raise ReleaseError("Malformed Git LFS pointer")
|
|
||||||
return oid, int(size)
|
|
||||||
|
|
||||||
|
|
||||||
def stream_response(response, destination: Path, prefix: bytes = b"") -> tuple[int, str]:
|
|
||||||
digest = hashlib.sha256()
|
|
||||||
size = 0
|
|
||||||
with destination.open("wb") as output:
|
|
||||||
if prefix:
|
|
||||||
output.write(prefix)
|
|
||||||
digest.update(prefix)
|
|
||||||
size += len(prefix)
|
|
||||||
for chunk in iter(lambda: response.read(1024 * 1024), b""):
|
|
||||||
output.write(chunk)
|
|
||||||
digest.update(chunk)
|
|
||||||
size += len(chunk)
|
|
||||||
return size, digest.hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def download_lfs_object(oid: str, expected_size: int, ref: str, destination: Path) -> tuple[int, str]:
|
|
||||||
batch_url = f"https://github.com/{OPENPILOT_REPO}.git/info/lfs/objects/batch"
|
|
||||||
payload = json.dumps({
|
|
||||||
"operation": "download",
|
|
||||||
"transfers": ["basic"],
|
|
||||||
"objects": [{"oid": oid, "size": expected_size}],
|
|
||||||
"ref": {"name": ref},
|
|
||||||
}).encode("utf-8")
|
|
||||||
with http_request(
|
|
||||||
batch_url,
|
|
||||||
method="POST",
|
|
||||||
payload=payload,
|
|
||||||
headers={"Accept": "application/vnd.git-lfs+json", "Content-Type": "application/vnd.git-lfs+json"},
|
|
||||||
) as response:
|
|
||||||
batch = json.loads(response.read().decode("utf-8"))
|
|
||||||
|
|
||||||
objects = batch.get("objects", []) if isinstance(batch, dict) else []
|
|
||||||
if not objects or "error" in objects[0]:
|
|
||||||
raise ReleaseError(f"Git LFS download was not available for {oid}")
|
|
||||||
action = objects[0].get("actions", {}).get("download")
|
|
||||||
if not action or not action.get("href"):
|
|
||||||
raise ReleaseError(f"Git LFS returned no download action for {oid}")
|
|
||||||
headers = {str(key): str(value) for key, value in action.get("header", {}).items()}
|
|
||||||
with http_request(action["href"], headers=headers) as response:
|
|
||||||
size, digest = stream_response(response, destination)
|
|
||||||
if size != expected_size or digest != oid:
|
|
||||||
raise ReleaseError(f"LFS object verification failed: size {size}/{expected_size}, sha256 {digest}/{oid}")
|
|
||||||
return size, digest
|
|
||||||
|
|
||||||
|
|
||||||
def download_source(ref: str, git_path: str, destination: Path, force: bool) -> dict:
|
|
||||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
if destination.exists() and not force:
|
|
||||||
raise ReleaseError(f"Source already exists: {destination}; use --force to fetch the requested commit")
|
|
||||||
|
|
||||||
encoded_ref = urllib.parse.quote(ref, safe="/")
|
|
||||||
encoded_path = "/".join(urllib.parse.quote(part, safe="") for part in git_path.split("/"))
|
|
||||||
raw_url = f"https://raw.githubusercontent.com/{OPENPILOT_REPO}/{encoded_ref}/{encoded_path}"
|
|
||||||
temporary = destination.with_name(destination.name + ".part")
|
|
||||||
temporary.unlink(missing_ok=True)
|
|
||||||
|
|
||||||
with http_request(raw_url) as response:
|
|
||||||
prefix = response.read(512)
|
|
||||||
pointer = parse_lfs_pointer(prefix)
|
|
||||||
if pointer is None:
|
|
||||||
size, digest = stream_response(response, temporary, prefix)
|
|
||||||
else:
|
|
||||||
temporary.unlink(missing_ok=True)
|
|
||||||
size, digest = download_lfs_object(pointer[0], pointer[1], ref, temporary)
|
|
||||||
|
|
||||||
temporary.replace(destination)
|
|
||||||
print(f"Downloaded source: {size} bytes, sha256 {digest}")
|
|
||||||
return {"path": str(destination), "size": size, "sha256": digest, "url": raw_url, "ref": ref, "git_path": git_path}
|
|
||||||
|
|
||||||
|
|
||||||
def clean_markdown(value: str) -> str:
|
|
||||||
value = re.sub(r"\[([^]]+)\]\([^)]*\)", r"\1", value)
|
|
||||||
value = re.sub(r"[*_`]+", "", value)
|
|
||||||
return " ".join(value.split()).strip()
|
|
||||||
|
|
||||||
|
|
||||||
def slug_model_id(name: str) -> str:
|
|
||||||
tokens = re.findall(r"[a-z0-9]+", name.lower())
|
|
||||||
return "".join(tokens)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_release_date(text: str) -> str | None:
|
|
||||||
match = DATE_RE.search(text)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
for fmt in ("%B %d, %Y", "%b %d, %Y"):
|
|
||||||
try:
|
|
||||||
return dt.datetime.strptime(match.group(1), fmt).date().isoformat()
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def commit_local_date(payload: dict) -> str:
|
|
||||||
commit_data = payload.get("commit", {})
|
|
||||||
for author_key in ("committer", "author"):
|
|
||||||
timestamp = commit_data.get(author_key, {}).get("date") if isinstance(commit_data, dict) else None
|
|
||||||
if not timestamp:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
return dt.datetime.fromisoformat(str(timestamp).replace("Z", "+00:00")).astimezone().date().isoformat()
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
return dt.date.today().isoformat()
|
|
||||||
|
|
||||||
|
|
||||||
def source_name_from_path(source_path: str) -> str:
|
|
||||||
stem = Path(source_path).stem
|
|
||||||
stem = re.sub(r"^(?:big_)?driving_supercombo$", "", stem, flags=re.IGNORECASE)
|
|
||||||
stem = re.sub(r"_driving_(?:supercombo|vision|policy)$", "", stem, flags=re.IGNORECASE)
|
|
||||||
stem = stem.strip("_-")
|
|
||||||
return stem.replace("_", " ").replace("-", " ").title() or "Model"
|
|
||||||
|
|
||||||
|
|
||||||
def select_model_source(files: list[Any], commit: str) -> str:
|
|
||||||
paths = [
|
|
||||||
str(item.get("filename", ""))
|
|
||||||
for item in files
|
|
||||||
if isinstance(item, dict) and str(item.get("filename", "")).lower().endswith(".onnx")
|
|
||||||
]
|
|
||||||
preferred = [path for path in paths if Path(path).name.lower().endswith("driving_supercombo.onnx")]
|
|
||||||
candidates = preferred or paths
|
|
||||||
if len(candidates) != 1:
|
|
||||||
if not candidates:
|
|
||||||
raise ReleaseError(f"Commit {commit} does not change a driving ONNX file")
|
|
||||||
raise ReleaseError(f"Commit {commit} changes multiple ONNX files; provide the full bot message to disambiguate")
|
|
||||||
return candidates[0]
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_commit_release(commit: str, model_id_override: str | None, behavior_version: str) -> ReleaseInfo:
|
|
||||||
commit_payload = get_json(f"https://api.github.com/repos/{OPENPILOT_REPO}/commits/{commit}")
|
|
||||||
files = commit_payload.get("files", [])
|
|
||||||
if not isinstance(files, list):
|
|
||||||
raise ReleaseError(f"GitHub returned no file list for commit {commit}")
|
|
||||||
source_path = select_model_source(files, commit)
|
|
||||||
|
|
||||||
branch = ""
|
|
||||||
display_name = ""
|
|
||||||
pulls = get_json_value(f"https://api.github.com/repos/{OPENPILOT_REPO}/commits/{commit}/pulls")
|
|
||||||
if isinstance(pulls, list):
|
|
||||||
for pull in pulls:
|
|
||||||
if not isinstance(pull, dict):
|
|
||||||
continue
|
|
||||||
head = pull.get("head", {})
|
|
||||||
if isinstance(head, dict) and str(head.get("sha", "")).lower() == commit:
|
|
||||||
branch = str(head.get("ref") or "")
|
|
||||||
display_name = clean_markdown(str(pull.get("title") or ""))
|
|
||||||
break
|
|
||||||
|
|
||||||
if not branch:
|
|
||||||
branches = get_json_value(
|
|
||||||
f"https://api.github.com/repos/{OPENPILOT_REPO}/commits/{commit}/branches-where-head"
|
|
||||||
)
|
|
||||||
if isinstance(branches, list):
|
|
||||||
names = [str(item.get("name")) for item in branches if isinstance(item, dict) and item.get("name")]
|
|
||||||
branch = next((name for name in names if name.lower() != "master"), names[0] if names else "")
|
|
||||||
branch = branch or commit
|
|
||||||
|
|
||||||
if not display_name or display_name.lower() in {"big", "model", "update model"}:
|
|
||||||
display_name = source_name_from_path(source_path)
|
|
||||||
model_id = model_id_override or slug_model_id(display_name)
|
|
||||||
if not MODEL_ID_RE.fullmatch(model_id):
|
|
||||||
raise ReleaseError(f"Invalid model ID {model_id!r}; use lowercase letters, digits, '-' or '_'")
|
|
||||||
uses_external_gpu = Path(source_path).name.lower().startswith("big_")
|
|
||||||
model_iteration_match = re.search(r"\b(v\d+)\b", display_name, flags=re.IGNORECASE)
|
|
||||||
return ReleaseInfo(
|
|
||||||
model_id=model_id,
|
|
||||||
display_name=display_name,
|
|
||||||
release_date=commit_local_date(commit_payload),
|
|
||||||
branch=branch,
|
|
||||||
source_ref=commit,
|
|
||||||
source_path=source_path,
|
|
||||||
input_format="supercombo" if "supercombo" in Path(source_path).name else "split",
|
|
||||||
behavior_version=behavior_version,
|
|
||||||
uses_external_gpu=uses_external_gpu,
|
|
||||||
commits=[commit],
|
|
||||||
model_iteration=model_iteration_match.group(1).lower() if model_iteration_match else "",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_pasted_release(text: str, model_id_override: str | None, behavior_version: str) -> ReleaseInfo:
|
|
||||||
cleaned_text = text.replace("\\u00a0", " ")
|
|
||||||
commits = list(dict.fromkeys(match.lower() for match in SHA_RE.findall(cleaned_text)))
|
|
||||||
if re.fullmatch(r"\s*[0-9a-f]{40}\s*", cleaned_text, flags=re.IGNORECASE):
|
|
||||||
return resolve_commit_release(commits[0], model_id_override, behavior_version)
|
|
||||||
|
|
||||||
source_match = re.search(
|
|
||||||
r"https?://github\.com/commaai/openpilot/(?:blob|raw)/([^/\s]+)/([^\s)\]]+)",
|
|
||||||
cleaned_text,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
if source_match:
|
|
||||||
branch = urllib.parse.unquote(source_match.group(1))
|
|
||||||
source_path = urllib.parse.unquote(source_match.group(2)).rstrip(".,")
|
|
||||||
else:
|
|
||||||
branch_match = re.search(r"\[([^]]+)\]\s*\(Branch\s+v?\d+\)", cleaned_text, flags=re.IGNORECASE)
|
|
||||||
branch = clean_markdown(branch_match.group(1)) if branch_match else ""
|
|
||||||
family_match = re.search(r"\[([a-z0-9_-]+)\]\s*\(Branch", cleaned_text, flags=re.IGNORECASE)
|
|
||||||
family = family_match.group(1).lower() if family_match else ""
|
|
||||||
source_path = f"openpilot/selfdrive/modeld/models/{family}_driving_supercombo.onnx" if family else ""
|
|
||||||
|
|
||||||
if not branch:
|
|
||||||
raise ReleaseError("Could not parse the openpilot branch from the pasted release block")
|
|
||||||
if not source_path or not source_path.endswith(".onnx"):
|
|
||||||
raise ReleaseError("Could not parse the upstream ONNX path from the pasted release block")
|
|
||||||
|
|
||||||
name = ""
|
|
||||||
release_date = None
|
|
||||||
for line in cleaned_text.splitlines():
|
|
||||||
plain = clean_markdown(line)
|
|
||||||
date_match = DATE_RE.search(plain)
|
|
||||||
if date_match:
|
|
||||||
candidate = plain[:date_match.start()].strip(" :-(\t")
|
|
||||||
candidate = re.sub(r"^(?:model name|name)\s*[:=-]?\s*", "", candidate, flags=re.IGNORECASE)
|
|
||||||
if candidate and "next model version" not in candidate.lower():
|
|
||||||
name = candidate
|
|
||||||
release_date = parse_release_date(plain)
|
|
||||||
break
|
|
||||||
if not name:
|
|
||||||
family_match = re.search(r"\[([a-z0-9_-]+)\]\s*\(Branch", cleaned_text, flags=re.IGNORECASE)
|
|
||||||
name = family_match.group(1).replace("-", " ").title() if family_match else Path(source_path).stem
|
|
||||||
release_date = dt.date.today().isoformat()
|
|
||||||
release_date = release_date or dt.date.today().isoformat()
|
|
||||||
|
|
||||||
iteration_match = re.search(r"\b(v\d+)\b", name, flags=re.IGNORECASE)
|
|
||||||
model_iteration = iteration_match.group(1).lower() if iteration_match else ""
|
|
||||||
model_id = model_id_override or slug_model_id(name)
|
|
||||||
if not MODEL_ID_RE.fullmatch(model_id):
|
|
||||||
raise ReleaseError(f"Invalid model ID {model_id!r}; use lowercase letters, digits, '-' or '_'")
|
|
||||||
|
|
||||||
uses_external_gpu = bool(
|
|
||||||
re.search(r"\[big\]|\bbig[_ -]model\b", cleaned_text, flags=re.IGNORECASE)
|
|
||||||
or Path(source_path).name.startswith("big_")
|
|
||||||
)
|
|
||||||
source_ref = commits[0] if commits else branch
|
|
||||||
input_format = "supercombo" if "supercombo" in Path(source_path).name else "split"
|
|
||||||
return ReleaseInfo(
|
|
||||||
model_id=model_id,
|
|
||||||
display_name=name,
|
|
||||||
release_date=release_date,
|
|
||||||
branch=branch,
|
|
||||||
source_ref=source_ref,
|
|
||||||
source_path=source_path,
|
|
||||||
input_format=input_format,
|
|
||||||
behavior_version=behavior_version,
|
|
||||||
uses_external_gpu=uses_external_gpu,
|
|
||||||
commits=commits,
|
|
||||||
model_iteration=model_iteration,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_branch_commit(branch: str) -> str:
|
|
||||||
url = f"https://api.github.com/repos/{OPENPILOT_REPO}/commits/{urllib.parse.quote(branch, safe='')}"
|
|
||||||
payload = get_json(url)
|
|
||||||
sha = str(payload.get("sha") or "")
|
|
||||||
if not SHA_RE.fullmatch(sha):
|
|
||||||
raise ReleaseError(f"Could not resolve branch head for {branch}")
|
|
||||||
return sha
|
|
||||||
|
|
||||||
|
|
||||||
def runtime_file(path: str) -> bool:
|
|
||||||
normalized = path.lstrip("./")
|
|
||||||
if normalized.lower().endswith(".onnx"):
|
|
||||||
return False
|
|
||||||
return normalized.startswith(RUNTIME_PATH_PREFIXES)
|
|
||||||
|
|
||||||
|
|
||||||
def scan_runtime_changes(info: ReleaseInfo) -> list[dict]:
|
|
||||||
commits = info.commits or [resolve_branch_commit(info.branch)]
|
|
||||||
findings: list[dict] = []
|
|
||||||
for commit in commits:
|
|
||||||
url = f"https://api.github.com/repos/{OPENPILOT_REPO}/commits/{commit}"
|
|
||||||
payload = get_json(url)
|
|
||||||
files = payload.get("files", [])
|
|
||||||
if not isinstance(files, list):
|
|
||||||
raise ReleaseError(f"GitHub returned no file list for commit {commit}")
|
|
||||||
changed = [str(item.get("filename", "")) for item in files if isinstance(item, dict)]
|
|
||||||
runtime_paths = [path for path in changed if runtime_file(path)]
|
|
||||||
if runtime_paths:
|
|
||||||
findings.append({"commit": commit, "message": str(payload.get("commit", {}).get("message", "")).splitlines()[0], "paths": runtime_paths})
|
|
||||||
return findings
|
|
||||||
|
|
||||||
|
|
||||||
def print_summary(info: ReleaseInfo) -> None:
|
|
||||||
print("\nRelease summary")
|
|
||||||
print(f" model ID: {info.model_id}")
|
|
||||||
print(f" display name: {info.display_name}")
|
|
||||||
print(f" release date: {info.release_date}")
|
|
||||||
print(f" behavior: {info.behavior_version}")
|
|
||||||
print(f" source ref: {info.source_ref}")
|
|
||||||
print(f" source path: {info.source_path}")
|
|
||||||
print(f" input format: {info.input_format}")
|
|
||||||
print(f" external GPU: {info.uses_external_gpu}")
|
|
||||||
|
|
||||||
|
|
||||||
def print_runtime_warning(findings: list[dict]) -> None:
|
|
||||||
print("\n" + "!" * 88)
|
|
||||||
print("STOP: UPSTREAM TINYGRAD/MODELD RUNTIME CHANGES DETECTED")
|
|
||||||
print("Ask Firestar to review these changes before compiling this model.")
|
|
||||||
for finding in findings:
|
|
||||||
print(f" {finding['commit'][:12]} {finding['message']}")
|
|
||||||
for path in finding["paths"]:
|
|
||||||
print(f" - {path}")
|
|
||||||
print("The release tool will not compile until --allow-runtime-changes is supplied.")
|
|
||||||
print("!" * 88 + "\n")
|
|
||||||
|
|
||||||
|
|
||||||
def choose_device_ip(args: argparse.Namespace) -> str:
|
|
||||||
if args.ip:
|
|
||||||
value = args.ip.strip()
|
|
||||||
elif sys.stdin.isatty():
|
|
||||||
value = input("Comma IP [192.168.3.110]: ").strip() or "192.168.3.110"
|
|
||||||
else:
|
|
||||||
raise ReleaseError("Pass --ip when the release text is piped on stdin")
|
|
||||||
try:
|
|
||||||
address = ipaddress.ip_address(value)
|
|
||||||
except ValueError as error:
|
|
||||||
raise ReleaseError(f"Invalid comma IP: {value}") from error
|
|
||||||
if str(address).split(".")[-1] == "109":
|
|
||||||
raise ReleaseError("Refusing to use .109. This workflow is restricted to the requested device, not 192.168.3.109.")
|
|
||||||
return str(address)
|
|
||||||
|
|
||||||
|
|
||||||
def ssh_base(ip: str) -> list[str]:
|
|
||||||
return ["ssh", "-o", "ConnectTimeout=10", "-o", "ConnectionAttempts=1", "-o", "ServerAliveInterval=30", f"comma@{ip}"]
|
|
||||||
|
|
||||||
|
|
||||||
def scp_base(ip: str) -> list[str]:
|
|
||||||
return ["scp", "-p", "-o", "ConnectTimeout=10", "-o", "ConnectionAttempts=1"]
|
|
||||||
|
|
||||||
|
|
||||||
def remote_compile(info: ReleaseInfo, source: Path, ip: str, workspace: Path, keep_device_files: bool) -> dict:
|
|
||||||
if info.input_format != "supercombo":
|
|
||||||
raise ReleaseError("The release tool currently requires a single supercombo ONNX source")
|
|
||||||
|
|
||||||
input_dir = f"{DEVICE_ROOT}/uncompiledmodels"
|
|
||||||
output_dir = f"{DEVICE_ROOT}/compiledmodels"
|
|
||||||
remote_source = f"{input_dir}/{info.model_id}_driving_supercombo.onnx"
|
|
||||||
artifact_prefix = f"{info.model_id}_driving_tinygrad.pkl"
|
|
||||||
safe_id = shlex.quote(info.model_id)
|
|
||||||
cleanup_command = f"rm -f {shlex.quote(remote_source)} {shlex.quote(output_dir)}/{artifact_prefix}*"
|
|
||||||
run(ssh_base(ip) + [f"mkdir -p {shlex.quote(input_dir)} {shlex.quote(output_dir)} && {cleanup_command}"])
|
|
||||||
run(scp_base(ip) + [str(source), f"comma@{ip}:{remote_source}"])
|
|
||||||
|
|
||||||
command = [
|
|
||||||
f"cd {shlex.quote(DEVICE_ROOT)} && ./models",
|
|
||||||
f"--model {safe_id}",
|
|
||||||
f"--input-dir {shlex.quote(input_dir)}",
|
|
||||||
f"--output-dir {shlex.quote(output_dir)}",
|
|
||||||
f"--input-format supercombo",
|
|
||||||
f"--version {shlex.quote(info.behavior_version)}",
|
|
||||||
]
|
|
||||||
if info.uses_external_gpu:
|
|
||||||
command.append("--gpu")
|
|
||||||
remote_command = " ".join(command)
|
|
||||||
log_path = workspace / "logs" / f"{info.model_id}.log"
|
|
||||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
print(f"\nCompiling on comma@{ip}. Output is also logged to {log_path}")
|
|
||||||
with log_path.open("w", encoding="utf-8") as log:
|
|
||||||
process = subprocess.Popen(
|
|
||||||
ssh_base(ip) + [remote_command],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
text=True,
|
|
||||||
bufsize=1,
|
|
||||||
)
|
|
||||||
assert process.stdout is not None
|
|
||||||
for line in process.stdout:
|
|
||||||
print(f"[device] {line}", end="")
|
|
||||||
log.write(line)
|
|
||||||
return_code = process.wait()
|
|
||||||
if return_code != 0:
|
|
||||||
raise ReleaseError(f"Device compilation failed; see {log_path}")
|
|
||||||
|
|
||||||
list_command = f"for f in {shlex.quote(output_dir)}/{artifact_prefix}*; do [ -f \"$f\" ] && basename \"$f\"; done"
|
|
||||||
listed = run(ssh_base(ip) + [list_command], capture=True).stdout.splitlines()
|
|
||||||
remote_files = sorted(name for name in listed if name.startswith(artifact_prefix))
|
|
||||||
if not remote_files:
|
|
||||||
raise ReleaseError(f"Device compiler produced no {artifact_prefix} output")
|
|
||||||
|
|
||||||
artifact_dir = workspace / "compiled" / info.model_id
|
|
||||||
artifact_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
for stale in artifact_dir.iterdir():
|
|
||||||
if stale.is_file():
|
|
||||||
stale.unlink()
|
|
||||||
for filename in remote_files:
|
|
||||||
run(scp_base(ip) + [f"comma@{ip}:{output_dir}/{filename}", str(artifact_dir / filename)])
|
|
||||||
|
|
||||||
parts = sorted(artifact_dir.glob(f"{artifact_prefix}.p[0-9][0-9]"))
|
|
||||||
full_artifact = artifact_dir / artifact_prefix
|
|
||||||
checksum_path = artifact_dir / f"{artifact_prefix}.sha256"
|
|
||||||
if parts:
|
|
||||||
if full_artifact.exists() or not checksum_path.is_file():
|
|
||||||
raise ReleaseError("Device returned invalid multipart output")
|
|
||||||
expected = checksum_path.read_text(encoding="utf-8").split()[0].lower()
|
|
||||||
digest = hashlib.sha256()
|
|
||||||
size = 0
|
|
||||||
for part in parts:
|
|
||||||
with part.open("rb") as source_part:
|
|
||||||
for chunk in iter(lambda: source_part.read(1024 * 1024), b""):
|
|
||||||
digest.update(chunk)
|
|
||||||
size += len(chunk)
|
|
||||||
actual = digest.hexdigest()
|
|
||||||
if actual != expected:
|
|
||||||
raise ReleaseError(f"Multipart checksum mismatch: {actual} != {expected}")
|
|
||||||
artifact_files = [*parts, checksum_path]
|
|
||||||
elif full_artifact.is_file():
|
|
||||||
size = full_artifact.stat().st_size
|
|
||||||
actual = sha256_file(full_artifact)
|
|
||||||
artifact_files = [full_artifact]
|
|
||||||
expected = actual
|
|
||||||
else:
|
|
||||||
raise ReleaseError("Device returned no usable artifact")
|
|
||||||
|
|
||||||
if not keep_device_files:
|
|
||||||
run(ssh_base(ip) + [cleanup_command])
|
|
||||||
result = {
|
|
||||||
"id": info.model_id,
|
|
||||||
"status": "compiled",
|
|
||||||
"size": size,
|
|
||||||
"sha256": expected,
|
|
||||||
"multipart": bool(parts),
|
|
||||||
"files": [path.name for path in artifact_files],
|
|
||||||
"path": str(artifact_dir),
|
|
||||||
}
|
|
||||||
(workspace / "results").mkdir(parents=True, exist_ok=True)
|
|
||||||
(workspace / "results" / f"{info.model_id}.json").write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def manifest_entry(info: ReleaseInfo, result: dict) -> dict:
|
|
||||||
display_name = info.display_name
|
|
||||||
if "👀" not in display_name and "📡" not in display_name:
|
|
||||||
display_name += " 👀📡"
|
|
||||||
return {
|
|
||||||
"id": info.model_id,
|
|
||||||
"name": display_name,
|
|
||||||
"version": info.behavior_version,
|
|
||||||
"series": "OP Series",
|
|
||||||
"released": info.release_date,
|
|
||||||
"community_favorite": False,
|
|
||||||
"artifact_format": "tinygrad_single_v1",
|
|
||||||
"artifact_size": result["size"],
|
|
||||||
"artifact_sha256": result["sha256"],
|
|
||||||
"uses_external_gpu": info.uses_external_gpu,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def update_manifest(repo: Path, info: ReleaseInfo, result: dict, manifest_version: str) -> Path:
|
|
||||||
path = repo / f"model_names_{manifest_version}.json"
|
|
||||||
if not path.is_file():
|
|
||||||
raise ReleaseError(f"Manifest not found: {path}")
|
|
||||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
||||||
models = payload.get("models", payload) if isinstance(payload, dict) else payload
|
|
||||||
if not isinstance(models, list):
|
|
||||||
raise ReleaseError(f"Unsupported manifest shape: {path}")
|
|
||||||
entry = manifest_entry(info, result)
|
|
||||||
replaced = False
|
|
||||||
updated = []
|
|
||||||
for model in models:
|
|
||||||
if isinstance(model, dict) and model.get("id") == info.model_id:
|
|
||||||
updated.append(entry)
|
|
||||||
replaced = True
|
|
||||||
else:
|
|
||||||
updated.append(model)
|
|
||||||
if not replaced:
|
|
||||||
updated.append(entry)
|
|
||||||
output = {**payload, "models": updated} if isinstance(payload, dict) else {"models": updated}
|
|
||||||
path.write_text(json.dumps(output, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def find_hf() -> str:
|
|
||||||
candidates = [shutil.which("hf"), str(Path.home() / ".local/bin/hf")]
|
|
||||||
for candidate in candidates:
|
|
||||||
if candidate and Path(candidate).is_file():
|
|
||||||
return candidate
|
|
||||||
raise ReleaseError("Hugging Face CLI not found; install/authenticate `hf` first")
|
|
||||||
|
|
||||||
|
|
||||||
def hf_copy(source: Path, bucket: str, remote_path: str) -> None:
|
|
||||||
hf = find_hf()
|
|
||||||
destination = f"hf://buckets/{bucket}/{remote_path}"
|
|
||||||
run([hf, "buckets", "cp", str(source), destination, "--format", "quiet"])
|
|
||||||
|
|
||||||
|
|
||||||
def upload_huggingface(info: ReleaseInfo, result: dict, workspace: Path, bucket: str, manifest: Path, upload_onnx: bool, source: Path) -> None:
|
|
||||||
artifact_dir = Path(result["path"])
|
|
||||||
for filename in result["files"]:
|
|
||||||
hf_copy(artifact_dir / filename, bucket, f"models/{info.model_id}/{filename}")
|
|
||||||
if upload_onnx:
|
|
||||||
hf_copy(source, bucket, f"onnx/{info.model_id}/{source.name}")
|
|
||||||
hf_copy(manifest, bucket, f"manifests/{manifest.name}")
|
|
||||||
print(f"Hugging Face upload complete: {bucket}/models/{info.model_id}/")
|
|
||||||
|
|
||||||
|
|
||||||
def git_output(repo: Path, args: list[str]) -> str:
|
|
||||||
return run(["git", "-C", str(repo), *args], capture=True).stdout.strip()
|
|
||||||
|
|
||||||
|
|
||||||
def check_resources_repo(repo: Path, branch: str) -> None:
|
|
||||||
if not (repo / ".git").exists():
|
|
||||||
raise ReleaseError(f"GitHub resources checkout not found: {repo}")
|
|
||||||
status = git_output(repo, ["status", "--porcelain"])
|
|
||||||
if status:
|
|
||||||
raise ReleaseError(f"Resources checkout is dirty; refusing to modify it:\n{status}")
|
|
||||||
current_branch = git_output(repo, ["branch", "--show-current"])
|
|
||||||
if current_branch != branch:
|
|
||||||
raise ReleaseError(f"Resources checkout is on {current_branch!r}, expected {branch!r}")
|
|
||||||
remote_head = git_output(repo, ["rev-parse", f"origin/{branch}"])
|
|
||||||
local_head = git_output(repo, ["rev-parse", "HEAD"])
|
|
||||||
if remote_head != local_head:
|
|
||||||
raise ReleaseError("Resources checkout has unpushed or missing remote commits; sync it before releasing")
|
|
||||||
|
|
||||||
|
|
||||||
def push_github(info: ReleaseInfo, result: dict, resources_repo: Path, manifest: Path, branch: str, force: bool) -> None:
|
|
||||||
artifact_dir = Path(result["path"])
|
|
||||||
artifact_names = list(result["files"])
|
|
||||||
destination_paths = []
|
|
||||||
stale_relative: list[str] = []
|
|
||||||
for filename in artifact_names:
|
|
||||||
destination = resources_repo / filename
|
|
||||||
if destination.exists() and not force:
|
|
||||||
raise ReleaseError(f"Artifact already exists in GitHub checkout: {destination}; use --force to replace it")
|
|
||||||
shutil.copy2(artifact_dir / filename, destination)
|
|
||||||
destination_paths.append(destination)
|
|
||||||
|
|
||||||
prefix = f"{info.model_id}_driving_tinygrad.pkl"
|
|
||||||
if force:
|
|
||||||
allowed = {path.name for path in destination_paths}
|
|
||||||
for stale in resources_repo.glob(f"{prefix}*"):
|
|
||||||
if stale.name not in allowed and stale.is_file():
|
|
||||||
stale.unlink()
|
|
||||||
stale_relative.append(str(stale.relative_to(resources_repo)))
|
|
||||||
|
|
||||||
for index, destination in enumerate(destination_paths):
|
|
||||||
relative = destination.relative_to(resources_repo)
|
|
||||||
paths_to_stage = [str(relative)]
|
|
||||||
if index == 0:
|
|
||||||
paths_to_stage.extend(stale_relative)
|
|
||||||
run(["git", "-C", str(resources_repo), "add", "-A", "--", *paths_to_stage])
|
|
||||||
run(["git", "-C", str(resources_repo), "commit", "-m", f"Add {info.model_id} artifact {destination.name}", "--", *paths_to_stage])
|
|
||||||
run(["git", "-C", str(resources_repo), "push", "origin", f"HEAD:{branch}"])
|
|
||||||
|
|
||||||
run(["git", "-C", str(resources_repo), "add", "--", str(manifest.relative_to(resources_repo))])
|
|
||||||
if git_output(resources_repo, ["diff", "--cached", "--name-only"]):
|
|
||||||
run(["git", "-C", str(resources_repo), "commit", "-m", f"Add {info.display_name} to {manifest.name}", "--", str(manifest.relative_to(resources_repo))])
|
|
||||||
run(["git", "-C", str(resources_repo), "push", "origin", f"HEAD:{branch}"])
|
|
||||||
print(f"GitHub upload complete: {RESOURCES_REPO}/{branch}")
|
|
||||||
|
|
||||||
|
|
||||||
def read_release_text(args: argparse.Namespace) -> str:
|
|
||||||
if args.commit:
|
|
||||||
return args.commit
|
|
||||||
if args.text_file:
|
|
||||||
return args.text_file.read_text(encoding="utf-8")
|
|
||||||
if args.text:
|
|
||||||
return args.text
|
|
||||||
if not sys.stdin.isatty():
|
|
||||||
return sys.stdin.read()
|
|
||||||
print("Paste the model bot message. Press Ctrl-D when finished.")
|
|
||||||
return sys.stdin.read()
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
|
||||||
parser = argparse.ArgumentParser(description="Download, device-compile, verify, and publish one upstream model.")
|
|
||||||
parser.add_argument("commit", nargs="?", help="A single openpilot commit SHA; metadata is resolved from GitHub.")
|
|
||||||
parser.add_argument("--text", help="Release text, otherwise paste it into stdin.")
|
|
||||||
parser.add_argument("--text-file", type=Path, help="Read the pasted release text from a file.")
|
|
||||||
parser.add_argument("--model-id", help="Override the ID parsed from the model name.")
|
|
||||||
parser.add_argument("--behavior-version", default=DEFAULT_BEHAVIOR_VERSION, help="Runtime behavior version (default: v16).")
|
|
||||||
parser.add_argument("--ip", help="Comma IP; prompted interactively when omitted.")
|
|
||||||
parser.add_argument("--workspace", type=Path, default=default_workspace())
|
|
||||||
parser.add_argument("--resources-repo", type=Path, default=Path.home() / "StarPilot-Resources")
|
|
||||||
parser.add_argument("--resources-branch", default=RESOURCE_BRANCH)
|
|
||||||
parser.add_argument("--manifest-version", default=MANIFEST_VERSION)
|
|
||||||
parser.add_argument("--hf-bucket", default=HF_BUCKET)
|
|
||||||
gpu = parser.add_mutually_exclusive_group()
|
|
||||||
gpu.add_argument("--gpu", dest="gpu", action="store_true", help="Force external-GPU compilation.")
|
|
||||||
gpu.add_argument("--no-gpu", dest="gpu", action="store_false", help="Disable external-GPU compilation.")
|
|
||||||
parser.set_defaults(gpu=None)
|
|
||||||
parser.add_argument("--allow-runtime-changes", action="store_true", help="Continue only after reviewing the runtime-change warning.")
|
|
||||||
parser.add_argument("--no-onnx-upload", action="store_true", help="Do not archive the source ONNX in Hugging Face.")
|
|
||||||
parser.add_argument("--keep-device-files", action="store_true", help="Leave the staged source and compiled output on the comma.")
|
|
||||||
parser.add_argument("--force", action="store_true", help="Replace an existing source/artifact/model ID.")
|
|
||||||
parser.add_argument("--dry-run", action="store_true", help="Parse and scan only; do not download, compile, or publish.")
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
|
||||||
args = parse_args()
|
|
||||||
try:
|
|
||||||
if not re.fullmatch(r"v\d+", args.behavior_version.strip(), flags=re.IGNORECASE):
|
|
||||||
raise ReleaseError("--behavior-version must look like v16")
|
|
||||||
text = read_release_text(args)
|
|
||||||
if not text.strip():
|
|
||||||
raise ReleaseError("No release text was supplied")
|
|
||||||
info = parse_pasted_release(text, args.model_id, args.behavior_version.strip().lower())
|
|
||||||
if args.gpu is not None:
|
|
||||||
info.uses_external_gpu = args.gpu
|
|
||||||
print_summary(info)
|
|
||||||
|
|
||||||
findings = scan_runtime_changes(info)
|
|
||||||
if findings:
|
|
||||||
print_runtime_warning(findings)
|
|
||||||
if not args.allow_runtime_changes:
|
|
||||||
return 2
|
|
||||||
else:
|
|
||||||
print("Runtime scan: no tinygrad/modeld runtime files changed in the supplied commits.")
|
|
||||||
|
|
||||||
if args.dry_run:
|
|
||||||
print("Dry run complete; no device or repository changes made.")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
ip = choose_device_ip(args)
|
|
||||||
workspace = args.workspace / info.model_id
|
|
||||||
for relative in ("onnx", "compiled", "logs", "results"):
|
|
||||||
(workspace / relative).mkdir(parents=True, exist_ok=True)
|
|
||||||
source = workspace / "onnx" / f"{info.model_id}_driving_supercombo.onnx"
|
|
||||||
source_result = download_source(info.source_ref, info.source_path, source, args.force)
|
|
||||||
(workspace / "release.txt").write_text(text, encoding="utf-8")
|
|
||||||
(workspace / "source.json").write_text(json.dumps({**source_result, "model": info.__dict__}, indent=2) + "\n", encoding="utf-8")
|
|
||||||
|
|
||||||
result = remote_compile(info, source, ip, workspace, args.keep_device_files)
|
|
||||||
resources_repo = args.resources_repo.expanduser().resolve()
|
|
||||||
check_resources_repo(resources_repo, args.resources_branch)
|
|
||||||
manifest = update_manifest(resources_repo, info, result, args.manifest_version)
|
|
||||||
upload_huggingface(info, result, workspace, args.hf_bucket, manifest, not args.no_onnx_upload, source)
|
|
||||||
push_github(info, result, resources_repo, manifest, args.resources_branch, args.force)
|
|
||||||
print("\nRelease complete.")
|
|
||||||
print(f" local artifact: {result['path']}")
|
|
||||||
print(f" Hugging Face: {args.hf_bucket}/models/{info.model_id}/")
|
|
||||||
print(f" GitHub: {RESOURCES_REPO}/{args.resources_branch}")
|
|
||||||
return 0
|
|
||||||
except (ReleaseError, subprocess.CalledProcessError) as error:
|
|
||||||
print(f"ERROR: {error}", file=sys.stderr)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
raise SystemExit(main())
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from scripts import model_release
|
|
||||||
from scripts.model_release import parse_lfs_pointer, parse_pasted_release, runtime_file, update_manifest
|
|
||||||
|
|
||||||
|
|
||||||
RELEASE_TEXT = """
|
|
||||||
**BRANCH UPDATED — BIG**
|
|
||||||
[remove-avgpool](https://github.com/commaai/openpilot/pull/38681) #38681 [big] (Branch v5)
|
|
||||||
**Changed Files**
|
|
||||||
[big_driving_supercombo](https://github.com/commaai/openpilot/blob/remove-avgpool/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx)
|
|
||||||
**Recent Commits [f877]**
|
|
||||||
[f877d7a0ccc3cce943c76e285214c020cd65c899](https://github.com/commaai/openpilot/commit/f877d7a0ccc3cce943c76e285214c020cd65c899)
|
|
||||||
[faster compile](https://github.com/commaai/openpilot/commit/83a461eb4f0cb5737132c24b7a5ad5de46fc0fbb)
|
|
||||||
**Next Model Version [big]**
|
|
||||||
Model v4
|
|
||||||
|
|
||||||
Bmrlnap v4 (August 30, 2026) f877
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def test_parse_release_block():
|
|
||||||
info = parse_pasted_release(RELEASE_TEXT, None, "v16")
|
|
||||||
assert info.model_id == "bmrlnapv4"
|
|
||||||
assert info.display_name == "Bmrlnap v4"
|
|
||||||
assert info.release_date == "2026-08-30"
|
|
||||||
assert info.branch == "remove-avgpool"
|
|
||||||
assert info.source_ref == "f877d7a0ccc3cce943c76e285214c020cd65c899"
|
|
||||||
assert info.source_path.endswith("big_driving_supercombo.onnx")
|
|
||||||
assert info.input_format == "supercombo"
|
|
||||||
assert info.uses_external_gpu
|
|
||||||
assert info.commits == [
|
|
||||||
"f877d7a0ccc3cce943c76e285214c020cd65c899",
|
|
||||||
"83a461eb4f0cb5737132c24b7a5ad5de46fc0fbb",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_lfs_pointer_parser():
|
|
||||||
pointer = (
|
|
||||||
b"version https://git-lfs.github.com/spec/v1\n"
|
|
||||||
b"oid sha256:" + b"a" * 64 + b"\n"
|
|
||||||
b"size 123\n"
|
|
||||||
)
|
|
||||||
assert parse_lfs_pointer(pointer) == ("a" * 64, 123)
|
|
||||||
|
|
||||||
|
|
||||||
def test_sha_only_resolves_commit_metadata(monkeypatch):
|
|
||||||
commit = "f877d7a0ccc3cce943c76e285214c020cd65c899"
|
|
||||||
payloads = {
|
|
||||||
f"https://api.github.com/repos/commaai/openpilot/commits/{commit}": {
|
|
||||||
"commit": {"committer": {"date": "2026-08-31T00:41:06Z"}},
|
|
||||||
"files": [{"filename": "openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx"}],
|
|
||||||
},
|
|
||||||
f"https://api.github.com/repos/commaai/openpilot/commits/{commit}/pulls": [
|
|
||||||
{"title": "BMRLNAP", "head": {"sha": commit, "ref": "remove-avgpool"}},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
monkeypatch.setattr(model_release, "get_json_value", lambda url: payloads[url])
|
|
||||||
info = parse_pasted_release(commit, None, "v16")
|
|
||||||
|
|
||||||
assert info.model_id == "bmrlnap"
|
|
||||||
assert info.display_name == "BMRLNAP"
|
|
||||||
assert info.release_date == "2026-08-30"
|
|
||||||
assert info.branch == "remove-avgpool"
|
|
||||||
assert info.source_ref == commit
|
|
||||||
assert info.source_path.endswith("big_driving_supercombo.onnx")
|
|
||||||
assert info.uses_external_gpu
|
|
||||||
|
|
||||||
|
|
||||||
def test_runtime_scan_excludes_model_weights_but_flags_runtime_code():
|
|
||||||
assert not runtime_file("openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx")
|
|
||||||
assert runtime_file("openpilot/selfdrive/modeld/compile_modeld.py")
|
|
||||||
assert runtime_file("tinygrad/engine/jit.py")
|
|
||||||
assert not runtime_file("README.md")
|
|
||||||
|
|
||||||
|
|
||||||
def test_update_manifest_replaces_one_entry(tmp_path: Path):
|
|
||||||
manifest = tmp_path / "model_names_v24.json"
|
|
||||||
manifest.write_text(json.dumps({"models": [{"id": "old"}]}) + "\n")
|
|
||||||
info = parse_pasted_release(RELEASE_TEXT, "bmrlnapv4", "v16")
|
|
||||||
path = update_manifest(
|
|
||||||
tmp_path,
|
|
||||||
info,
|
|
||||||
{"size": 123, "sha256": "a" * 64},
|
|
||||||
"v24",
|
|
||||||
)
|
|
||||||
payload = json.loads(path.read_text())
|
|
||||||
assert len(payload["models"]) == 2
|
|
||||||
entry = payload["models"][1]
|
|
||||||
assert entry["id"] == "bmrlnapv4"
|
|
||||||
assert entry["artifact_size"] == 123
|
|
||||||
assert entry["uses_external_gpu"]
|
|
||||||
@@ -45,326 +45,326 @@ const static double MAHA_THRESH_31 = 3.8414588206941227;
|
|||||||
* *
|
* *
|
||||||
* This file is part of 'ekf' *
|
* This file is part of 'ekf' *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void err_fun(double *nom_x, double *delta_x, double *out_7311248151803822396) {
|
void err_fun(double *nom_x, double *delta_x, double *out_1982741958495934934) {
|
||||||
out_7311248151803822396[0] = delta_x[0] + nom_x[0];
|
out_1982741958495934934[0] = delta_x[0] + nom_x[0];
|
||||||
out_7311248151803822396[1] = delta_x[1] + nom_x[1];
|
out_1982741958495934934[1] = delta_x[1] + nom_x[1];
|
||||||
out_7311248151803822396[2] = delta_x[2] + nom_x[2];
|
out_1982741958495934934[2] = delta_x[2] + nom_x[2];
|
||||||
out_7311248151803822396[3] = delta_x[3] + nom_x[3];
|
out_1982741958495934934[3] = delta_x[3] + nom_x[3];
|
||||||
out_7311248151803822396[4] = delta_x[4] + nom_x[4];
|
out_1982741958495934934[4] = delta_x[4] + nom_x[4];
|
||||||
out_7311248151803822396[5] = delta_x[5] + nom_x[5];
|
out_1982741958495934934[5] = delta_x[5] + nom_x[5];
|
||||||
out_7311248151803822396[6] = delta_x[6] + nom_x[6];
|
out_1982741958495934934[6] = delta_x[6] + nom_x[6];
|
||||||
out_7311248151803822396[7] = delta_x[7] + nom_x[7];
|
out_1982741958495934934[7] = delta_x[7] + nom_x[7];
|
||||||
out_7311248151803822396[8] = delta_x[8] + nom_x[8];
|
out_1982741958495934934[8] = delta_x[8] + nom_x[8];
|
||||||
}
|
}
|
||||||
void inv_err_fun(double *nom_x, double *true_x, double *out_5602719869542378501) {
|
void inv_err_fun(double *nom_x, double *true_x, double *out_1965858196176103805) {
|
||||||
out_5602719869542378501[0] = -nom_x[0] + true_x[0];
|
out_1965858196176103805[0] = -nom_x[0] + true_x[0];
|
||||||
out_5602719869542378501[1] = -nom_x[1] + true_x[1];
|
out_1965858196176103805[1] = -nom_x[1] + true_x[1];
|
||||||
out_5602719869542378501[2] = -nom_x[2] + true_x[2];
|
out_1965858196176103805[2] = -nom_x[2] + true_x[2];
|
||||||
out_5602719869542378501[3] = -nom_x[3] + true_x[3];
|
out_1965858196176103805[3] = -nom_x[3] + true_x[3];
|
||||||
out_5602719869542378501[4] = -nom_x[4] + true_x[4];
|
out_1965858196176103805[4] = -nom_x[4] + true_x[4];
|
||||||
out_5602719869542378501[5] = -nom_x[5] + true_x[5];
|
out_1965858196176103805[5] = -nom_x[5] + true_x[5];
|
||||||
out_5602719869542378501[6] = -nom_x[6] + true_x[6];
|
out_1965858196176103805[6] = -nom_x[6] + true_x[6];
|
||||||
out_5602719869542378501[7] = -nom_x[7] + true_x[7];
|
out_1965858196176103805[7] = -nom_x[7] + true_x[7];
|
||||||
out_5602719869542378501[8] = -nom_x[8] + true_x[8];
|
out_1965858196176103805[8] = -nom_x[8] + true_x[8];
|
||||||
}
|
}
|
||||||
void H_mod_fun(double *state, double *out_6859429191092688662) {
|
void H_mod_fun(double *state, double *out_7322816943518629238) {
|
||||||
out_6859429191092688662[0] = 1.0;
|
out_7322816943518629238[0] = 1.0;
|
||||||
out_6859429191092688662[1] = 0.0;
|
out_7322816943518629238[1] = 0.0;
|
||||||
out_6859429191092688662[2] = 0.0;
|
out_7322816943518629238[2] = 0.0;
|
||||||
out_6859429191092688662[3] = 0.0;
|
out_7322816943518629238[3] = 0.0;
|
||||||
out_6859429191092688662[4] = 0.0;
|
out_7322816943518629238[4] = 0.0;
|
||||||
out_6859429191092688662[5] = 0.0;
|
out_7322816943518629238[5] = 0.0;
|
||||||
out_6859429191092688662[6] = 0.0;
|
out_7322816943518629238[6] = 0.0;
|
||||||
out_6859429191092688662[7] = 0.0;
|
out_7322816943518629238[7] = 0.0;
|
||||||
out_6859429191092688662[8] = 0.0;
|
out_7322816943518629238[8] = 0.0;
|
||||||
out_6859429191092688662[9] = 0.0;
|
out_7322816943518629238[9] = 0.0;
|
||||||
out_6859429191092688662[10] = 1.0;
|
out_7322816943518629238[10] = 1.0;
|
||||||
out_6859429191092688662[11] = 0.0;
|
out_7322816943518629238[11] = 0.0;
|
||||||
out_6859429191092688662[12] = 0.0;
|
out_7322816943518629238[12] = 0.0;
|
||||||
out_6859429191092688662[13] = 0.0;
|
out_7322816943518629238[13] = 0.0;
|
||||||
out_6859429191092688662[14] = 0.0;
|
out_7322816943518629238[14] = 0.0;
|
||||||
out_6859429191092688662[15] = 0.0;
|
out_7322816943518629238[15] = 0.0;
|
||||||
out_6859429191092688662[16] = 0.0;
|
out_7322816943518629238[16] = 0.0;
|
||||||
out_6859429191092688662[17] = 0.0;
|
out_7322816943518629238[17] = 0.0;
|
||||||
out_6859429191092688662[18] = 0.0;
|
out_7322816943518629238[18] = 0.0;
|
||||||
out_6859429191092688662[19] = 0.0;
|
out_7322816943518629238[19] = 0.0;
|
||||||
out_6859429191092688662[20] = 1.0;
|
out_7322816943518629238[20] = 1.0;
|
||||||
out_6859429191092688662[21] = 0.0;
|
out_7322816943518629238[21] = 0.0;
|
||||||
out_6859429191092688662[22] = 0.0;
|
out_7322816943518629238[22] = 0.0;
|
||||||
out_6859429191092688662[23] = 0.0;
|
out_7322816943518629238[23] = 0.0;
|
||||||
out_6859429191092688662[24] = 0.0;
|
out_7322816943518629238[24] = 0.0;
|
||||||
out_6859429191092688662[25] = 0.0;
|
out_7322816943518629238[25] = 0.0;
|
||||||
out_6859429191092688662[26] = 0.0;
|
out_7322816943518629238[26] = 0.0;
|
||||||
out_6859429191092688662[27] = 0.0;
|
out_7322816943518629238[27] = 0.0;
|
||||||
out_6859429191092688662[28] = 0.0;
|
out_7322816943518629238[28] = 0.0;
|
||||||
out_6859429191092688662[29] = 0.0;
|
out_7322816943518629238[29] = 0.0;
|
||||||
out_6859429191092688662[30] = 1.0;
|
out_7322816943518629238[30] = 1.0;
|
||||||
out_6859429191092688662[31] = 0.0;
|
out_7322816943518629238[31] = 0.0;
|
||||||
out_6859429191092688662[32] = 0.0;
|
out_7322816943518629238[32] = 0.0;
|
||||||
out_6859429191092688662[33] = 0.0;
|
out_7322816943518629238[33] = 0.0;
|
||||||
out_6859429191092688662[34] = 0.0;
|
out_7322816943518629238[34] = 0.0;
|
||||||
out_6859429191092688662[35] = 0.0;
|
out_7322816943518629238[35] = 0.0;
|
||||||
out_6859429191092688662[36] = 0.0;
|
out_7322816943518629238[36] = 0.0;
|
||||||
out_6859429191092688662[37] = 0.0;
|
out_7322816943518629238[37] = 0.0;
|
||||||
out_6859429191092688662[38] = 0.0;
|
out_7322816943518629238[38] = 0.0;
|
||||||
out_6859429191092688662[39] = 0.0;
|
out_7322816943518629238[39] = 0.0;
|
||||||
out_6859429191092688662[40] = 1.0;
|
out_7322816943518629238[40] = 1.0;
|
||||||
out_6859429191092688662[41] = 0.0;
|
out_7322816943518629238[41] = 0.0;
|
||||||
out_6859429191092688662[42] = 0.0;
|
out_7322816943518629238[42] = 0.0;
|
||||||
out_6859429191092688662[43] = 0.0;
|
out_7322816943518629238[43] = 0.0;
|
||||||
out_6859429191092688662[44] = 0.0;
|
out_7322816943518629238[44] = 0.0;
|
||||||
out_6859429191092688662[45] = 0.0;
|
out_7322816943518629238[45] = 0.0;
|
||||||
out_6859429191092688662[46] = 0.0;
|
out_7322816943518629238[46] = 0.0;
|
||||||
out_6859429191092688662[47] = 0.0;
|
out_7322816943518629238[47] = 0.0;
|
||||||
out_6859429191092688662[48] = 0.0;
|
out_7322816943518629238[48] = 0.0;
|
||||||
out_6859429191092688662[49] = 0.0;
|
out_7322816943518629238[49] = 0.0;
|
||||||
out_6859429191092688662[50] = 1.0;
|
out_7322816943518629238[50] = 1.0;
|
||||||
out_6859429191092688662[51] = 0.0;
|
out_7322816943518629238[51] = 0.0;
|
||||||
out_6859429191092688662[52] = 0.0;
|
out_7322816943518629238[52] = 0.0;
|
||||||
out_6859429191092688662[53] = 0.0;
|
out_7322816943518629238[53] = 0.0;
|
||||||
out_6859429191092688662[54] = 0.0;
|
out_7322816943518629238[54] = 0.0;
|
||||||
out_6859429191092688662[55] = 0.0;
|
out_7322816943518629238[55] = 0.0;
|
||||||
out_6859429191092688662[56] = 0.0;
|
out_7322816943518629238[56] = 0.0;
|
||||||
out_6859429191092688662[57] = 0.0;
|
out_7322816943518629238[57] = 0.0;
|
||||||
out_6859429191092688662[58] = 0.0;
|
out_7322816943518629238[58] = 0.0;
|
||||||
out_6859429191092688662[59] = 0.0;
|
out_7322816943518629238[59] = 0.0;
|
||||||
out_6859429191092688662[60] = 1.0;
|
out_7322816943518629238[60] = 1.0;
|
||||||
out_6859429191092688662[61] = 0.0;
|
out_7322816943518629238[61] = 0.0;
|
||||||
out_6859429191092688662[62] = 0.0;
|
out_7322816943518629238[62] = 0.0;
|
||||||
out_6859429191092688662[63] = 0.0;
|
out_7322816943518629238[63] = 0.0;
|
||||||
out_6859429191092688662[64] = 0.0;
|
out_7322816943518629238[64] = 0.0;
|
||||||
out_6859429191092688662[65] = 0.0;
|
out_7322816943518629238[65] = 0.0;
|
||||||
out_6859429191092688662[66] = 0.0;
|
out_7322816943518629238[66] = 0.0;
|
||||||
out_6859429191092688662[67] = 0.0;
|
out_7322816943518629238[67] = 0.0;
|
||||||
out_6859429191092688662[68] = 0.0;
|
out_7322816943518629238[68] = 0.0;
|
||||||
out_6859429191092688662[69] = 0.0;
|
out_7322816943518629238[69] = 0.0;
|
||||||
out_6859429191092688662[70] = 1.0;
|
out_7322816943518629238[70] = 1.0;
|
||||||
out_6859429191092688662[71] = 0.0;
|
out_7322816943518629238[71] = 0.0;
|
||||||
out_6859429191092688662[72] = 0.0;
|
out_7322816943518629238[72] = 0.0;
|
||||||
out_6859429191092688662[73] = 0.0;
|
out_7322816943518629238[73] = 0.0;
|
||||||
out_6859429191092688662[74] = 0.0;
|
out_7322816943518629238[74] = 0.0;
|
||||||
out_6859429191092688662[75] = 0.0;
|
out_7322816943518629238[75] = 0.0;
|
||||||
out_6859429191092688662[76] = 0.0;
|
out_7322816943518629238[76] = 0.0;
|
||||||
out_6859429191092688662[77] = 0.0;
|
out_7322816943518629238[77] = 0.0;
|
||||||
out_6859429191092688662[78] = 0.0;
|
out_7322816943518629238[78] = 0.0;
|
||||||
out_6859429191092688662[79] = 0.0;
|
out_7322816943518629238[79] = 0.0;
|
||||||
out_6859429191092688662[80] = 1.0;
|
out_7322816943518629238[80] = 1.0;
|
||||||
}
|
}
|
||||||
void f_fun(double *state, double dt, double *out_3400060270232460893) {
|
void f_fun(double *state, double dt, double *out_6429621653186063469) {
|
||||||
out_3400060270232460893[0] = state[0];
|
out_6429621653186063469[0] = state[0];
|
||||||
out_3400060270232460893[1] = state[1];
|
out_6429621653186063469[1] = state[1];
|
||||||
out_3400060270232460893[2] = state[2];
|
out_6429621653186063469[2] = state[2];
|
||||||
out_3400060270232460893[3] = state[3];
|
out_6429621653186063469[3] = state[3];
|
||||||
out_3400060270232460893[4] = state[4];
|
out_6429621653186063469[4] = state[4];
|
||||||
out_3400060270232460893[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
|
out_6429621653186063469[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
|
||||||
out_3400060270232460893[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
|
out_6429621653186063469[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
|
||||||
out_3400060270232460893[7] = state[7];
|
out_6429621653186063469[7] = state[7];
|
||||||
out_3400060270232460893[8] = state[8];
|
out_6429621653186063469[8] = state[8];
|
||||||
}
|
}
|
||||||
void F_fun(double *state, double dt, double *out_6511275578440991802) {
|
void F_fun(double *state, double dt, double *out_4451613020495234820) {
|
||||||
out_6511275578440991802[0] = 1;
|
out_4451613020495234820[0] = 1;
|
||||||
out_6511275578440991802[1] = 0;
|
out_4451613020495234820[1] = 0;
|
||||||
out_6511275578440991802[2] = 0;
|
out_4451613020495234820[2] = 0;
|
||||||
out_6511275578440991802[3] = 0;
|
out_4451613020495234820[3] = 0;
|
||||||
out_6511275578440991802[4] = 0;
|
out_4451613020495234820[4] = 0;
|
||||||
out_6511275578440991802[5] = 0;
|
out_4451613020495234820[5] = 0;
|
||||||
out_6511275578440991802[6] = 0;
|
out_4451613020495234820[6] = 0;
|
||||||
out_6511275578440991802[7] = 0;
|
out_4451613020495234820[7] = 0;
|
||||||
out_6511275578440991802[8] = 0;
|
out_4451613020495234820[8] = 0;
|
||||||
out_6511275578440991802[9] = 0;
|
out_4451613020495234820[9] = 0;
|
||||||
out_6511275578440991802[10] = 1;
|
out_4451613020495234820[10] = 1;
|
||||||
out_6511275578440991802[11] = 0;
|
out_4451613020495234820[11] = 0;
|
||||||
out_6511275578440991802[12] = 0;
|
out_4451613020495234820[12] = 0;
|
||||||
out_6511275578440991802[13] = 0;
|
out_4451613020495234820[13] = 0;
|
||||||
out_6511275578440991802[14] = 0;
|
out_4451613020495234820[14] = 0;
|
||||||
out_6511275578440991802[15] = 0;
|
out_4451613020495234820[15] = 0;
|
||||||
out_6511275578440991802[16] = 0;
|
out_4451613020495234820[16] = 0;
|
||||||
out_6511275578440991802[17] = 0;
|
out_4451613020495234820[17] = 0;
|
||||||
out_6511275578440991802[18] = 0;
|
out_4451613020495234820[18] = 0;
|
||||||
out_6511275578440991802[19] = 0;
|
out_4451613020495234820[19] = 0;
|
||||||
out_6511275578440991802[20] = 1;
|
out_4451613020495234820[20] = 1;
|
||||||
out_6511275578440991802[21] = 0;
|
out_4451613020495234820[21] = 0;
|
||||||
out_6511275578440991802[22] = 0;
|
out_4451613020495234820[22] = 0;
|
||||||
out_6511275578440991802[23] = 0;
|
out_4451613020495234820[23] = 0;
|
||||||
out_6511275578440991802[24] = 0;
|
out_4451613020495234820[24] = 0;
|
||||||
out_6511275578440991802[25] = 0;
|
out_4451613020495234820[25] = 0;
|
||||||
out_6511275578440991802[26] = 0;
|
out_4451613020495234820[26] = 0;
|
||||||
out_6511275578440991802[27] = 0;
|
out_4451613020495234820[27] = 0;
|
||||||
out_6511275578440991802[28] = 0;
|
out_4451613020495234820[28] = 0;
|
||||||
out_6511275578440991802[29] = 0;
|
out_4451613020495234820[29] = 0;
|
||||||
out_6511275578440991802[30] = 1;
|
out_4451613020495234820[30] = 1;
|
||||||
out_6511275578440991802[31] = 0;
|
out_4451613020495234820[31] = 0;
|
||||||
out_6511275578440991802[32] = 0;
|
out_4451613020495234820[32] = 0;
|
||||||
out_6511275578440991802[33] = 0;
|
out_4451613020495234820[33] = 0;
|
||||||
out_6511275578440991802[34] = 0;
|
out_4451613020495234820[34] = 0;
|
||||||
out_6511275578440991802[35] = 0;
|
out_4451613020495234820[35] = 0;
|
||||||
out_6511275578440991802[36] = 0;
|
out_4451613020495234820[36] = 0;
|
||||||
out_6511275578440991802[37] = 0;
|
out_4451613020495234820[37] = 0;
|
||||||
out_6511275578440991802[38] = 0;
|
out_4451613020495234820[38] = 0;
|
||||||
out_6511275578440991802[39] = 0;
|
out_4451613020495234820[39] = 0;
|
||||||
out_6511275578440991802[40] = 1;
|
out_4451613020495234820[40] = 1;
|
||||||
out_6511275578440991802[41] = 0;
|
out_4451613020495234820[41] = 0;
|
||||||
out_6511275578440991802[42] = 0;
|
out_4451613020495234820[42] = 0;
|
||||||
out_6511275578440991802[43] = 0;
|
out_4451613020495234820[43] = 0;
|
||||||
out_6511275578440991802[44] = 0;
|
out_4451613020495234820[44] = 0;
|
||||||
out_6511275578440991802[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
|
out_4451613020495234820[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
|
||||||
out_6511275578440991802[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
|
out_4451613020495234820[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
|
||||||
out_6511275578440991802[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
out_4451613020495234820[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||||
out_6511275578440991802[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
out_4451613020495234820[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||||
out_6511275578440991802[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
|
out_4451613020495234820[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
|
||||||
out_6511275578440991802[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
|
out_4451613020495234820[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
|
||||||
out_6511275578440991802[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
|
out_4451613020495234820[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
|
||||||
out_6511275578440991802[52] = dt*stiffness_front*state[0]/(mass*state[1]);
|
out_4451613020495234820[52] = dt*stiffness_front*state[0]/(mass*state[1]);
|
||||||
out_6511275578440991802[53] = -9.8100000000000005*dt;
|
out_4451613020495234820[53] = -9.8100000000000005*dt;
|
||||||
out_6511275578440991802[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
|
out_4451613020495234820[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
|
||||||
out_6511275578440991802[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
|
out_4451613020495234820[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
|
||||||
out_6511275578440991802[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
out_4451613020495234820[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||||
out_6511275578440991802[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
out_4451613020495234820[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||||
out_6511275578440991802[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
|
out_4451613020495234820[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
|
||||||
out_6511275578440991802[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
|
out_4451613020495234820[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
|
||||||
out_6511275578440991802[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
|
out_4451613020495234820[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
|
||||||
out_6511275578440991802[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
out_4451613020495234820[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||||
out_6511275578440991802[62] = 0;
|
out_4451613020495234820[62] = 0;
|
||||||
out_6511275578440991802[63] = 0;
|
out_4451613020495234820[63] = 0;
|
||||||
out_6511275578440991802[64] = 0;
|
out_4451613020495234820[64] = 0;
|
||||||
out_6511275578440991802[65] = 0;
|
out_4451613020495234820[65] = 0;
|
||||||
out_6511275578440991802[66] = 0;
|
out_4451613020495234820[66] = 0;
|
||||||
out_6511275578440991802[67] = 0;
|
out_4451613020495234820[67] = 0;
|
||||||
out_6511275578440991802[68] = 0;
|
out_4451613020495234820[68] = 0;
|
||||||
out_6511275578440991802[69] = 0;
|
out_4451613020495234820[69] = 0;
|
||||||
out_6511275578440991802[70] = 1;
|
out_4451613020495234820[70] = 1;
|
||||||
out_6511275578440991802[71] = 0;
|
out_4451613020495234820[71] = 0;
|
||||||
out_6511275578440991802[72] = 0;
|
out_4451613020495234820[72] = 0;
|
||||||
out_6511275578440991802[73] = 0;
|
out_4451613020495234820[73] = 0;
|
||||||
out_6511275578440991802[74] = 0;
|
out_4451613020495234820[74] = 0;
|
||||||
out_6511275578440991802[75] = 0;
|
out_4451613020495234820[75] = 0;
|
||||||
out_6511275578440991802[76] = 0;
|
out_4451613020495234820[76] = 0;
|
||||||
out_6511275578440991802[77] = 0;
|
out_4451613020495234820[77] = 0;
|
||||||
out_6511275578440991802[78] = 0;
|
out_4451613020495234820[78] = 0;
|
||||||
out_6511275578440991802[79] = 0;
|
out_4451613020495234820[79] = 0;
|
||||||
out_6511275578440991802[80] = 1;
|
out_4451613020495234820[80] = 1;
|
||||||
}
|
}
|
||||||
void h_25(double *state, double *unused, double *out_2633570630840598096) {
|
void h_25(double *state, double *unused, double *out_5140546513771631716) {
|
||||||
out_2633570630840598096[0] = state[6];
|
out_5140546513771631716[0] = state[6];
|
||||||
}
|
}
|
||||||
void H_25(double *state, double *unused, double *out_2394126656704625717) {
|
void H_25(double *state, double *unused, double *out_1930738904278685141) {
|
||||||
out_2394126656704625717[0] = 0;
|
out_1930738904278685141[0] = 0;
|
||||||
out_2394126656704625717[1] = 0;
|
out_1930738904278685141[1] = 0;
|
||||||
out_2394126656704625717[2] = 0;
|
out_1930738904278685141[2] = 0;
|
||||||
out_2394126656704625717[3] = 0;
|
out_1930738904278685141[3] = 0;
|
||||||
out_2394126656704625717[4] = 0;
|
out_1930738904278685141[4] = 0;
|
||||||
out_2394126656704625717[5] = 0;
|
out_1930738904278685141[5] = 0;
|
||||||
out_2394126656704625717[6] = 1;
|
out_1930738904278685141[6] = 1;
|
||||||
out_2394126656704625717[7] = 0;
|
out_1930738904278685141[7] = 0;
|
||||||
out_2394126656704625717[8] = 0;
|
out_1930738904278685141[8] = 0;
|
||||||
}
|
}
|
||||||
void h_24(double *state, double *unused, double *out_3094145344632818755) {
|
void h_24(double *state, double *unused, double *out_867003127290538570) {
|
||||||
out_3094145344632818755[0] = state[4];
|
out_867003127290538570[0] = state[4];
|
||||||
out_3094145344632818755[1] = state[5];
|
out_867003127290538570[1] = state[5];
|
||||||
}
|
}
|
||||||
void H_24(double *state, double *unused, double *out_665263537527311648) {
|
void H_24(double *state, double *unused, double *out_4156446688257553703) {
|
||||||
out_665263537527311648[0] = 0;
|
out_4156446688257553703[0] = 0;
|
||||||
out_665263537527311648[1] = 0;
|
out_4156446688257553703[1] = 0;
|
||||||
out_665263537527311648[2] = 0;
|
out_4156446688257553703[2] = 0;
|
||||||
out_665263537527311648[3] = 0;
|
out_4156446688257553703[3] = 0;
|
||||||
out_665263537527311648[4] = 1;
|
out_4156446688257553703[4] = 1;
|
||||||
out_665263537527311648[5] = 0;
|
out_4156446688257553703[5] = 0;
|
||||||
out_665263537527311648[6] = 0;
|
out_4156446688257553703[6] = 0;
|
||||||
out_665263537527311648[7] = 0;
|
out_4156446688257553703[7] = 0;
|
||||||
out_665263537527311648[8] = 0;
|
out_4156446688257553703[8] = 0;
|
||||||
out_665263537527311648[9] = 0;
|
out_4156446688257553703[9] = 0;
|
||||||
out_665263537527311648[10] = 0;
|
out_4156446688257553703[10] = 0;
|
||||||
out_665263537527311648[11] = 0;
|
out_4156446688257553703[11] = 0;
|
||||||
out_665263537527311648[12] = 0;
|
out_4156446688257553703[12] = 0;
|
||||||
out_665263537527311648[13] = 0;
|
out_4156446688257553703[13] = 0;
|
||||||
out_665263537527311648[14] = 1;
|
out_4156446688257553703[14] = 1;
|
||||||
out_665263537527311648[15] = 0;
|
out_4156446688257553703[15] = 0;
|
||||||
out_665263537527311648[16] = 0;
|
out_4156446688257553703[16] = 0;
|
||||||
out_665263537527311648[17] = 0;
|
out_4156446688257553703[17] = 0;
|
||||||
}
|
}
|
||||||
void h_30(double *state, double *unused, double *out_1872662776110252318) {
|
void h_30(double *state, double *unused, double *out_5297733182122760861) {
|
||||||
out_1872662776110252318[0] = state[4];
|
out_5297733182122760861[0] = state[4];
|
||||||
}
|
}
|
||||||
void H_30(double *state, double *unused, double *out_9135927075513309144) {
|
void H_30(double *state, double *unused, double *out_8847429245770301896) {
|
||||||
out_9135927075513309144[0] = 0;
|
out_8847429245770301896[0] = 0;
|
||||||
out_9135927075513309144[1] = 0;
|
out_8847429245770301896[1] = 0;
|
||||||
out_9135927075513309144[2] = 0;
|
out_8847429245770301896[2] = 0;
|
||||||
out_9135927075513309144[3] = 0;
|
out_8847429245770301896[3] = 0;
|
||||||
out_9135927075513309144[4] = 1;
|
out_8847429245770301896[4] = 1;
|
||||||
out_9135927075513309144[5] = 0;
|
out_8847429245770301896[5] = 0;
|
||||||
out_9135927075513309144[6] = 0;
|
out_8847429245770301896[6] = 0;
|
||||||
out_9135927075513309144[7] = 0;
|
out_8847429245770301896[7] = 0;
|
||||||
out_9135927075513309144[8] = 0;
|
out_8847429245770301896[8] = 0;
|
||||||
}
|
}
|
||||||
void h_26(double *state, double *unused, double *out_2552698139187979215) {
|
void h_26(double *state, double *unused, double *out_8147337623925945110) {
|
||||||
out_2552698139187979215[0] = state[7];
|
out_8147337623925945110[0] = state[7];
|
||||||
}
|
}
|
||||||
void H_26(double *state, double *unused, double *out_1347376662169430507) {
|
void H_26(double *state, double *unused, double *out_1810764414595371083) {
|
||||||
out_1347376662169430507[0] = 0;
|
out_1810764414595371083[0] = 0;
|
||||||
out_1347376662169430507[1] = 0;
|
out_1810764414595371083[1] = 0;
|
||||||
out_1347376662169430507[2] = 0;
|
out_1810764414595371083[2] = 0;
|
||||||
out_1347376662169430507[3] = 0;
|
out_1810764414595371083[3] = 0;
|
||||||
out_1347376662169430507[4] = 0;
|
out_1810764414595371083[4] = 0;
|
||||||
out_1347376662169430507[5] = 0;
|
out_1810764414595371083[5] = 0;
|
||||||
out_1347376662169430507[6] = 0;
|
out_1810764414595371083[6] = 0;
|
||||||
out_1347376662169430507[7] = 1;
|
out_1810764414595371083[7] = 1;
|
||||||
out_1347376662169430507[8] = 0;
|
out_1810764414595371083[8] = 0;
|
||||||
}
|
}
|
||||||
void h_27(double *state, double *unused, double *out_8276300501921554931) {
|
void h_27(double *state, double *unused, double *out_217345790508090885) {
|
||||||
out_8276300501921554931[0] = state[3];
|
out_217345790508090885[0] = state[3];
|
||||||
}
|
}
|
||||||
void H_27(double *state, double *unused, double *out_7136053686395817561) {
|
void H_27(double *state, double *unused, double *out_6672665933969876985) {
|
||||||
out_7136053686395817561[0] = 0;
|
out_6672665933969876985[0] = 0;
|
||||||
out_7136053686395817561[1] = 0;
|
out_6672665933969876985[1] = 0;
|
||||||
out_7136053686395817561[2] = 0;
|
out_6672665933969876985[2] = 0;
|
||||||
out_7136053686395817561[3] = 1;
|
out_6672665933969876985[3] = 1;
|
||||||
out_7136053686395817561[4] = 0;
|
out_6672665933969876985[4] = 0;
|
||||||
out_7136053686395817561[5] = 0;
|
out_6672665933969876985[5] = 0;
|
||||||
out_7136053686395817561[6] = 0;
|
out_6672665933969876985[6] = 0;
|
||||||
out_7136053686395817561[7] = 0;
|
out_6672665933969876985[7] = 0;
|
||||||
out_7136053686395817561[8] = 0;
|
out_6672665933969876985[8] = 0;
|
||||||
}
|
}
|
||||||
void h_29(double *state, double *unused, double *out_6874336043771097963) {
|
void h_29(double *state, double *unused, double *out_675547152666652547) {
|
||||||
out_6874336043771097963[0] = state[1];
|
out_675547152666652547[0] = state[1];
|
||||||
}
|
}
|
||||||
void H_29(double *state, double *unused, double *out_8625695731198916960) {
|
void H_29(double *state, double *unused, double *out_9089083483624857536) {
|
||||||
out_8625695731198916960[0] = 0;
|
out_9089083483624857536[0] = 0;
|
||||||
out_8625695731198916960[1] = 1;
|
out_9089083483624857536[1] = 1;
|
||||||
out_8625695731198916960[2] = 0;
|
out_9089083483624857536[2] = 0;
|
||||||
out_8625695731198916960[3] = 0;
|
out_9089083483624857536[3] = 0;
|
||||||
out_8625695731198916960[4] = 0;
|
out_9089083483624857536[4] = 0;
|
||||||
out_8625695731198916960[5] = 0;
|
out_9089083483624857536[5] = 0;
|
||||||
out_8625695731198916960[6] = 0;
|
out_9089083483624857536[6] = 0;
|
||||||
out_8625695731198916960[7] = 0;
|
out_9089083483624857536[7] = 0;
|
||||||
out_8625695731198916960[8] = 0;
|
out_9089083483624857536[8] = 0;
|
||||||
}
|
}
|
||||||
void h_28(double *state, double *unused, double *out_1452606651919304359) {
|
void h_28(double *state, double *unused, double *out_4927544272607556652) {
|
||||||
out_1452606651919304359[0] = state[0];
|
out_4927544272607556652[0] = state[0];
|
||||||
}
|
}
|
||||||
void H_28(double *state, double *unused, double *out_340291942456735954) {
|
void H_28(double *state, double *unused, double *out_123095809969204622) {
|
||||||
out_340291942456735954[0] = 1;
|
out_123095809969204622[0] = 1;
|
||||||
out_340291942456735954[1] = 0;
|
out_123095809969204622[1] = 0;
|
||||||
out_340291942456735954[2] = 0;
|
out_123095809969204622[2] = 0;
|
||||||
out_340291942456735954[3] = 0;
|
out_123095809969204622[3] = 0;
|
||||||
out_340291942456735954[4] = 0;
|
out_123095809969204622[4] = 0;
|
||||||
out_340291942456735954[5] = 0;
|
out_123095809969204622[5] = 0;
|
||||||
out_340291942456735954[6] = 0;
|
out_123095809969204622[6] = 0;
|
||||||
out_340291942456735954[7] = 0;
|
out_123095809969204622[7] = 0;
|
||||||
out_340291942456735954[8] = 0;
|
out_123095809969204622[8] = 0;
|
||||||
}
|
}
|
||||||
void h_31(double *state, double *unused, double *out_4557978482014913700) {
|
void h_31(double *state, double *unused, double *out_2544246198651735911) {
|
||||||
out_4557978482014913700[0] = state[8];
|
out_2544246198651735911[0] = state[8];
|
||||||
}
|
}
|
||||||
void H_31(double *state, double *unused, double *out_2424772618581586145) {
|
void H_31(double *state, double *unused, double *out_1961384866155645569) {
|
||||||
out_2424772618581586145[0] = 0;
|
out_1961384866155645569[0] = 0;
|
||||||
out_2424772618581586145[1] = 0;
|
out_1961384866155645569[1] = 0;
|
||||||
out_2424772618581586145[2] = 0;
|
out_1961384866155645569[2] = 0;
|
||||||
out_2424772618581586145[3] = 0;
|
out_1961384866155645569[3] = 0;
|
||||||
out_2424772618581586145[4] = 0;
|
out_1961384866155645569[4] = 0;
|
||||||
out_2424772618581586145[5] = 0;
|
out_1961384866155645569[5] = 0;
|
||||||
out_2424772618581586145[6] = 0;
|
out_1961384866155645569[6] = 0;
|
||||||
out_2424772618581586145[7] = 0;
|
out_1961384866155645569[7] = 0;
|
||||||
out_2424772618581586145[8] = 1;
|
out_1961384866155645569[8] = 1;
|
||||||
}
|
}
|
||||||
#include <eigen3/Eigen/Dense>
|
#include <eigen3/Eigen/Dense>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -518,68 +518,68 @@ void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, doubl
|
|||||||
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) {
|
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) {
|
||||||
update<1, 3, 0>(in_x, in_P, h_31, H_31, NULL, in_z, in_R, in_ea, MAHA_THRESH_31);
|
update<1, 3, 0>(in_x, in_P, h_31, H_31, NULL, in_z, in_R, in_ea, MAHA_THRESH_31);
|
||||||
}
|
}
|
||||||
void car_err_fun(double *nom_x, double *delta_x, double *out_7311248151803822396) {
|
void car_err_fun(double *nom_x, double *delta_x, double *out_1982741958495934934) {
|
||||||
err_fun(nom_x, delta_x, out_7311248151803822396);
|
err_fun(nom_x, delta_x, out_1982741958495934934);
|
||||||
}
|
}
|
||||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_5602719869542378501) {
|
void car_inv_err_fun(double *nom_x, double *true_x, double *out_1965858196176103805) {
|
||||||
inv_err_fun(nom_x, true_x, out_5602719869542378501);
|
inv_err_fun(nom_x, true_x, out_1965858196176103805);
|
||||||
}
|
}
|
||||||
void car_H_mod_fun(double *state, double *out_6859429191092688662) {
|
void car_H_mod_fun(double *state, double *out_7322816943518629238) {
|
||||||
H_mod_fun(state, out_6859429191092688662);
|
H_mod_fun(state, out_7322816943518629238);
|
||||||
}
|
}
|
||||||
void car_f_fun(double *state, double dt, double *out_3400060270232460893) {
|
void car_f_fun(double *state, double dt, double *out_6429621653186063469) {
|
||||||
f_fun(state, dt, out_3400060270232460893);
|
f_fun(state, dt, out_6429621653186063469);
|
||||||
}
|
}
|
||||||
void car_F_fun(double *state, double dt, double *out_6511275578440991802) {
|
void car_F_fun(double *state, double dt, double *out_4451613020495234820) {
|
||||||
F_fun(state, dt, out_6511275578440991802);
|
F_fun(state, dt, out_4451613020495234820);
|
||||||
}
|
}
|
||||||
void car_h_25(double *state, double *unused, double *out_2633570630840598096) {
|
void car_h_25(double *state, double *unused, double *out_5140546513771631716) {
|
||||||
h_25(state, unused, out_2633570630840598096);
|
h_25(state, unused, out_5140546513771631716);
|
||||||
}
|
}
|
||||||
void car_H_25(double *state, double *unused, double *out_2394126656704625717) {
|
void car_H_25(double *state, double *unused, double *out_1930738904278685141) {
|
||||||
H_25(state, unused, out_2394126656704625717);
|
H_25(state, unused, out_1930738904278685141);
|
||||||
}
|
}
|
||||||
void car_h_24(double *state, double *unused, double *out_3094145344632818755) {
|
void car_h_24(double *state, double *unused, double *out_867003127290538570) {
|
||||||
h_24(state, unused, out_3094145344632818755);
|
h_24(state, unused, out_867003127290538570);
|
||||||
}
|
}
|
||||||
void car_H_24(double *state, double *unused, double *out_665263537527311648) {
|
void car_H_24(double *state, double *unused, double *out_4156446688257553703) {
|
||||||
H_24(state, unused, out_665263537527311648);
|
H_24(state, unused, out_4156446688257553703);
|
||||||
}
|
}
|
||||||
void car_h_30(double *state, double *unused, double *out_1872662776110252318) {
|
void car_h_30(double *state, double *unused, double *out_5297733182122760861) {
|
||||||
h_30(state, unused, out_1872662776110252318);
|
h_30(state, unused, out_5297733182122760861);
|
||||||
}
|
}
|
||||||
void car_H_30(double *state, double *unused, double *out_9135927075513309144) {
|
void car_H_30(double *state, double *unused, double *out_8847429245770301896) {
|
||||||
H_30(state, unused, out_9135927075513309144);
|
H_30(state, unused, out_8847429245770301896);
|
||||||
}
|
}
|
||||||
void car_h_26(double *state, double *unused, double *out_2552698139187979215) {
|
void car_h_26(double *state, double *unused, double *out_8147337623925945110) {
|
||||||
h_26(state, unused, out_2552698139187979215);
|
h_26(state, unused, out_8147337623925945110);
|
||||||
}
|
}
|
||||||
void car_H_26(double *state, double *unused, double *out_1347376662169430507) {
|
void car_H_26(double *state, double *unused, double *out_1810764414595371083) {
|
||||||
H_26(state, unused, out_1347376662169430507);
|
H_26(state, unused, out_1810764414595371083);
|
||||||
}
|
}
|
||||||
void car_h_27(double *state, double *unused, double *out_8276300501921554931) {
|
void car_h_27(double *state, double *unused, double *out_217345790508090885) {
|
||||||
h_27(state, unused, out_8276300501921554931);
|
h_27(state, unused, out_217345790508090885);
|
||||||
}
|
}
|
||||||
void car_H_27(double *state, double *unused, double *out_7136053686395817561) {
|
void car_H_27(double *state, double *unused, double *out_6672665933969876985) {
|
||||||
H_27(state, unused, out_7136053686395817561);
|
H_27(state, unused, out_6672665933969876985);
|
||||||
}
|
}
|
||||||
void car_h_29(double *state, double *unused, double *out_6874336043771097963) {
|
void car_h_29(double *state, double *unused, double *out_675547152666652547) {
|
||||||
h_29(state, unused, out_6874336043771097963);
|
h_29(state, unused, out_675547152666652547);
|
||||||
}
|
}
|
||||||
void car_H_29(double *state, double *unused, double *out_8625695731198916960) {
|
void car_H_29(double *state, double *unused, double *out_9089083483624857536) {
|
||||||
H_29(state, unused, out_8625695731198916960);
|
H_29(state, unused, out_9089083483624857536);
|
||||||
}
|
}
|
||||||
void car_h_28(double *state, double *unused, double *out_1452606651919304359) {
|
void car_h_28(double *state, double *unused, double *out_4927544272607556652) {
|
||||||
h_28(state, unused, out_1452606651919304359);
|
h_28(state, unused, out_4927544272607556652);
|
||||||
}
|
}
|
||||||
void car_H_28(double *state, double *unused, double *out_340291942456735954) {
|
void car_H_28(double *state, double *unused, double *out_123095809969204622) {
|
||||||
H_28(state, unused, out_340291942456735954);
|
H_28(state, unused, out_123095809969204622);
|
||||||
}
|
}
|
||||||
void car_h_31(double *state, double *unused, double *out_4557978482014913700) {
|
void car_h_31(double *state, double *unused, double *out_2544246198651735911) {
|
||||||
h_31(state, unused, out_4557978482014913700);
|
h_31(state, unused, out_2544246198651735911);
|
||||||
}
|
}
|
||||||
void car_H_31(double *state, double *unused, double *out_2424772618581586145) {
|
void car_H_31(double *state, double *unused, double *out_1961384866155645569) {
|
||||||
H_31(state, unused, out_2424772618581586145);
|
H_31(state, unused, out_1961384866155645569);
|
||||||
}
|
}
|
||||||
void car_predict(double *in_x, double *in_P, double *in_Q, double dt) {
|
void car_predict(double *in_x, double *in_P, double *in_Q, double dt) {
|
||||||
predict(in_x, in_P, in_Q, dt);
|
predict(in_x, in_P, in_Q, dt);
|
||||||
|
|||||||
@@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl
|
|||||||
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||||
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||||
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||||
void car_err_fun(double *nom_x, double *delta_x, double *out_7311248151803822396);
|
void car_err_fun(double *nom_x, double *delta_x, double *out_1982741958495934934);
|
||||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_5602719869542378501);
|
void car_inv_err_fun(double *nom_x, double *true_x, double *out_1965858196176103805);
|
||||||
void car_H_mod_fun(double *state, double *out_6859429191092688662);
|
void car_H_mod_fun(double *state, double *out_7322816943518629238);
|
||||||
void car_f_fun(double *state, double dt, double *out_3400060270232460893);
|
void car_f_fun(double *state, double dt, double *out_6429621653186063469);
|
||||||
void car_F_fun(double *state, double dt, double *out_6511275578440991802);
|
void car_F_fun(double *state, double dt, double *out_4451613020495234820);
|
||||||
void car_h_25(double *state, double *unused, double *out_2633570630840598096);
|
void car_h_25(double *state, double *unused, double *out_5140546513771631716);
|
||||||
void car_H_25(double *state, double *unused, double *out_2394126656704625717);
|
void car_H_25(double *state, double *unused, double *out_1930738904278685141);
|
||||||
void car_h_24(double *state, double *unused, double *out_3094145344632818755);
|
void car_h_24(double *state, double *unused, double *out_867003127290538570);
|
||||||
void car_H_24(double *state, double *unused, double *out_665263537527311648);
|
void car_H_24(double *state, double *unused, double *out_4156446688257553703);
|
||||||
void car_h_30(double *state, double *unused, double *out_1872662776110252318);
|
void car_h_30(double *state, double *unused, double *out_5297733182122760861);
|
||||||
void car_H_30(double *state, double *unused, double *out_9135927075513309144);
|
void car_H_30(double *state, double *unused, double *out_8847429245770301896);
|
||||||
void car_h_26(double *state, double *unused, double *out_2552698139187979215);
|
void car_h_26(double *state, double *unused, double *out_8147337623925945110);
|
||||||
void car_H_26(double *state, double *unused, double *out_1347376662169430507);
|
void car_H_26(double *state, double *unused, double *out_1810764414595371083);
|
||||||
void car_h_27(double *state, double *unused, double *out_8276300501921554931);
|
void car_h_27(double *state, double *unused, double *out_217345790508090885);
|
||||||
void car_H_27(double *state, double *unused, double *out_7136053686395817561);
|
void car_H_27(double *state, double *unused, double *out_6672665933969876985);
|
||||||
void car_h_29(double *state, double *unused, double *out_6874336043771097963);
|
void car_h_29(double *state, double *unused, double *out_675547152666652547);
|
||||||
void car_H_29(double *state, double *unused, double *out_8625695731198916960);
|
void car_H_29(double *state, double *unused, double *out_9089083483624857536);
|
||||||
void car_h_28(double *state, double *unused, double *out_1452606651919304359);
|
void car_h_28(double *state, double *unused, double *out_4927544272607556652);
|
||||||
void car_H_28(double *state, double *unused, double *out_340291942456735954);
|
void car_H_28(double *state, double *unused, double *out_123095809969204622);
|
||||||
void car_h_31(double *state, double *unused, double *out_4557978482014913700);
|
void car_h_31(double *state, double *unused, double *out_2544246198651735911);
|
||||||
void car_H_31(double *state, double *unused, double *out_2424772618581586145);
|
void car_H_31(double *state, double *unused, double *out_1961384866155645569);
|
||||||
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
|
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
|
||||||
void car_set_mass(double x);
|
void car_set_mass(double x);
|
||||||
void car_set_rotational_inertia(double x);
|
void car_set_rotational_inertia(double x);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user