diff --git a/docs/CARS.md b/docs/CARS.md index 136101e97b..89d282c021 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -31,11 +31,11 @@ A supported vehicle is one that just works when you install a comma three. All s |Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Chrysler|Pacifica Hybrid 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|| -|Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Explorer 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Kuga 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Ford|Maverick 2022-23|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Maverick 2022-23|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G70 2020|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G80 2017|All|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
View- 1 Hyundai J connector
- 1 RJ45 cable (7 ft)
- 1 comma power v2
- 1 comma three
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/release/files_common b/release/files_common index 781600ac8f..af1fca176f 100644 --- a/release/files_common +++ b/release/files_common @@ -181,7 +181,6 @@ selfdrive/controls/lib/desire_helper.py selfdrive/controls/lib/drive_helpers.py selfdrive/controls/lib/events.py selfdrive/controls/lib/latcontrol_angle.py -selfdrive/controls/lib/latcontrol_indi.py selfdrive/controls/lib/latcontrol_torque.py selfdrive/controls/lib/latcontrol_pid.py selfdrive/controls/lib/latcontrol.py diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index c1ebc35cab..23b460147e 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -55,7 +55,7 @@ class EnumBase(Enum): class Mount(EnumBase): mount = BasePart("mount") - angled_mount = BasePart("angled mount") + angled_mount_8_degrees = BasePart("angled mount (8 degrees)") class Cable(EnumBase): @@ -120,7 +120,7 @@ class CarHarness(EnumBase): class Device(EnumBase): three = BasePart("comma three", parts=[Mount.mount, Cable.right_angle_obd_c_cable_1_5ft]) # variant of comma three with angled mounts - three_angled_mount = BasePart("comma three", parts=[Mount.angled_mount, Cable.right_angle_obd_c_cable_1_5ft]) + three_angled_mount = BasePart("comma three", parts=[Mount.angled_mount_8_degrees, Cable.right_angle_obd_c_cable_1_5ft]) red_panda = BasePart("red panda") diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index fbb6917b34..edc40f629c 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -4,7 +4,7 @@ from typing import Dict, List, Set, Union from cereal import car from selfdrive.car import AngleRateLimit, dbc_dict -from selfdrive.car.docs_definitions import CarInfo, CarParts, CarHarness, Device +from selfdrive.car.docs_definitions import CarHarness, CarInfo, CarParts, Device from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -29,8 +29,8 @@ class CarControllerParams: ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 25], angle_v=[0.000225, 0.00015]) CURVATURE_ERROR = 0.002 # ~6 degrees at 10 m/s, ~10 degrees at 35 m/s - ACCEL_MAX = 2.0 # m/s^s max acceleration - ACCEL_MIN = -3.5 # m/s^s max deceleration + ACCEL_MAX = 2.0 # m/s^2 max acceleration + ACCEL_MIN = -3.5 # m/s^2 max deceleration MIN_GAS = -0.5 INACTIVE_GAS = -5.0 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6d653091d2..3903340c8d 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -20,7 +20,6 @@ from selfdrive.controls.lib.drive_helpers import VCruiseHelper, get_lag_adjusted from selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED from selfdrive.controls.lib.longcontrol import LongControl from selfdrive.controls.lib.latcontrol_pid import LatControlPID -from selfdrive.controls.lib.latcontrol_indi import LatControlINDI from selfdrive.controls.lib.latcontrol_angle import LatControlAngle, STEER_ANGLE_SATURATION_THRESHOLD from selfdrive.controls.lib.latcontrol_torque import LatControlTorque from selfdrive.controls.lib.events import Events, ET @@ -152,8 +151,6 @@ class Controls: self.LaC = LatControlAngle(self.CP, self.CI) elif self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP, self.CI) - elif self.CP.lateralTuning.which() == 'indi': - self.LaC = LatControlINDI(self.CP, self.CI) elif self.CP.lateralTuning.which() == 'torque': self.LaC = LatControlTorque(self.CP, self.CI) diff --git a/selfdrive/controls/lib/latcontrol_indi.py b/selfdrive/controls/lib/latcontrol_indi.py deleted file mode 100644 index dca82c6729..0000000000 --- a/selfdrive/controls/lib/latcontrol_indi.py +++ /dev/null @@ -1,120 +0,0 @@ -import math -import numpy as np - -from cereal import log -from common.filter_simple import FirstOrderFilter -from common.numpy_fast import clip, interp -from common.realtime import DT_CTRL -from selfdrive.controls.lib.latcontrol import LatControl - - -class LatControlINDI(LatControl): - def __init__(self, CP, CI): - super().__init__(CP, CI) - self.angle_steers_des = 0. - - A = np.array([[1.0, DT_CTRL, 0.0], - [0.0, 1.0, DT_CTRL], - [0.0, 0.0, 1.0]]) - C = np.array([[1.0, 0.0, 0.0], - [0.0, 1.0, 0.0]]) - - # Q = np.matrix([[1e-2, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 10.0]]) - # R = np.matrix([[1e-2, 0.0], [0.0, 1e3]]) - - # (x, l, K) = control.dare(np.transpose(A), np.transpose(C), Q, R) - # K = np.transpose(K) - K = np.array([[7.30262179e-01, 2.07003658e-04], - [7.29394177e+00, 1.39159419e-02], - [1.71022442e+01, 3.38495381e-02]]) - - self.speed = 0. - - self.K = K - self.A_K = A - np.dot(K, C) - self.x = np.array([[0.], [0.], [0.]]) - - self._RC = (CP.lateralTuning.indi.timeConstantBP, CP.lateralTuning.indi.timeConstantV) - self._G = (CP.lateralTuning.indi.actuatorEffectivenessBP, CP.lateralTuning.indi.actuatorEffectivenessV) - self._outer_loop_gain = (CP.lateralTuning.indi.outerLoopGainBP, CP.lateralTuning.indi.outerLoopGainV) - self._inner_loop_gain = (CP.lateralTuning.indi.innerLoopGainBP, CP.lateralTuning.indi.innerLoopGainV) - - self.steer_filter = FirstOrderFilter(0., self.RC, DT_CTRL) - self.reset() - - @property - def RC(self): - return interp(self.speed, self._RC[0], self._RC[1]) - - @property - def G(self): - return interp(self.speed, self._G[0], self._G[1]) - - @property - def outer_loop_gain(self): - return interp(self.speed, self._outer_loop_gain[0], self._outer_loop_gain[1]) - - @property - def inner_loop_gain(self): - return interp(self.speed, self._inner_loop_gain[0], self._inner_loop_gain[1]) - - def reset(self): - super().reset() - self.steer_filter.x = 0. - self.speed = 0. - - def update(self, active, CS, VM, params, last_actuators, steer_limited, desired_curvature, desired_curvature_rate, llk): - self.speed = CS.vEgo - # Update Kalman filter - y = np.array([[math.radians(CS.steeringAngleDeg)], [math.radians(CS.steeringRateDeg)]]) - self.x = np.dot(self.A_K, self.x) + np.dot(self.K, y) - - indi_log = log.ControlsState.LateralINDIState.new_message() - indi_log.steeringAngleDeg = math.degrees(self.x[0]) - indi_log.steeringRateDeg = math.degrees(self.x[1]) - indi_log.steeringAccelDeg = math.degrees(self.x[2]) - - steers_des = VM.get_steer_from_curvature(-desired_curvature, CS.vEgo, params.roll) - steers_des += math.radians(params.angleOffsetDeg) - indi_log.steeringAngleDesiredDeg = math.degrees(steers_des) - - # desired rate is the desired rate of change in the setpoint, not the absolute desired curvature - rate_des = VM.get_steer_from_curvature(-desired_curvature_rate, CS.vEgo, 0) - indi_log.steeringRateDesiredDeg = math.degrees(rate_des) - - if not active: - indi_log.active = False - self.steer_filter.x = 0.0 - output_steer = 0 - else: - # Expected actuator value - self.steer_filter.update_alpha(self.RC) - self.steer_filter.update(last_actuators.steer) - - # Compute acceleration error - rate_sp = self.outer_loop_gain * (steers_des - self.x[0]) + rate_des - accel_sp = self.inner_loop_gain * (rate_sp - self.x[1]) - accel_error = accel_sp - self.x[2] - - # Compute change in actuator - g_inv = 1. / self.G - delta_u = g_inv * accel_error - - # If steering pressed, only allow wind down - if CS.steeringPressed and (delta_u * last_actuators.steer > 0): - delta_u = 0 - - output_steer = self.steer_filter.x + delta_u - - output_steer = clip(output_steer, -self.steer_max, self.steer_max) - - indi_log.active = True - indi_log.rateSetPoint = float(rate_sp) - indi_log.accelSetPoint = float(accel_sp) - indi_log.accelError = float(accel_error) - indi_log.delayedOutput = float(self.steer_filter.x) - indi_log.delta = float(delta_u) - indi_log.output = float(output_steer) - indi_log.saturated = self._check_saturation(self.steer_max - abs(output_steer) < 1e-3, CS, steer_limited) - - return float(output_steer), float(steers_des), indi_log diff --git a/selfdrive/controls/lib/tests/test_latcontrol.py b/selfdrive/controls/lib/tests/test_latcontrol.py index 993774f719..b504b3d125 100755 --- a/selfdrive/controls/lib/tests/test_latcontrol.py +++ b/selfdrive/controls/lib/tests/test_latcontrol.py @@ -10,14 +10,13 @@ from selfdrive.car.toyota.values import CAR as TOYOTA from selfdrive.car.nissan.values import CAR as NISSAN from selfdrive.controls.lib.latcontrol_pid import LatControlPID from selfdrive.controls.lib.latcontrol_torque import LatControlTorque -from selfdrive.controls.lib.latcontrol_indi import LatControlINDI from selfdrive.controls.lib.latcontrol_angle import LatControlAngle from selfdrive.controls.lib.vehicle_model import VehicleModel class TestLatControl(unittest.TestCase): - @parameterized.expand([(HONDA.CIVIC, LatControlPID), (TOYOTA.RAV4, LatControlTorque), (TOYOTA.PRIUS, LatControlINDI), (NISSAN.LEAF, LatControlAngle)]) + @parameterized.expand([(HONDA.CIVIC, LatControlPID), (TOYOTA.RAV4, LatControlTorque), (NISSAN.LEAF, LatControlAngle)]) def test_saturation(self, car_name, controller): CarInterface, CarController, CarState = interfaces[car_name] CP = CarInterface.get_non_essential_params(car_name) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index b9fec9d62d..0c8132343c 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -35,12 +35,6 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { tr("Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off."), "../assets/offroad/icon_openpilot.png", }, - { - "ExperimentalMode", - tr("Experimental Mode"), - "", - "../assets/img_experimental_white.svg", - }, { "ExperimentalLongitudinalEnabled", tr("openpilot Longitudinal Control (Alpha)"), @@ -49,18 +43,24 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { .arg(tr("On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.")), "../assets/offroad/icon_speed_limit.png", }, + { + "ExperimentalMode", + tr("Experimental Mode"), + "", + "../assets/img_experimental_white.svg", + }, + { + "DisengageOnAccelerator", + tr("Disengage on Accelerator Pedal"), + tr("When enabled, pressing the accelerator pedal will disengage openpilot."), + "../assets/offroad/icon_disengage_on_accelerator.svg", + }, { "IsLdwEnabled", tr("Enable Lane Departure Warnings"), tr("Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h)."), "../assets/offroad/icon_warning.png", }, - { - "IsMetric", - tr("Use Metric System"), - tr("Display speed in km/h instead of mph."), - "../assets/offroad/icon_metric.png", - }, { "RecordFront", tr("Record and Upload Driver Camera"), @@ -68,10 +68,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { "../assets/offroad/icon_monitoring.png", }, { - "DisengageOnAccelerator", - tr("Disengage on Accelerator Pedal"), - tr("When enabled, pressing the accelerator pedal will disengage openpilot."), - "../assets/offroad/icon_disengage_on_accelerator.svg", + "IsMetric", + tr("Use Metric System"), + tr("Display speed in km/h instead of mph."), + "../assets/offroad/icon_metric.png", }, #ifdef ENABLE_MAPS { diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc index e1b31489b9..d9938b0fbc 100644 --- a/tools/cabana/dbc/dbcfile.cc +++ b/tools/cabana/dbc/dbcfile.cc @@ -194,8 +194,8 @@ void DBCFile::parseExtraInfo(const QString &content) { static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))"); static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); static QRegularExpression sgm_regexp(R"(^SG_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); - static QRegularExpression msg_comment_regexp(R"(^CM_ BO_ *(\w+) *\"(.*)\";)"); - static QRegularExpression sg_comment_regexp(R"(^CM_ SG_ *(\w+) *(\w+) *\"(.*)\";)"); + static QRegularExpression msg_comment_regexp(R"(^CM_ BO_ *(\w+) *\"([^"]*)\";)"); + static QRegularExpression sg_comment_regexp(R"(^CM_ SG_ *(\w+) *(\w+) *\"([^"]*)\";)"); static QRegularExpression val_regexp(R"(VAL_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*))"); int line_num = 0; @@ -212,7 +212,7 @@ void DBCFile::parseExtraInfo(const QString &content) { uint32_t address = 0; while (!stream.atEnd()) { ++line_num; - line = stream.readLine().trimmed(); + line = stream.readLine(); if (line.startsWith("BO_ ")) { auto match = bo_regexp.match(line); dbc_assert(match.hasMatch()); @@ -244,12 +244,20 @@ void DBCFile::parseExtraInfo(const QString &content) { } } } else if (line.startsWith("CM_ BO_")) { + if (!line.endsWith("\";")) { + int pos = stream.pos() - line.length() - 1; + line = content.mid(pos, content.indexOf("\";", pos)); + } auto match = msg_comment_regexp.match(line); dbc_assert(match.hasMatch()); if (auto m = (cabana::Msg *)msg(match.captured(1).toUInt())) { m->comment = match.captured(2).trimmed(); } } else if (line.startsWith("CM_ SG_ ")) { + if (!line.endsWith("\";")) { + int pos = stream.pos() - line.length() - 1; + line = content.mid(pos, content.indexOf("\";", pos)); + } auto match = sg_comment_regexp.match(line); dbc_assert(match.hasMatch()); if (auto s = get_sig(match.captured(1).toUInt(), match.captured(2))) {