openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.4 KiB

from dataclasses import dataclass, field
from enum import StrEnum, IntFlag
from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms, structs, uds
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts, Device
from opendbc.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
from opendbc.car.vin import Vin
class WMI(StrEnum):
RIVIAN_TRUCK = "7FC"
RIVIAN_MPV = "7PD"
class ModelLine(StrEnum):
R1T = "T" # R1T 4-door Pickup Truck
R1S = "S" # R1S 4-door MPV
class ModelYear(StrEnum):
N_2022 = "N"
P_2023 = "P"
R_2024 = "R"
S_2025 = "S"
@dataclass
class RivianCarDocs(CarDocs):
package: str = "All"
car_parts: CarParts = field(default_factory=CarParts([Device.threex_angled_mount, CarHarness.rivian]))
setup_video_link: str = "https://youtu.be/uaISd1j7Z4U"
@dataclass
class RivianPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: 'rivian_primary_actuator', Bus.radar: 'rivian_mando_front_radar_generated'})
wmis: set[WMI] = field(default_factory=set)
lines: set[ModelLine] = field(default_factory=set)
years: set[ModelYear] = field(default_factory=set)
class CAR(Platforms):
RIVIAN_R1_GEN1 = RivianPlatformConfig(
# TODO: verify this
[
RivianCarDocs("Rivian R1S 2022-24"),
RivianCarDocs("Rivian R1T 2022-24"),
],
CarSpecs(mass=3206., wheelbase=3.08, steerRatio=15.2),
wmis={WMI.RIVIAN_TRUCK, WMI.RIVIAN_MPV},
lines={ModelLine.R1T, ModelLine.R1S},
years={ModelYear.N_2022, ModelYear.P_2023, ModelYear.R_2024},
)
def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str]:
# Rivian VIN reference: https://www.rivianforums.com/forum/threads/rivian-vin-decoder.1546
vin_obj = Vin(vin)
line = vin_obj.vds[:1]
year = vin_obj.vis[:1]
candidates = set()
for platform in CAR:
if vin_obj.wmi in platform.config.wmis and line in platform.config.lines and year in platform.config.years:
candidates.add(platform)
return {str(c) for c in candidates}
RIVIAN_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
p16(0xf1a0)
RIVIAN_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40])
FW_QUERY_CONFIG = FwQueryConfig(
requests=[
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.SUPPLIER_SOFTWARE_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.SUPPLIER_SOFTWARE_VERSION_RESPONSE],
rx_offset=0x40,
bus=0,
),
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.MANUFACTURER_ECU_HARDWARE_NUMBER_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.MANUFACTURER_ECU_HARDWARE_NUMBER_RESPONSE],
rx_offset=0x40,
bus=0,
logging=True,
),
Request(
[StdQueries.TESTER_PRESENT_REQUEST, RIVIAN_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, RIVIAN_VERSION_RESPONSE],
rx_offset=0x40,
bus=0,
logging=True,
),
],
match_fw_to_car_fuzzy=match_fw_to_car_fuzzy,
)
GEAR_MAP = {
0: structs.CarState.GearShifter.unknown,
1: structs.CarState.GearShifter.park,
2: structs.CarState.GearShifter.reverse,
3: structs.CarState.GearShifter.neutral,
4: structs.CarState.GearShifter.drive,
}
class CarControllerParams:
# The R1T 2023 and R1S 2023 we tested on achieves slightly more lateral acceleration going left vs. right
# and lateral acceleration falls linearly as speed decreases from 38 mph to 20 mph. These values are set
# conservatively to reach a maximum of 3.0 m/s^2 turning left at 80 mph
# These refer to turning left:
# 250 is ~2.8 m/s^2 above 17 m/s, then linearly ramps to ~1.6 m/s^2 from 17 m/s to 9 m/s
# TODO: it is theorized older models have different steering racks and achieve down to half the
# lateral acceleration referenced here at all speeds. detect this and ship a torque increase for those models
STEER_MAX = 250 # 350 is intended to maintain lateral accel, not increase it
STEER_MAX_LOOKUP = [9, 17], [350, 250]
STEER_STEP = 1
STEER_DELTA_UP = 3 # torque increase per refresh
STEER_DELTA_DOWN = 5 # torque decrease per refresh
STEER_DRIVER_ALLOWANCE = 100 # allowed driver torque before start limiting
STEER_DRIVER_MULTIPLIER = 2 # weight driver torque
STEER_DRIVER_FACTOR = 100
ACCEL_MIN = -3.5 # m/s^2
ACCEL_MAX = 2.0 # m/s^2
def __init__(self, CP):
pass
class RivianSafetyFlags(IntFlag):
LONG_CONTROL = 1
DBC = CAR.create_dbc_map()