mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 17:13:54 +08:00
Fix Ford qualification coverage, MISRA declarations and test fixtures
Preserve geometry, steering limits, defaults and fault checks.
This commit is contained in:
@@ -3,6 +3,7 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from opendbc.car.ford.interface import CarInterface
|
||||
from opendbc.car.ford.lateral_strategy import FordLateralController
|
||||
from opendbc.car.ford.values import CAR
|
||||
|
||||
@@ -36,7 +37,7 @@ def test_typed_saved_blends_reach_owner_without_model(values, expected, monkeypa
|
||||
for key, value in zip(keys, values, strict=True):
|
||||
saved.put(key, value, block=True)
|
||||
inputs = controller_extensions.ManualTurnInputs(saved)
|
||||
owner = FordLateralController(SimpleNamespace(carFingerprint=CAR.FORD_RANGER_MK2))
|
||||
owner = FordLateralController(CarInterface.get_non_essential_params(CAR.FORD_RANGER_MK2))
|
||||
calls = []
|
||||
setter = owner.set_blend_settings
|
||||
|
||||
@@ -66,7 +67,7 @@ def test_typed_saved_blends_reach_owner_without_model(values, expected, monkeypa
|
||||
@pytest.mark.parametrize("desired,predicted,direction", ((-0.0005, -0.002, 1), (0.0005, 0.002, 2),
|
||||
(-0.001, -0.003, 2), (0.001, 0.003, 1)))
|
||||
def test_saved_blends_preserve_source_units_and_lane_direction(desired, predicted, direction):
|
||||
owner = FordLateralController(SimpleNamespace(carFingerprint=CAR.FORD_RANGER_MK2))
|
||||
owner = FordLateralController(CarInterface.get_non_essential_params(CAR.FORD_RANGER_MK2))
|
||||
owner.set_blend_settings(0.25, 0.65, 1.1)
|
||||
owner.model = SimpleNamespace(meta=SimpleNamespace(laneChangeState=2, laneChangeDirection=direction))
|
||||
blend = 0.25 + min(abs(desired) / 0.001, 1.0) * 0.4
|
||||
|
||||
@@ -155,3 +155,23 @@ def test_angle_selection_preserves_pinion_and_aol_exact_profile(car, long):
|
||||
cp.alternativeExperience = 32
|
||||
assert cp.safetyConfigs[-1].safetyParam in AOL_WORDS
|
||||
assert configured(cp) and angle_qualified(cp) and qualified(cp, marked_only=True)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('word', [32 | ENABLE, 32 | (1 << SHIFT), 32 | ENABLE | (13 << SHIFT),
|
||||
66 | ENABLE | (1 << SHIFT), 32 | ENABLE | (1 << SHIFT) | 0x4000,
|
||||
32 | ENABLE | (1 << SHIFT) | 0x8000])
|
||||
def test_invalid_pinion_native_profile_denies_all_commands(word):
|
||||
n = libsafety_py.libsafety
|
||||
n.set_alternative_experience(32)
|
||||
n.set_safety_hooks(structs.CarParams.SafetyModel.ford, word)
|
||||
n.set_controls_allowed(True)
|
||||
assert not n.get_ford_pinion_enabled()
|
||||
for address in (0x3D3, 0x3D6, 0x3CA, 0x186, 0x18A, 0x3D8):
|
||||
assert not n.safety_tx_hook(libsafety_py.make_CANPacket(address, 0, bytes(8)))
|
||||
|
||||
|
||||
def test_pinion_rx_capacity_guard_withdraws_authority_without_overwrite():
|
||||
n = libsafety_py.libsafety
|
||||
n.set_alternative_experience(32)
|
||||
n.set_safety_hooks(structs.CarParams.SafetyModel.ford, 66 | ENABLE | (7 << SHIFT))
|
||||
assert n.test_ford_pinion_rx_overflow()
|
||||
|
||||
@@ -114,11 +114,12 @@ static const CurvatureSteeringLimits FORD_STEERING_LIMITS = {
|
||||
};
|
||||
|
||||
static CurvatureSteeringLimits ford_measurement_limits(CurvatureSteeringLimits limits) {
|
||||
const int max_curvature_error = (ford_pinion_enabled && (limits.max_curvature_error < 150)) ? 150 : limits.max_curvature_error;
|
||||
return (CurvatureSteeringLimits){
|
||||
.max_curvature = limits.max_curvature,
|
||||
.curvature_to_can = limits.curvature_to_can,
|
||||
.frequency = limits.frequency,
|
||||
.max_curvature_error = ford_pinion_enabled ? SAFETY_MAX(limits.max_curvature_error, 150) : limits.max_curvature_error,
|
||||
.max_curvature_error = max_curvature_error,
|
||||
.curvature_error_min_speed = limits.curvature_error_min_speed,
|
||||
.max_steer_power = limits.max_steer_power,
|
||||
};
|
||||
@@ -532,14 +533,31 @@ static void ford_aol_bind_tx(safety_config *ret, CanMsg workspace[7]) {
|
||||
}
|
||||
}
|
||||
|
||||
static RxCheck ford_rx_workspace[11];
|
||||
|
||||
static void ford_append_pinion_rx(safety_config *config, RxCheck workspace[11]) {
|
||||
if (config->rx_checks_len <= 10) {
|
||||
const int count = config->rx_checks_len;
|
||||
for (int i = 0; i < count; i++) {
|
||||
workspace[i] = config->rx_checks[i];
|
||||
}
|
||||
workspace[count] = (RxCheck){.msg = {{FORD_SteeringPinion_Data, 0, 8, 100U,
|
||||
.max_counter = 15U, .ignore_checksum = true}, {0}, {0}}};
|
||||
config->rx_checks = workspace;
|
||||
config->rx_checks_len = count + 1;
|
||||
} else {
|
||||
config->tx_msgs = NULL;
|
||||
config->tx_msgs_len = 0;
|
||||
ford_aol_reset();
|
||||
}
|
||||
}
|
||||
|
||||
static safety_config ford_init(uint16_t configured_param) {
|
||||
static RxCheck ford_rx_workspace[11];
|
||||
const bool pinion_valid = ford_pinion_word_valid(configured_param);
|
||||
const uint16_t profile_param = ford_pinion_base_word(configured_param);
|
||||
const uint16_t geometry = (configured_param >> 10U) & 15U;
|
||||
ford_pinion_enabled = pinion_valid && ((configured_param & FORD_PINION_ENABLE) != 0U);
|
||||
ford_pinion_params = ford_pinion_enabled ? &ford_pinion_geometry[geometry] : &ford_pinion_geometry[0];
|
||||
ford_pinion_params = ford_pinion_geometry_at(ford_pinion_enabled ? geometry : 0U);
|
||||
const uint16_t bp_param = profile_param & ~256U;
|
||||
const bool joint_angle = ((unsigned int)alternative_experience == 32U) &&
|
||||
((bp_param == 146U) || (bp_param == 147U) || (bp_param == 160U) || (bp_param == 161U) || (bp_param == 194U) || (bp_param == 195U));
|
||||
@@ -746,20 +764,7 @@ static safety_config ford_init(uint16_t configured_param) {
|
||||
}
|
||||
if (ford_pinion_enabled) {
|
||||
// Append after profile-specific RX selection so AOL retains every existing check.
|
||||
if (ret.rx_checks_len <= 10) {
|
||||
const int count = ret.rx_checks_len;
|
||||
for (int i = 0; i < count; i++) {
|
||||
ford_rx_workspace[i] = ret.rx_checks[i];
|
||||
}
|
||||
ford_rx_workspace[count] = (RxCheck){.msg = {{FORD_SteeringPinion_Data, 0, 8, 100U,
|
||||
.max_counter = 15U, .ignore_checksum = true}, {0}, {0}}};
|
||||
ret.rx_checks = ford_rx_workspace;
|
||||
ret.rx_checks_len = count + 1;
|
||||
} else {
|
||||
ret.tx_msgs = NULL;
|
||||
ret.tx_msgs_len = 0;
|
||||
ford_aol_reset();
|
||||
}
|
||||
ford_append_pinion_rx(&ret, ford_rx_workspace);
|
||||
}
|
||||
if (!pinion_valid) {
|
||||
ret.tx_msgs = NULL;
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
#pragma once
|
||||
#define FORD_PINION_GEOMETRY_COUNT 12U
|
||||
static const AngleSteeringParams ford_pinion_geometry[FORD_PINION_GEOMETRY_COUNT + 1U] = {
|
||||
{.slip_factor = 0.0f, .steer_ratio = 1.0f, .wheelbase = 1.0f}, // 0: invalid
|
||||
{.slip_factor = -0.00062819555f, .steer_ratio = 17.7f, .wheelbase = 2.670f}, // 1: FORD_BRONCO_SPORT_MK1
|
||||
{.slip_factor = -0.00061892325f, .steer_ratio = 16.7f, .wheelbase = 2.710f}, // 2: FORD_ESCAPE_MK4
|
||||
{.slip_factor = -0.00061892325f, .steer_ratio = 16.7f, .wheelbase = 2.710f}, // 3: FORD_ESCAPE_MK4_5
|
||||
{.slip_factor = -0.00045454798f, .steer_ratio = 17.0f, .wheelbase = 3.690f}, // 4: FORD_EXPEDITION_MK4
|
||||
{.slip_factor = -0.00055447339f, .steer_ratio = 16.8f, .wheelbase = 3.025f}, // 5: FORD_EXPLORER_MK6
|
||||
{.slip_factor = -0.00062121569f, .steer_ratio = 15.0f, .wheelbase = 2.700f}, // 6: FORD_FOCUS_MK4
|
||||
{.slip_factor = -0.00045331952f, .steer_ratio = 16.9f, .wheelbase = 3.700f}, // 7: FORD_F_150_LIGHTNING_MK1
|
||||
{.slip_factor = -0.00042037149f, .steer_ratio = 17.0f, .wheelbase = 3.990f}, // 8: FORD_F_150_MK14
|
||||
{.slip_factor = -0.00054528036f, .steer_ratio = 17.0f, .wheelbase = 3.076f}, // 9: FORD_MAVERICK_MK1
|
||||
{.slip_factor = -0.00058852001f, .steer_ratio = 14.8f, .wheelbase = 2.850f}, // 10: FORD_MONDEO_MK5
|
||||
{.slip_factor = -0.00056209187f, .steer_ratio = 17.0f, .wheelbase = 2.984f}, // 11: FORD_MUSTANG_MACH_E_MK1
|
||||
{.slip_factor = -0.00051293030f, .steer_ratio = 17.0f, .wheelbase = 3.270f}, // 12: FORD_RANGER_MK2
|
||||
};
|
||||
|
||||
static const AngleSteeringParams *ford_pinion_geometry_at(uint16_t index) {
|
||||
static const AngleSteeringParams ford_pinion_geometry[FORD_PINION_GEOMETRY_COUNT + 1U] = {
|
||||
{.slip_factor = 0.0f, .steer_ratio = 1.0f, .wheelbase = 1.0f}, // 0: invalid
|
||||
{.slip_factor = -0.00062819555f, .steer_ratio = 17.7f, .wheelbase = 2.670f}, // 1: FORD_BRONCO_SPORT_MK1
|
||||
{.slip_factor = -0.00061892325f, .steer_ratio = 16.7f, .wheelbase = 2.710f}, // 2: FORD_ESCAPE_MK4
|
||||
{.slip_factor = -0.00061892325f, .steer_ratio = 16.7f, .wheelbase = 2.710f}, // 3: FORD_ESCAPE_MK4_5
|
||||
{.slip_factor = -0.00045454798f, .steer_ratio = 17.0f, .wheelbase = 3.690f}, // 4: FORD_EXPEDITION_MK4
|
||||
{.slip_factor = -0.00055447339f, .steer_ratio = 16.8f, .wheelbase = 3.025f}, // 5: FORD_EXPLORER_MK6
|
||||
{.slip_factor = -0.00062121569f, .steer_ratio = 15.0f, .wheelbase = 2.700f}, // 6: FORD_FOCUS_MK4
|
||||
{.slip_factor = -0.00045331952f, .steer_ratio = 16.9f, .wheelbase = 3.700f}, // 7: FORD_F_150_LIGHTNING_MK1
|
||||
{.slip_factor = -0.00042037149f, .steer_ratio = 17.0f, .wheelbase = 3.990f}, // 8: FORD_F_150_MK14
|
||||
{.slip_factor = -0.00054528036f, .steer_ratio = 17.0f, .wheelbase = 3.076f}, // 9: FORD_MAVERICK_MK1
|
||||
{.slip_factor = -0.00058852001f, .steer_ratio = 14.8f, .wheelbase = 2.850f}, // 10: FORD_MONDEO_MK5
|
||||
{.slip_factor = -0.00056209187f, .steer_ratio = 17.0f, .wheelbase = 2.984f}, // 11: FORD_MUSTANG_MACH_E_MK1
|
||||
{.slip_factor = -0.00051293030f, .steer_ratio = 17.0f, .wheelbase = 3.270f}, // 12: FORD_RANGER_MK2
|
||||
};
|
||||
return &ford_pinion_geometry[index];
|
||||
}
|
||||
|
||||
static bool ford_pinion_enabled = false;
|
||||
static const AngleSteeringParams *ford_pinion_params = &ford_pinion_geometry[0];
|
||||
static const AngleSteeringParams *ford_pinion_params = NULL;
|
||||
|
||||
@@ -460,7 +460,17 @@ bool safety_test_hyundai_gv60_catalog_rejection(bool alternate) {
|
||||
// Pinion protocol introspection for exact host/native geometry and namespace tests.
|
||||
uint16_t get_ford_pinion_base(uint16_t word) { return ford_pinion_base_word(word); }
|
||||
bool get_ford_pinion_enabled(void) { return ford_pinion_enabled; }
|
||||
float get_ford_pinion_slip(int index) { return ford_pinion_geometry[index].slip_factor; }
|
||||
float get_ford_pinion_ratio(int index) { return ford_pinion_geometry[index].steer_ratio; }
|
||||
float get_ford_pinion_wheelbase(int index) { return ford_pinion_geometry[index].wheelbase; }
|
||||
float get_ford_pinion_slip(int index) { return ford_pinion_geometry_at((uint16_t)index)->slip_factor; }
|
||||
float get_ford_pinion_ratio(int index) { return ford_pinion_geometry_at((uint16_t)index)->steer_ratio; }
|
||||
float get_ford_pinion_wheelbase(int index) { return ford_pinion_geometry_at((uint16_t)index)->wheelbase; }
|
||||
int get_ford_pinion_rx_count(void) { return current_safety_config.rx_checks_len; }
|
||||
|
||||
bool test_ford_pinion_rx_overflow(void) {
|
||||
RxCheck workspace[11] = {0};
|
||||
safety_config config = current_safety_config;
|
||||
config.rx_checks = workspace;
|
||||
config.rx_checks_len = 11;
|
||||
ford_append_pinion_rx(&config, workspace);
|
||||
return (config.tx_msgs == NULL) && (config.tx_msgs_len == 0) &&
|
||||
(config.rx_checks_len == 11) && !ford_aol_enabled;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Actual typed Params, Galaxy parked write, and startup configuration for pinion."""
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
from opendbc.car import gen_empty_fingerprint
|
||||
@@ -20,8 +19,11 @@ def test_real_galaxy_typed_parked_selection_and_stale_dependency():
|
||||
params.put_bool('AlwaysOnLateral', False, block=True)
|
||||
cp = ford_params(CAR.FORD_EXPLORER_MK6)
|
||||
parked = True
|
||||
context = SimpleNamespace(sample=lambda: AuthorityContext(parked, cp, cp.as_reader().as_builder().to_bytes()))
|
||||
gateway = SettingsGateway(params, context)
|
||||
class TestContext:
|
||||
def sample(self) -> AuthorityContext:
|
||||
return AuthorityContext(parked, cp, cp.as_reader().as_builder().to_bytes())
|
||||
|
||||
gateway = SettingsGateway(params, TestContext())
|
||||
try:
|
||||
page = gateway.page('torque', 'pinion-test', b'generation')
|
||||
index, row = next((i, row) for i, row in enumerate(page['rows']) if row['label'] == 'Use Pinion Yaw Sensor')
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "bac00362c2a71e8b613fc38a6654dca4dfdf46b270f57f267da490c04e7cebf0", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "c6bef01a6bedfafd1c7e9cd62762c0fd4f5a8eeaa16018d6d5fc369c37ff56b9", "schema_version": 1}
|
||||
|
||||
@@ -31,7 +31,8 @@ def targets_for_coverage(root=ROOT):
|
||||
selected.add(f'{relative}::{node.name}')
|
||||
# These existing end-to-end callers bind the supplied library. Other vehicle suites
|
||||
# deliberately compile distinct DEBUG/RELEASE artifacts and retain their own gates.
|
||||
for relative in ('openpilot/starpilot/car/nissan/tests/test_aol.py',
|
||||
for relative in ('opendbc_repo/opendbc/car/ford/tests/test_pinion_measurement.py',
|
||||
'openpilot/starpilot/car/nissan/tests/test_aol.py',
|
||||
'openpilot/starpilot/car/rivian/tests/test_aol_native.py'):
|
||||
if (root / relative).is_file():
|
||||
selected.add(relative)
|
||||
|
||||
@@ -95,7 +95,8 @@ class TestSafetyQualificationRunner(TestCase):
|
||||
def test_coverage_catalog_includes_native_pytest_and_external_callers(self):
|
||||
from tools.ci import safety_pytest_coverage as coverage
|
||||
selected = coverage.targets_for_coverage(qualification.ROOT)
|
||||
for name in ('opendbc_repo/opendbc/safety/tests/test_tesla_preap_pedal.py::test_actual_registered_priming_rate_absolute_bus_and_counter_bounds',
|
||||
for name in ('opendbc_repo/opendbc/car/ford/tests/test_pinion_measurement.py',
|
||||
'opendbc_repo/opendbc/safety/tests/test_tesla_preap_pedal.py::test_actual_registered_priming_rate_absolute_bus_and_counter_bounds',
|
||||
'openpilot/starpilot/car/nissan/tests/test_aol.py',
|
||||
'openpilot/starpilot/car/rivian/tests/test_aol_native.py'):
|
||||
self.assertIn(name, selected)
|
||||
|
||||
Reference in New Issue
Block a user