diff --git a/Jenkinsfile b/Jenkinsfile
index d716510bfe..4afb3964f7 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -194,7 +194,7 @@ node {
["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"],
["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"],
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"],
- ["test pigeond", "pytest system/sensord/tests/test_pigeond.py"],
+ ["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"],
["test manager", "pytest selfdrive/manager/test/test_manager.py"],
])
},
diff --git a/common/transformations/camera.py b/common/transformations/camera.py
index 1a7b9c3f80..dc3ca5f388 100644
--- a/common/transformations/camera.py
+++ b/common/transformations/camera.py
@@ -11,6 +11,10 @@ class CameraConfig:
height: int
focal_length: float
+ @property
+ def size(self):
+ return (self.width, self.height)
+
@property
def intrinsics(self):
# aka 'K' aka camera_frame_from_view_frame
@@ -25,33 +29,45 @@ class CameraConfig:
# aka 'K_inv' aka view_frame_from_camera_frame
return np.linalg.inv(self.intrinsics)
+@dataclass(frozen=True)
+class _NoneCameraConfig(CameraConfig):
+ width: int = 0
+ height: int = 0
+ focal_length: float = 0
+
@dataclass(frozen=True)
class DeviceCameraConfig:
fcam: CameraConfig
dcam: CameraConfig
ecam: CameraConfig
-ar_ox_fisheye = CameraConfig(1928, 1208, 567.0) # focal length probably wrong? magnification is not consistent across frame
-ar_ox_config = DeviceCameraConfig(CameraConfig(1928, 1208, 2648.0), ar_ox_fisheye, ar_ox_fisheye)
-os_fisheye = CameraConfig(2688, 1520, 567.0 / 2 * 3)
-os_config = DeviceCameraConfig(CameraConfig(2688, 1520, 2648.0 * 2 / 3), os_fisheye, os_fisheye)
+ def all_cams(self):
+ for cam in ['fcam', 'dcam', 'ecam']:
+ if not isinstance(getattr(self, cam), _NoneCameraConfig):
+ yield cam, getattr(self, cam)
+
+_ar_ox_fisheye = CameraConfig(1928, 1208, 567.0) # focal length probably wrong? magnification is not consistent across frame
+_os_fisheye = CameraConfig(2688, 1520, 567.0 / 2 * 3)
+_ar_ox_config = DeviceCameraConfig(CameraConfig(1928, 1208, 2648.0), _ar_ox_fisheye, _ar_ox_fisheye)
+_os_config = DeviceCameraConfig(CameraConfig(2688, 1520, 2648.0 * 2 / 3), _os_fisheye, _os_fisheye)
+_neo_config = DeviceCameraConfig(CameraConfig(1164, 874, 910.0), CameraConfig(816, 612, 650.0), _NoneCameraConfig())
DEVICE_CAMERAS = {
# A "device camera" is defined by a device type and sensor
# sensor type was never set on eon/neo/two
- ("neo", "unknown"): DeviceCameraConfig(CameraConfig(1164, 874, 910.0), CameraConfig(816, 612, 650.0), CameraConfig(0, 0, 0.)),
+ ("neo", "unknown"): _neo_config,
# unknown here is AR0231, field was added with OX03C10 support
- ("tici", "unknown"): ar_ox_config,
+ ("tici", "unknown"): _ar_ox_config,
# before deviceState.deviceType was set, assume tici AR config
- ("unknown", "ar0231"): ar_ox_config,
- ("unknown", "ox03c10"): ar_ox_config,
+ ("unknown", "ar0231"): _ar_ox_config,
+ ("unknown", "ox03c10"): _ar_ox_config,
# simulator (emulates a tici)
- ("pc", "unknown"): ar_ox_config,
+ ("pc", "unknown"): _ar_ox_config,
}
-prods = itertools.product(('tici', 'tizi', 'mici'), (('ar0231', ar_ox_config), ('ox03c10', ar_ox_config), ('os04c10', os_config)))
+prods = itertools.product(('tici', 'tizi', 'mici'), (('ar0231', _ar_ox_config), ('ox03c10', _ar_ox_config), ('os04c10', _os_config)))
DEVICE_CAMERAS.update({(d, c[0]): c[1] for d, c in prods})
# device/mesh : x->forward, y-> right, z->down
diff --git a/docs/CARS.md b/docs/CARS.md
index 8854a801ab..13381ec202 100644
--- a/docs/CARS.md
+++ b/docs/CARS.md
@@ -47,11 +47,11 @@ A supported vehicle is one that just works when you install a comma device. All
|Ford|Kuga Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Ford|Kuga Plug-in Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Ford|Maverick 2022|LARIAT Luxury|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
-|Ford|Maverick 2023|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+|Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
-|Ford|Maverick Hybrid 2023|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 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|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+|Genesis|G70 2020-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 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|[](##)|[](##)|Parts
- 1 Hyundai J connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Genesis|G80 2018-19|All|Stock|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
|Genesis|G90 2017-18|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 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 e483620052..94af70eff2 100644
--- a/release/files_common
+++ b/release/files_common
@@ -182,6 +182,7 @@ system/hardware/pc/hardware.py
system/ubloxd/.gitignore
system/ubloxd/SConscript
+system/ubloxd/pigeond.py
system/ubloxd/generated/*
system/ubloxd/*.h
system/ubloxd/*.cc
@@ -241,7 +242,6 @@ system/sensord/SConscript
system/sensord/sensors_qcom2.cc
system/sensord/sensors/*.cc
system/sensord/sensors/*.h
-system/sensord/pigeond.py
system/webrtc/__init__.py
system/webrtc/webrtcd.py
diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py
index eb1cf7e7d5..91b922c596 100644
--- a/selfdrive/car/chrysler/carstate.py
+++ b/selfdrive/car/chrysler/carstate.py
@@ -21,10 +21,16 @@ class CarState(CarStateBase):
else:
self.shifter_values = can_define.dv["GEAR"]["PRNDL"]
+ self.prev_distance_button = 0
+ self.distance_button = 0
+
def update(self, cp, cp_cam):
ret = car.CarState.new_message()
+ self.prev_distance_button = self.distance_button
+ self.distance_button = cp.vl["CRUISE_BUTTONS"]["ACC_Distance_Dec"]
+
# lock info
ret.doorOpen = any([cp.vl["BCM_1"]["DOOR_OPEN_FL"],
cp.vl["BCM_1"]["DOOR_OPEN_FR"],
diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py
index eb40bc6f6e..198bf63b10 100755
--- a/selfdrive/car/chrysler/interface.py
+++ b/selfdrive/car/chrysler/interface.py
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
from cereal import car
from panda import Panda
-from openpilot.selfdrive.car import get_safety_config
+from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
+ButtonType = car.CarState.ButtonEvent.Type
+
class CarInterface(CarInterfaceBase):
@staticmethod
@@ -76,6 +78,8 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
+ ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
+
# events
events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low])
diff --git a/selfdrive/car/fingerprints.py b/selfdrive/car/fingerprints.py
index 6a7c3c75be..eaf9002dcd 100644
--- a/selfdrive/car/fingerprints.py
+++ b/selfdrive/car/fingerprints.py
@@ -1,4 +1,8 @@
from openpilot.selfdrive.car.interfaces import get_interface_attr
+from openpilot.selfdrive.car.honda.values import CAR as HONDA
+from openpilot.selfdrive.car.hyundai.values import CAR as HYUNDAI
+from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
+from openpilot.selfdrive.car.volkswagen.values import CAR as VW
FW_VERSIONS = get_interface_attr('FW_VERSIONS', combine_brands=True, ignore_none=True)
_FINGERPRINTS = get_interface_attr('FINGERPRINTS', combine_brands=True, ignore_none=True)
@@ -44,3 +48,73 @@ def all_known_cars():
def all_legacy_fingerprint_cars():
"""Returns a list of all known car strings, FPv1 only."""
return list(_FINGERPRINTS.keys())
+
+
+# A dict that maps old platform strings to their latest representations
+MIGRATION = {
+ "ACURA ILX 2016 ACURAWATCH PLUS": HONDA.ACURA_ILX,
+ "ACURA RDX 2018 ACURAWATCH PLUS": HONDA.ACURA_RDX,
+ "ACURA RDX 2020 TECH": HONDA.ACURA_RDX_3G,
+ "AUDI A3": VW.AUDI_A3_MK3,
+ "HONDA ACCORD 2018 HYBRID TOURING": HONDA.ACCORD,
+ "HONDA ACCORD 1.5T 2018": HONDA.ACCORD,
+ "HONDA ACCORD 2018 LX 1.5T": HONDA.ACCORD,
+ "HONDA ACCORD 2018 SPORT 2T": HONDA.ACCORD,
+ "HONDA ACCORD 2T 2018": HONDA.ACCORD,
+ "HONDA ACCORD HYBRID 2018": HONDA.ACCORD,
+ "HONDA CIVIC 2016 TOURING": HONDA.CIVIC,
+ "HONDA CIVIC HATCHBACK 2017 SEDAN/COUPE 2019": HONDA.CIVIC_BOSCH,
+ "HONDA CIVIC SEDAN 1.6 DIESEL": HONDA.CIVIC_BOSCH_DIESEL,
+ "HONDA CR-V 2016 EXECUTIVE": HONDA.CRV_EU,
+ "HONDA CR-V 2016 TOURING": HONDA.CRV,
+ "HONDA CR-V 2017 EX": HONDA.CRV_5G,
+ "HONDA CR-V 2019 HYBRID": HONDA.CRV_HYBRID,
+ "HONDA FIT 2018 EX": HONDA.FIT,
+ "HONDA HRV 2019 TOURING": HONDA.HRV,
+ "HONDA INSIGHT 2019 TOURING": HONDA.INSIGHT,
+ "HONDA ODYSSEY 2018 EX-L": HONDA.ODYSSEY,
+ "HONDA ODYSSEY 2019 EXCLUSIVE CHN": HONDA.ODYSSEY_CHN,
+ "HONDA PILOT 2017 TOURING": HONDA.PILOT,
+ "HONDA PILOT 2019 ELITE": HONDA.PILOT,
+ "HONDA PILOT 2019": HONDA.PILOT,
+ "HONDA PASSPORT 2021": HONDA.PILOT,
+ "HONDA RIDGELINE 2017 BLACK EDITION": HONDA.RIDGELINE,
+ "HYUNDAI ELANTRA LIMITED ULTIMATE 2017": HYUNDAI.ELANTRA,
+ "HYUNDAI SANTA FE LIMITED 2019": HYUNDAI.SANTA_FE,
+ "HYUNDAI TUCSON DIESEL 2019": HYUNDAI.TUCSON,
+ "KIA OPTIMA 2016": HYUNDAI.KIA_OPTIMA_G4,
+ "KIA OPTIMA 2019": HYUNDAI.KIA_OPTIMA_G4_FL,
+ "KIA OPTIMA SX 2019 & 2016": HYUNDAI.KIA_OPTIMA_G4_FL,
+ "LEXUS CT 200H 2018": TOYOTA.LEXUS_CTH,
+ "LEXUS ES 300H 2018": TOYOTA.LEXUS_ES,
+ "LEXUS ES 300H 2019": TOYOTA.LEXUS_ES_TSS2,
+ "LEXUS IS300 2018": TOYOTA.LEXUS_IS,
+ "LEXUS NX300 2018": TOYOTA.LEXUS_NX,
+ "LEXUS NX300H 2018": TOYOTA.LEXUS_NX,
+ "LEXUS RX 350 2016": TOYOTA.LEXUS_RX,
+ "LEXUS RX350 2020": TOYOTA.LEXUS_RX_TSS2,
+ "LEXUS RX450 HYBRID 2020": TOYOTA.LEXUS_RX_TSS2,
+ "TOYOTA SIENNA XLE 2018": TOYOTA.SIENNA,
+ "TOYOTA C-HR HYBRID 2018": TOYOTA.CHR,
+ "TOYOTA COROLLA HYBRID TSS2 2019": TOYOTA.COROLLA_TSS2,
+ "TOYOTA RAV4 HYBRID 2019": TOYOTA.RAV4_TSS2,
+ "LEXUS ES HYBRID 2019": TOYOTA.LEXUS_ES_TSS2,
+ "LEXUS NX HYBRID 2018": TOYOTA.LEXUS_NX,
+ "LEXUS NX HYBRID 2020": TOYOTA.LEXUS_NX_TSS2,
+ "LEXUS RX HYBRID 2020": TOYOTA.LEXUS_RX_TSS2,
+ "TOYOTA ALPHARD HYBRID 2021": TOYOTA.ALPHARD_TSS2,
+ "TOYOTA AVALON HYBRID 2019": TOYOTA.AVALON_2019,
+ "TOYOTA AVALON HYBRID 2022": TOYOTA.AVALON_TSS2,
+ "TOYOTA CAMRY HYBRID 2018": TOYOTA.CAMRY,
+ "TOYOTA CAMRY HYBRID 2021": TOYOTA.CAMRY_TSS2,
+ "TOYOTA C-HR HYBRID 2022": TOYOTA.CHR_TSS2,
+ "TOYOTA HIGHLANDER HYBRID 2020": TOYOTA.HIGHLANDER_TSS2,
+ "TOYOTA RAV4 HYBRID 2022": TOYOTA.RAV4_TSS2_2022,
+ "TOYOTA RAV4 HYBRID 2023": TOYOTA.RAV4_TSS2_2023,
+ "TOYOTA HIGHLANDER HYBRID 2018": TOYOTA.HIGHLANDER,
+ "LEXUS ES HYBRID 2018": TOYOTA.LEXUS_ES,
+ "LEXUS RX HYBRID 2017": TOYOTA.LEXUS_RX,
+ "HYUNDAI TUCSON HYBRID 4TH GEN": HYUNDAI.TUCSON_4TH_GEN,
+ "KIA SPORTAGE HYBRID 5TH GEN": HYUNDAI.KIA_SPORTAGE_5TH_GEN,
+ "KIA SORENTO PLUG-IN HYBRID 4TH GEN": HYUNDAI.KIA_SORENTO_HEV_4TH_GEN,
+}
diff --git a/selfdrive/car/ford/carcontroller.py b/selfdrive/car/ford/carcontroller.py
index 7ce2ded6e3..47082fb56f 100644
--- a/selfdrive/car/ford/carcontroller.py
+++ b/selfdrive/car/ford/carcontroller.py
@@ -35,6 +35,7 @@ class CarController(CarControllerBase):
self.main_on_last = False
self.lkas_enabled_last = False
self.steer_alert_last = False
+ self.lead_distance_bars_last = None
def update(self, CC, CS, now_nanos):
can_sends = []
@@ -98,15 +99,19 @@ class CarController(CarControllerBase):
# send lkas ui msg at 1Hz or if ui state changes
if (self.frame % CarControllerParams.LKAS_UI_STEP) == 0 or send_ui:
can_sends.append(fordcan.create_lkas_ui_msg(self.packer, self.CAN, main_on, CC.latActive, steer_alert, hud_control, CS.lkas_status_stock_values))
+
# send acc ui msg at 5Hz or if ui state changes
+ if hud_control.leadDistanceBars != self.lead_distance_bars_last:
+ send_ui = True
if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui:
can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive,
- fcw_alert, CS.out.cruiseState.standstill, hud_control,
- CS.acc_tja_status_stock_values))
+ fcw_alert, CS.out.cruiseState.standstill, hud_control,
+ CS.acc_tja_status_stock_values))
self.main_on_last = main_on
self.lkas_enabled_last = CC.latActive
self.steer_alert_last = steer_alert
+ self.lead_distance_bars_last = hud_control.leadDistanceBars
new_actuators = actuators.copy()
new_actuators.curvature = self.apply_curvature_last
diff --git a/selfdrive/car/ford/fingerprints.py b/selfdrive/car/ford/fingerprints.py
index 504d27e681..fae529aa00 100644
--- a/selfdrive/car/ford/fingerprints.py
+++ b/selfdrive/car/ford/fingerprints.py
@@ -85,6 +85,7 @@ FW_VERSIONS = {
b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdCamera, 0x706, None): [
+ b'ML3T-14H102-ABR\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PJ6T-14H102-ABJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
@@ -136,6 +137,7 @@ FW_VERSIONS = {
b'NZ6C-2D053-AG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PZ6C-2D053-ED\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PZ6C-2D053-EE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
+ b'PZ6C-2D053-EF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
],
(Ecu.fwdRadar, 0x764, None): [
b'NZ6T-14D049-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
diff --git a/selfdrive/car/ford/fordcan.py b/selfdrive/car/ford/fordcan.py
index c5ef0900f3..939084c4a0 100644
--- a/selfdrive/car/ford/fordcan.py
+++ b/selfdrive/car/ford/fordcan.py
@@ -212,7 +212,7 @@ def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw
"AccFllwMde_B_Dsply": 1 if hud_control.leadVisible else 0, # Lead indicator
"AccStopMde_B_Dsply": 1 if standstill else 0,
"AccWarn_D_Dsply": 0, # ACC warning
- "AccTGap_D_Dsply": 4, # Fixed time gap in UI
+ "AccTGap_D_Dsply": hud_control.leadDistanceBars + 1, # Time gap
})
# Forwards FCW alert from IPMA
diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py
index 15c0d3bdb7..09c02d53a6 100644
--- a/selfdrive/car/ford/values.py
+++ b/selfdrive/car/ford/values.py
@@ -114,8 +114,8 @@ class CAR(Platforms):
F_150_MK14 = FordCANFDPlatformConfig(
"FORD F-150 14TH GEN",
[
- FordCarInfo("Ford F-150 2023", "Co-Pilot360 Active 2.0"),
- FordCarInfo("Ford F-150 Hybrid 2023", "Co-Pilot360 Active 2.0"),
+ FordCarInfo("Ford F-150 2022-23", "Co-Pilot360 Active 2.0"),
+ FordCarInfo("Ford F-150 Hybrid 2022-23", "Co-Pilot360 Active 2.0"),
],
CarSpecs(mass=2000, wheelbase=3.69, steerRatio=17.0),
)
@@ -137,8 +137,8 @@ class CAR(Platforms):
[
FordCarInfo("Ford Maverick 2022", "LARIAT Luxury"),
FordCarInfo("Ford Maverick Hybrid 2022", "LARIAT Luxury"),
- FordCarInfo("Ford Maverick 2023", "Co-Pilot360 Assist"),
- FordCarInfo("Ford Maverick Hybrid 2023", "Co-Pilot360 Assist"),
+ FordCarInfo("Ford Maverick 2023-24", "Co-Pilot360 Assist"),
+ FordCarInfo("Ford Maverick Hybrid 2023-24", "Co-Pilot360 Assist"),
],
CarSpecs(mass=1650, wheelbase=3.076, steerRatio=17.0),
)
diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py
index 547abcd9b9..00cc54dcb3 100644
--- a/selfdrive/car/honda/carcontroller.py
+++ b/selfdrive/car/honda/carcontroller.py
@@ -96,7 +96,7 @@ def process_hud_alert(hud_alert):
HUDData = namedtuple("HUDData",
["pcm_accel", "v_cruise", "lead_visible",
- "lanes_visible", "fcw", "acc_alert", "steer_required"])
+ "lanes_visible", "fcw", "acc_alert", "steer_required", "lead_distance_bars"])
def rate_limit_steer(new_steer, last_steer):
@@ -251,7 +251,7 @@ class CarController(CarControllerBase):
# Send dashboard UI commands.
if self.frame % 10 == 0:
hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_control.leadVisible,
- hud_control.lanesVisible, fcw_display, acc_alert, steer_required)
+ hud_control.lanesVisible, fcw_display, acc_alert, steer_required, hud_control.leadDistanceBars)
can_sends.extend(hondacan.create_ui_commands(self.packer, self.CAN, self.CP, CC.enabled, pcm_speed, hud, CS.is_metric, CS.acc_hud, CS.lkas_hud))
if self.CP.openpilotLongitudinalControl and self.CP.carFingerprint not in HONDA_BOSCH:
diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py
index 7784581e1c..d429da33fb 100644
--- a/selfdrive/car/honda/carstate.py
+++ b/selfdrive/car/honda/carstate.py
@@ -204,6 +204,10 @@ class CarState(CarStateBase):
ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD.get(self.CP.carFingerprint, 1200)
if self.CP.carFingerprint in HONDA_BOSCH:
+ # The PCM always manages its own cruise control state, but doesn't publish it
+ if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS:
+ ret.cruiseState.nonAdaptive = cp_cam.vl["ACC_HUD"]["CRUISE_CONTROL_LABEL"] != 0
+
if not self.CP.openpilotLongitudinalControl:
# ACC_HUD is on camera bus on radarless cars
acc_hud = cp_cam.vl["ACC_HUD"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else cp.vl["ACC_HUD"]
@@ -276,9 +280,10 @@ class CarState(CarStateBase):
]
if CP.carFingerprint in HONDA_BOSCH_RADARLESS:
- messages.append(("LKAS_HUD", 10))
- if not CP.openpilotLongitudinalControl:
- messages.append(("ACC_HUD", 10))
+ messages += [
+ ("ACC_HUD", 10),
+ ("LKAS_HUD", 10),
+ ]
elif CP.carFingerprint not in HONDA_BOSCH:
messages += [
diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py
index d10d5576d9..efa5ba1f1e 100644
--- a/selfdrive/car/honda/hondacan.py
+++ b/selfdrive/car/honda/hondacan.py
@@ -143,7 +143,7 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_
acc_hud_values = {
'CRUISE_SPEED': hud.v_cruise,
'ENABLE_MINI_CAR': 1 if enabled else 0,
- 'HUD_DISTANCE': 0, # max distance setting on display
+ 'HUD_DISTANCE': (hud.lead_distance_bars + 1) % 4, # wraps to 0 at 4 bars
'IMPERIAL_UNIT': int(not is_metric),
'HUD_LEAD': 2 if enabled and hud.lead_visible else 1 if enabled else 0,
'SET_ME_X01_2': 1,
diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py
index f791d4b639..d316626a94 100755
--- a/selfdrive/car/honda/interface.py
+++ b/selfdrive/car/honda/interface.py
@@ -4,8 +4,8 @@ from panda import Panda
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import interp
from openpilot.selfdrive.car.honda.hondacan import CanBus
-from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, \
- HONDA_BOSCH_RADARLESS
+from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, CruiseSettings, HondaFlags, CAR, HONDA_BOSCH, \
+ HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS
from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.disable_ecu import disable_ecu
@@ -16,6 +16,7 @@ EventName = car.CarEvent.EventName
TransmissionType = car.CarParams.TransmissionType
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
+SETTINGS_BUTTONS_DICT = {CruiseSettings.DISTANCE: ButtonType.gapAdjustCruise, CruiseSettings.LKAS: ButtonType.altButton1}
class CarInterface(CarInterfaceBase):
@@ -236,7 +237,7 @@ class CarInterface(CarInterfaceBase):
ret.buttonEvents = [
*create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT),
- *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1}),
+ *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT),
]
# events
diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py
index 4960380bbc..eed76c42ab 100644
--- a/selfdrive/car/honda/values.py
+++ b/selfdrive/car/honda/values.py
@@ -68,6 +68,11 @@ class CruiseButtons:
MAIN = 1
+class CruiseSettings:
+ DISTANCE = 3
+ LKAS = 1
+
+
# See dbc files for info on values
VISUAL_HUD = {
VisualAlert.none: 0,
diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py
index ee7f441227..7829d764b0 100644
--- a/selfdrive/car/hyundai/carcontroller.py
+++ b/selfdrive/car/hyundai/carcontroller.py
@@ -129,7 +129,7 @@ class CarController(CarControllerBase):
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override,
- set_speed_in_units))
+ set_speed_in_units, hud_control))
self.accel_last = accel
else:
# button presses
@@ -148,7 +148,7 @@ class CarController(CarControllerBase):
jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0
use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value
can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2),
- hud_control.leadVisible, set_speed_in_units, stopping,
+ hud_control, set_speed_in_units, stopping,
CC.cruiseControl.override, use_fca))
# 20 Hz LFA MFA message
diff --git a/selfdrive/car/hyundai/fingerprints.py b/selfdrive/car/hyundai/fingerprints.py
index 6349318fbf..12303f806a 100644
--- a/selfdrive/car/hyundai/fingerprints.py
+++ b/selfdrive/car/hyundai/fingerprints.py
@@ -535,25 +535,31 @@ FW_VERSIONS = {
CAR.SANTA_FE_HEV_2022: {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ',
+ b'\xf1\x00TMhe SCC FHCUP 1.00 1.01 99110-CL500 ',
],
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLAC0 4TSHC102',
b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLEC0 4TSHC102',
b'\xf1\x00TM MDPS C 1.00 1.02 56310-GA000 4TSHA100',
b'\xf1\x00TM MDPS R 1.00 1.05 57700-CL000 4TSHP105',
+ b'\xf1\x00TM MDPS R 1.00 1.06 57700-CL000 4TSHP106',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00TMA MFC AT USA LHD 1.00 1.03 99211-S2500 220414',
b'\xf1\x00TMH MFC AT EUR LHD 1.00 1.06 99211-S1500 220727',
+ b'\xf1\x00TMH MFC AT KOR LHD 1.00 1.06 99211-S1500 220727',
b'\xf1\x00TMH MFC AT USA LHD 1.00 1.03 99211-S1500 210224',
+ b'\xf1\x00TMH MFC AT USA LHD 1.00 1.05 99211-S1500 220126',
b'\xf1\x00TMH MFC AT USA LHD 1.00 1.06 99211-S1500 220727',
],
(Ecu.transmission, 0x7e1, None): [
+ b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16KA1\xc6\x15Q\x1e',
b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16SA3\xa3\x1b\xe14',
b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16UA3I\x94\xac\x8f',
b'\xf1\x87959102T250\x00\x00\x00\x00\x00\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E14\x00\x00\x00\x00\x00\x00\x00TTM2H16SA2\x80\xd7l\xb2',
],
(Ecu.engine, 0x7e0, None): [
+ b'\xf1\x87391312MTA0',
b'\xf1\x87391312MTC1',
b'\xf1\x87391312MTE0',
b'\xf1\x87391312MTL0',
@@ -561,6 +567,7 @@ FW_VERSIONS = {
},
CAR.SANTA_FE_PHEV_2022: {
(Ecu.fwdRadar, 0x7d0, None): [
+ b'\xf1\x00TMhe SCC F-CUP 1.00 1.00 99110-CL500 ',
b'\xf1\x00TMhe SCC FHCUP 1.00 1.01 99110-CL500 ',
b'\xf1\x8799110CL500\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ',
],
@@ -574,6 +581,7 @@ FW_VERSIONS = {
b'\xf1\x00TMP MFC AT USA LHD 1.00 1.06 99211-S1500 220727',
],
(Ecu.transmission, 0x7e1, None): [
+ b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA0o\x88^\xbe',
b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea',
b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA0o\x88^\xbe',
b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea',
@@ -836,10 +844,12 @@ FW_VERSIONS = {
b'\xf1\x00IK MDPS R 1.00 1.07 57700-G9420 4I4VL107',
b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9200 4I2CL108',
b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9420 4I4VL108',
+ b'\xf1\x00IK MDPS R 1.00 5.09 57700-G9520 4I4VL509',
],
(Ecu.transmission, 0x7e1, None): [
b'\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL',
b'\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T20KB3Wuvz',
+ b'\xf1\x00bcsh8p54 E31\x00\x00\x00\x00\x00\x00\x00SIK0T33NH0\x0f\xa3Y*',
b'\xf1\x87VCJLP18407832DN3\x88vXfvUVT\x97eFU\x87d7v\x88eVeveFU\x89\x98\x7f\xff\xb2\xb0\xf1\x81E25\x00\x00\x00',
b'\xf1\x87VDJLC18480772DK9\x88eHfwfff\x87eFUeDEU\x98eFe\x86T5DVyo\xff\x87s\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33KB5\x9f\xa5&\x81',
b'\xf1\x87VDKLT18912362DN4wfVfwefeveVUwfvw\x88vWfvUFU\x89\xa9\x8f\xff\x87w\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL',
@@ -847,16 +857,19 @@ FW_VERSIONS = {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 ',
b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 \xf1\xa01.02',
+ b'\xf1\x00IK__ SCC FHCUP 1.00 1.00 99110-G9300 ',
b'\xf1\x00IK__ SCC FHCUP 1.00 1.02 96400-G9000 ',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00IK MFC AT KOR LHD 1.00 1.01 95740-G9000 170920',
b'\xf1\x00IK MFC AT USA LHD 1.00 1.01 95740-G9000 170920',
+ b'\xf1\x00IK MFC AT USA LHD 1.00 1.04 99211-G9000 220401',
],
(Ecu.engine, 0x7e0, None): [
b'\xf1\x81606G2051\x00\x00\x00\x00\x00\x00\x00\x00',
b'\xf1\x81640H0051\x00\x00\x00\x00\x00\x00\x00\x00',
b'\xf1\x81640J0051\x00\x00\x00\x00\x00\x00\x00\x00',
+ b'\xf1\x81640N2051\x00\x00\x00\x00\x00\x00\x00\x00',
],
},
CAR.GENESIS_G80: {
diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py
index 0bf29664e8..7cbeed0afb 100644
--- a/selfdrive/car/hyundai/hyundaican.py
+++ b/selfdrive/car/hyundai/hyundaican.py
@@ -126,12 +126,12 @@ def create_lfahda_mfc(packer, enabled, hda_set_speed=0):
}
return packer.make_can_msg("LFAHDA_MFC", 0, values)
-def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, set_speed, stopping, long_override, use_fca):
+def create_acc_commands(packer, enabled, accel, upper_jerk, idx, hud_control, set_speed, stopping, long_override, use_fca):
commands = []
scc11_values = {
"MainMode_ACC": 1,
- "TauGapSet": 4,
+ "TauGapSet": hud_control.leadDistanceBars + 1,
"VSetDis": set_speed if enabled else 0,
"AliveCounterACC": idx % 0x10,
"ObjValid": 1, # close lead makes controls tighter
@@ -167,7 +167,7 @@ def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, s
"JerkUpperLimit": upper_jerk, # stock usually is 1.0 but sometimes uses higher values
"JerkLowerLimit": 5.0, # stock usually is 0.5 but sometimes uses higher values
"ACCMode": 2 if enabled and long_override else 1 if enabled else 4, # stock will always be 4 instead of 0 after first disengage
- "ObjGap": 2 if lead_visible else 0, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead
+ "ObjGap": 2 if hud_control.leadVisible else 0, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead
}
commands.append(packer.make_can_msg("SCC14", 0, scc14_values))
diff --git a/selfdrive/car/hyundai/hyundaicanfd.py b/selfdrive/car/hyundai/hyundaicanfd.py
index a35fcb7779..17ec9dcdd2 100644
--- a/selfdrive/car/hyundai/hyundaicanfd.py
+++ b/selfdrive/car/hyundai/hyundaicanfd.py
@@ -121,7 +121,7 @@ def create_lfahda_cluster(packer, CAN, enabled):
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
-def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed):
+def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control):
jerk = 5
jn = jerk / 50
if not enabled or gas_override:
@@ -146,7 +146,7 @@ def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_ov
"SET_ME_2": 0x4,
"SET_ME_3": 0x3,
"SET_ME_TMP_64": 0x64,
- "DISTANCE_SETTING": 4,
+ "DISTANCE_SETTING": hud_control.leadDistanceBars + 1,
}
return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values)
diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py
index e79da0f473..79cec1f787 100644
--- a/selfdrive/car/hyundai/values.py
+++ b/selfdrive/car/hyundai/values.py
@@ -569,7 +569,7 @@ class CAR(Platforms):
)
GENESIS_G70_2020 = HyundaiPlatformConfig(
"GENESIS G70 2020",
- HyundaiCarInfo("Genesis G70 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ HyundaiCarInfo("Genesis G70 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
CarSpecs(mass=3673 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=12.9),
flags=HyundaiFlags.MANDO_RADAR,
)
diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py
index 37a67ecd93..83b238fb68 100644
--- a/selfdrive/car/mazda/carstate.py
+++ b/selfdrive/car/mazda/carstate.py
@@ -18,9 +18,16 @@ class CarState(CarStateBase):
self.lkas_allowed_speed = False
self.lkas_disabled = False
+ self.prev_distance_button = 0
+ self.distance_button = 0
+
def update(self, cp, cp_cam):
ret = car.CarState.new_message()
+
+ self.prev_distance_button = self.distance_button
+ self.distance_button = cp.vl["CRZ_BTNS"]["DISTANCE_LESS"]
+
ret.wheelSpeeds = self.get_wheel_speeds(
cp.vl["WHEEL_SPEEDS"]["FL"],
cp.vl["WHEEL_SPEEDS"]["FR"],
diff --git a/selfdrive/car/mazda/fingerprints.py b/selfdrive/car/mazda/fingerprints.py
index 292f407935..8143ad71af 100644
--- a/selfdrive/car/mazda/fingerprints.py
+++ b/selfdrive/car/mazda/fingerprints.py
@@ -10,6 +10,7 @@ FW_VERSIONS = {
],
(Ecu.engine, 0x7e0, None): [
b'PEW5-188K2-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
+ b'PW67-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2H-188K2-J\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
@@ -31,6 +32,7 @@ FW_VERSIONS = {
],
(Ecu.transmission, 0x7e1, None): [
b'PG69-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
+ b'PW66-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PXDL-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PXFG-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PXFG-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py
index 85be0166ce..12d156fee8 100755
--- a/selfdrive/car/mazda/interface.py
+++ b/selfdrive/car/mazda/interface.py
@@ -2,7 +2,7 @@
from cereal import car
from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS
-from openpilot.selfdrive.car import get_safety_config
+from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = car.CarState.ButtonEvent.Type
@@ -34,6 +34,9 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_cam)
+ # TODO: add button types for inc and dec
+ ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
+
# events
events = self.create_common_events(ret)
diff --git a/selfdrive/car/nissan/carstate.py b/selfdrive/car/nissan/carstate.py
index b2ba9ce290..694d6c3bb0 100644
--- a/selfdrive/car/nissan/carstate.py
+++ b/selfdrive/car/nissan/carstate.py
@@ -20,9 +20,15 @@ class CarState(CarStateBase):
self.steeringTorqueSamples = deque(TORQUE_SAMPLES*[0], TORQUE_SAMPLES)
self.shifter_values = can_define.dv["GEARBOX"]["GEAR_SHIFTER"]
+ self.prev_distance_button = 0
+ self.distance_button = 0
+
def update(self, cp, cp_adas, cp_cam):
ret = car.CarState.new_message()
+ self.prev_distance_button = self.distance_button
+ self.distance_button = cp.vl["CRUISE_THROTTLE"]["FOLLOW_DISTANCE_BUTTON"]
+
if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA):
ret.gas = cp.vl["GAS_PEDAL"]["GAS_PEDAL"]
elif self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC):
diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py
index 60cc3a0090..3e82b5192e 100644
--- a/selfdrive/car/nissan/interface.py
+++ b/selfdrive/car/nissan/interface.py
@@ -1,9 +1,11 @@
from cereal import car
from panda import Panda
-from openpilot.selfdrive.car import get_safety_config
+from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.nissan.values import CAR
+ButtonType = car.CarState.ButtonEvent.Type
+
class CarInterface(CarInterfaceBase):
@@ -30,6 +32,8 @@ class CarInterface(CarInterfaceBase):
def _update(self, c):
ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam)
+ ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
+
events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.brake])
if self.CS.lkas_enabled:
diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py
index 1b1858703d..cfba43b4da 100644
--- a/selfdrive/car/volkswagen/carcontroller.py
+++ b/selfdrive/car/volkswagen/carcontroller.py
@@ -102,7 +102,7 @@ class CarController(CarControllerBase):
# FIXME: follow the recent displayed-speed updates, also use mph_kmh toggle to fix display rounding problem?
set_speed = hud_control.setSpeed * CV.MS_TO_KPH
can_sends.append(self.CCS.create_acc_hud_control(self.packer_pt, CANBUS.pt, acc_hud_status, set_speed,
- lead_distance))
+ lead_distance, hud_control.leadDistanceBars))
# **** Stock ACC Button Controls **************************************** #
diff --git a/selfdrive/car/volkswagen/fingerprints.py b/selfdrive/car/volkswagen/fingerprints.py
index f6b3c49982..c530288027 100644
--- a/selfdrive/car/volkswagen/fingerprints.py
+++ b/selfdrive/car/volkswagen/fingerprints.py
@@ -381,6 +381,7 @@ FW_VERSIONS = {
b'\xf1\x8704L906026FP\xf1\x892012',
b'\xf1\x8704L906026GA\xf1\x892013',
b'\xf1\x8704L906026KD\xf1\x894798',
+ b'\xf1\x8705L906022A \xf1\x890827',
b'\xf1\x873G0906259 \xf1\x890004',
b'\xf1\x873G0906259B \xf1\x890002',
b'\xf1\x873G0906264 \xf1\x890004',
@@ -400,6 +401,7 @@ FW_VERSIONS = {
b'\xf1\x870DL300011H \xf1\x895201',
b'\xf1\x870GC300042H \xf1\x891404',
b'\xf1\x870GC300043 \xf1\x892301',
+ b'\xf1\x870GC300046P \xf1\x892805',
],
(Ecu.srs, 0x715, None): [
b'\xf1\x873Q0959655AE\xf1\x890195\xf1\x82\r56140056130012416612124111',
@@ -415,6 +417,7 @@ FW_VERSIONS = {
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e5915005914001354701311542900',
b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e5915005914001305701311052900',
b'\xf1\x875Q0959655S \xf1\x890870\xf1\x82\x1315120011111200631145171716121691132111',
+ b'\xf1\x875QF959655S \xf1\x890639\xf1\x82\x13131100131300111111000120----2211114A48',
],
(Ecu.eps, 0x712, None): [
b'\xf1\x873Q0909144J \xf1\x895063\xf1\x82\x0566B00611A1',
@@ -633,14 +636,17 @@ FW_VERSIONS = {
},
CAR.TOURAN_MK2: {
(Ecu.engine, 0x7e0, None): [
+ b'\xf1\x8704E906027HQ\xf1\x893746',
b'\xf1\x8704L906026HM\xf1\x893017',
b'\xf1\x8705E906018CQ\xf1\x890808',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x870CW300041E \xf1\x891005',
+ b'\xf1\x870CW300041Q \xf1\x891606',
b'\xf1\x870CW300051M \xf1\x891926',
],
(Ecu.srs, 0x715, None): [
+ b'\xf1\x875Q0959655AS\xf1\x890318\xf1\x82\x1336350021353335314132014730479333313100',
b'\xf1\x875Q0959655AS\xf1\x890318\xf1\x82\x13363500213533353141324C4732479333313100',
b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1336350021353336314740025250529333613100',
],
@@ -651,6 +657,7 @@ FW_VERSIONS = {
(Ecu.fwdRadar, 0x757, None): [
b'\xf1\x872Q0907572AA\xf1\x890396',
b'\xf1\x873Q0907572C \xf1\x890195',
+ b'\xf1\x875Q0907572R \xf1\x890771',
],
},
CAR.TRANSPORTER_T61: {
@@ -990,7 +997,9 @@ FW_VERSIONS = {
b'\xf1\x8704L906026HT\xf1\x893617',
b'\xf1\x8705E906018DJ\xf1\x890915',
b'\xf1\x8705E906018DJ\xf1\x891903',
+ b'\xf1\x8705L906022GM\xf1\x893411',
b'\xf1\x875NA906259E \xf1\x890003',
+ b'\xf1\x875NA907115D \xf1\x890003',
b'\xf1\x875NA907115E \xf1\x890003',
b'\xf1\x875NA907115E \xf1\x890005',
b'\xf1\x8783A907115E \xf1\x890001',
@@ -999,14 +1008,17 @@ FW_VERSIONS = {
b'\xf1\x870D9300014S \xf1\x895201',
b'\xf1\x870D9300043 \xf1\x895202',
b'\xf1\x870DL300011N \xf1\x892014',
+ b'\xf1\x870DL300012G \xf1\x892006',
b'\xf1\x870DL300012M \xf1\x892107',
b'\xf1\x870DL300012N \xf1\x892110',
b'\xf1\x870DL300013G \xf1\x892119',
b'\xf1\x870GC300014N \xf1\x892801',
+ b'\xf1\x870GC300018S \xf1\x892803',
b'\xf1\x870GC300019H \xf1\x892806',
b'\xf1\x870GC300046Q \xf1\x892802',
],
(Ecu.srs, 0x715, None): [
+ b'\xf1\x873Q0959655AN\xf1\x890306\xf1\x82\r11110011110011031111310311',
b'\xf1\x873Q0959655AP\xf1\x890306\xf1\x82\r11110011110011421111314211',
b'\xf1\x873Q0959655BH\xf1\x890703\xf1\x82\x0e1213001211001205212111052100',
b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100',
@@ -1015,6 +1027,7 @@ FW_VERSIONS = {
b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111',
b'\xf1\x873Q0959655DJ\xf1\x890731\xf1\x82\x0e1513001511001205232113052J00',
b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100010200--1121240749',
+ b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100010200--1121246149',
],
(Ecu.eps, 0x712, None): [
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6050405',
@@ -1022,6 +1035,7 @@ FW_VERSIONS = {
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6070405',
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G500',
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G600',
+ b'\xf1\x875TA907145F \xf1\x891063\xf1\x82\x0025T6BA25OM',
b'\xf1\x875TA907145F \xf1\x891063\xf1\x82\x002LT61A2LOM',
],
(Ecu.fwdRadar, 0x757, None): [
diff --git a/selfdrive/car/volkswagen/mqbcan.py b/selfdrive/car/volkswagen/mqbcan.py
index 787c7de530..6043533acf 100644
--- a/selfdrive/car/volkswagen/mqbcan.py
+++ b/selfdrive/car/volkswagen/mqbcan.py
@@ -125,11 +125,11 @@ def create_acc_accel_control(packer, bus, acc_type, acc_enabled, accel, acc_cont
return commands
-def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance):
+def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance, distance):
values = {
"ACC_Status_Anzeige": acc_hud_status,
"ACC_Wunschgeschw_02": set_speed if set_speed < 250 else 327.36,
- "ACC_Gesetzte_Zeitluecke": 3,
+ "ACC_Gesetzte_Zeitluecke": distance + 2,
"ACC_Display_Prio": 3,
"ACC_Abstandsindex": lead_distance,
}
diff --git a/selfdrive/car/volkswagen/pqcan.py b/selfdrive/car/volkswagen/pqcan.py
index f42c3cf781..307aaaa2a7 100644
--- a/selfdrive/car/volkswagen/pqcan.py
+++ b/selfdrive/car/volkswagen/pqcan.py
@@ -91,10 +91,10 @@ def create_acc_accel_control(packer, bus, acc_type, acc_enabled, accel, acc_cont
return commands
-def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance):
+def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance, distance):
values = {
"ACA_StaACC": acc_hud_status,
- "ACA_Zeitluecke": 2,
+ "ACA_Zeitluecke": distance + 2,
"ACA_V_Wunsch": set_speed,
"ACA_gemZeitl": lead_distance,
"ACA_PrioDisp": 3,
diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py
index cc6fc2ae17..3c5733520e 100755
--- a/selfdrive/debug/test_fw_query_on_routes.py
+++ b/selfdrive/debug/test_fw_query_on_routes.py
@@ -9,6 +9,7 @@ from tqdm import tqdm
from openpilot.tools.lib.logreader import LogReader, ReadMode
from openpilot.tools.lib.route import SegmentRange
from openpilot.selfdrive.car.car_helpers import interface_names
+from openpilot.selfdrive.car.fingerprints import MIGRATION
from openpilot.selfdrive.car.fw_versions import VERSIONS, match_fw_to_car
@@ -17,11 +18,6 @@ SUPPORTED_BRANDS = VERSIONS.keys()
SUPPORTED_CARS = [brand for brand in SUPPORTED_BRANDS for brand in interface_names[brand]]
UNKNOWN_BRAND = "unknown"
-try:
- from xx.pipeline.lib.fingerprint import MIGRATION
-except ImportError:
- MIGRATION = {}
-
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Run FW fingerprint on Qlog of route or list of routes')
parser.add_argument('route', help='Route or file with list of routes')
diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py
index 4f292917fd..8b616b7874 100644
--- a/selfdrive/manager/process_config.py
+++ b/selfdrive/manager/process_config.py
@@ -69,11 +69,12 @@ procs = [
PythonProcess("deleter", "system.loggerd.deleter", always_run),
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)),
PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI),
+ #PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI),
PythonProcess("navd", "selfdrive.navd.navd", only_onroad),
PythonProcess("pandad", "selfdrive.boardd.pandad", always_run),
PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI),
- PythonProcess("pigeond", "system.sensord.pigeond", ublox, enabled=TICI),
+ PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI),
PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad),
PythonProcess("radard", "selfdrive.controls.radard", only_onroad),
PythonProcess("thermald", "selfdrive.thermald.thermald", always_run),
diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit
index 0eedc6257b..91e32036b5 100644
--- a/selfdrive/test/process_replay/ref_commit
+++ b/selfdrive/test/process_replay/ref_commit
@@ -1 +1 @@
-fba62008efd13fb578de325f0cdb0a87fe5e28f0
\ No newline at end of file
+4f02bcfbf45697c5e6ba0a032797f6b2f37e16d3
diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py
index 4be9b8a430..250534bf86 100755
--- a/selfdrive/test/test_onroad.py
+++ b/selfdrive/test/test_onroad.py
@@ -65,7 +65,7 @@ PROCS.update({
"tici": {
"./boardd": 4.0,
"./ubloxd": 0.02,
- "system.sensord.pigeond": 6.0,
+ "system.ubloxd.pigeond": 6.0,
},
"tizi": {
"./boardd": 19.0,
diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc
index 7b1f2f1d24..7818da8669 100644
--- a/selfdrive/ui/qt/widgets/cameraview.cc
+++ b/selfdrive/ui/qt/widgets/cameraview.cc
@@ -41,6 +41,8 @@ const char frame_fragment_shader[] =
"out vec4 colorOut;\n"
"void main() {\n"
" colorOut = texture(uTexture, vTexCoord);\n"
+ // gamma to improve worst case visibility when dark
+ " colorOut.rgb = pow(colorOut.rgb, vec3(1.0/1.28));\n"
"}\n";
#else
#ifdef __APPLE__
diff --git a/system/qcomgpsd/cgpsd.py b/system/qcomgpsd/cgpsd.py
deleted file mode 100755
index 54d3c623f3..0000000000
--- a/system/qcomgpsd/cgpsd.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python3
-import time
-import datetime
-from collections import defaultdict
-
-from cereal import log
-import cereal.messaging as messaging
-from openpilot.common.swaglog import cloudlog
-from openpilot.system.qcomgpsd.qcomgpsd import at_cmd, wait_for_modem
-
-# https://campar.in.tum.de/twiki/pub/Chair/NaviGpsDemon/nmea.html#RMC
-"""
-AT+CGPSGPOS=1
-response: '$GNGGA,220212.00,3245.09188,N,11711.76362,W,1,06,24.54,0.0,M,,M,,*77'
-
-AT+CGPSGPOS=2
-response: '$GNGSA,A,3,06,17,19,22,,,,,,,,,14.11,8.95,10.91,1*01
-$GNGSA,A,3,29,26,,,,,,,,,,,14.11,8.95,10.91,4*03'
-
-AT+CGPSGPOS=3
-response: '$GPGSV,3,1,11,06,55,047,22,19,29,053,20,22,19,115,14,05,01,177,,0*68
-$GPGSV,3,2,11,11,77,156,23,12,47,322,17,17,08,066,10,20,25,151,,0*6D
-$GPGSV,3,3,11,24,44,232,,25,16,312,,29,02,260,,0*5D'
-
-AT+CGPSGPOS=4
-response: '$GBGSV,1,1,03,26,75,242,20,29,19,049,16,35,,,24,0*7D'
-
-AT+CGPSGPOS=5
-response: '$GNRMC,220216.00,A,3245.09531,N,11711.76043,W,,,070324,,,A,V*20'
-"""
-
-
-def sfloat(n: str):
- return float(n) if len(n) > 0 else 0
-
-def checksum(s: str):
- ret = 0
- for c in s[1:-3]:
- ret ^= ord(c)
- return format(ret, '02X')
-
-def main():
- wait_for_modem("AT+CGPS?")
-
- cmds = [
- "AT+GPSPORT=1",
- "AT+CGPS=1",
- ]
- for c in cmds:
- at_cmd(c)
-
- nmea = defaultdict(list)
- pm = messaging.PubMaster(['gpsLocation'])
- while True:
- time.sleep(1)
- try:
- # TODO: read from streaming AT port instead of polling
- out = at_cmd("AT+CGPS?")
-
- if '+CGPS: 1' not in out:
- for c in cmds:
- at_cmd(c)
-
- sentences = out.split("'")[1].splitlines()
- new = {l.split(',')[0]: l.split(',') for l in sentences if l.startswith('$G')}
- nmea.update(new)
- if '$GNRMC' not in new:
- print(f"no GNRMC:\n{out}\n")
- continue
-
- # validate checksums
- for s in nmea.values():
- sent = ','.join(s)
- if checksum(sent) != s[-1].split('*')[1]:
- cloudlog.error(f"invalid checksum: {repr(sent)}")
- continue
-
- gnrmc = nmea['$GNRMC']
- #print(gnrmc)
-
- msg = messaging.new_message('gpsLocation', valid=True)
- gps = msg.gpsLocation
- gps.latitude = (sfloat(gnrmc[3][:2]) + (sfloat(gnrmc[3][2:]) / 60)) * (1 if gnrmc[4] == "N" else -2)
- gps.longitude = (sfloat(gnrmc[5][:3]) + (sfloat(gnrmc[5][3:]) / 60)) * (1 if gnrmc[6] == "E" else -1)
-
- date = gnrmc[9][:6]
- dt = datetime.datetime.strptime(f"{date} {gnrmc[1]}", '%d%m%y %H%M%S.%f')
- gps.unixTimestampMillis = dt.timestamp()*1e3
-
- gps.hasFix = gnrmc[1] == 'A'
-
- gps.source = log.GpsLocationData.SensorSource.unicore
-
- gps.speed = sfloat(gnrmc[7])
- gps.bearingDeg = sfloat(gnrmc[8])
-
- if len(nmea['$GNGGA']):
- gngga = nmea['$GNGGA']
- if gngga[10] == 'M':
- gps.altitude = sfloat(gngga[9])
-
- if len(nmea['$GNGSA']):
- # TODO: this is only for GPS sats
- gngsa = nmea['$GNGSA']
- gps.horizontalAccuracy = sfloat(gngsa[4])
- gps.verticalAccuracy = sfloat(gngsa[5])
-
- # TODO: set these from the module
- gps.bearingAccuracyDeg = 5.
- gps.speedAccuracy = 3.
-
- # TODO: can we get this from the NMEA sentences?
- #gps.vNED = vNED
-
- pm.send('gpsLocation', msg)
-
- except Exception:
- cloudlog.exception("gps.issue")
-
-
-if __name__ == "__main__":
- main()
diff --git a/system/sensord/pigeond.py b/system/ubloxd/pigeond.py
similarity index 100%
rename from system/sensord/pigeond.py
rename to system/ubloxd/pigeond.py
diff --git a/system/sensord/tests/test_pigeond.py b/system/ubloxd/tests/test_pigeond.py
similarity index 100%
rename from system/sensord/tests/test_pigeond.py
rename to system/ubloxd/tests/test_pigeond.py
diff --git a/system/ugpsd.py b/system/ugpsd.py
new file mode 100755
index 0000000000..34b20b01c8
--- /dev/null
+++ b/system/ugpsd.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python3
+import os
+import time
+import traceback
+import serial
+import datetime
+import numpy as np
+from collections import defaultdict
+
+from cereal import log
+import cereal.messaging as messaging
+from openpilot.common.retry import retry
+from openpilot.common.swaglog import cloudlog
+from openpilot.system.qcomgpsd.qcomgpsd import at_cmd, wait_for_modem
+
+
+def sfloat(n: str):
+ return float(n) if len(n) > 0 else 0
+
+def checksum(s: str):
+ ret = 0
+ for c in s[1:-3]:
+ ret ^= ord(c)
+ return format(ret, '02X')
+
+class Unicore:
+ def __init__(self):
+ self.s = serial.Serial('/dev/ttyHS0', 115200)
+ self.s.timeout = 1
+ self.s.writeTimeout = 1
+ self.s.newline = b'\r\n'
+
+ self.s.flush()
+ self.s.reset_input_buffer()
+ self.s.reset_output_buffer()
+ self.s.read(2048)
+
+ def send(self, cmd):
+ self.s.write(cmd.encode('utf8') + b'\r')
+ resp = self.s.read(2048)
+ print(len(resp), cmd, "\n", resp)
+ assert b"OK" in resp
+
+ def recv(self):
+ return self.s.readline()
+
+def build_msg(state):
+ """
+ NMEA sentences:
+ https://campar.in.tum.de/twiki/pub/Chair/NaviGpsDemon/nmea.html#RMC
+ NAV messages:
+ https://www.unicorecomm.com/assets/upload/file/UFirebird_Standard_Positioning_Products_Protocol_Specification_CH.pdf
+ """
+
+ msg = messaging.new_message('gpsLocation', valid=True)
+ gps = msg.gpsLocation
+
+ gnrmc = state['$GNRMC']
+ gps.hasFix = gnrmc[1] == 'A'
+ gps.source = log.GpsLocationData.SensorSource.unicore
+ gps.latitude = (sfloat(gnrmc[3][:2]) + (sfloat(gnrmc[3][2:]) / 60)) * (1 if gnrmc[4] == "N" else -1)
+ gps.longitude = (sfloat(gnrmc[5][:3]) + (sfloat(gnrmc[5][3:]) / 60)) * (1 if gnrmc[6] == "E" else -1)
+
+ try:
+ date = gnrmc[9][:6]
+ dt = datetime.datetime.strptime(f"{date} {gnrmc[1]}", '%d%m%y %H%M%S.%f')
+ gps.unixTimestampMillis = dt.timestamp()*1e3
+ except Exception:
+ pass
+
+ gps.bearingDeg = sfloat(gnrmc[8])
+
+ if len(state['$GNGGA']):
+ gngga = state['$GNGGA']
+ if gngga[10] == 'M':
+ gps.altitude = sfloat(gngga[9])
+
+ if len(state['$GNGSA']):
+ gngsa = state['$GNGSA']
+ gps.horizontalAccuracy = sfloat(gngsa[4])
+ gps.verticalAccuracy = sfloat(gngsa[5])
+
+ #if len(state['$NAVACC']):
+ # # $NAVVEL,264415000,5,3,0.375,0.141,-0.735,-65.450*2A
+ # navacc = state['$NAVACC']
+ # gps.horizontalAccuracy = sfloat(navacc[3])
+ # gps.speedAccuracy = sfloat(navacc[4])
+ # gps.bearingAccuracyDeg = sfloat(navacc[5])
+
+ if len(state['$NAVVEL']):
+ # $NAVVEL,264415000,5,3,0.375,0.141,-0.735,-65.450*2A
+ navvel = state['$NAVVEL']
+ vECEF = [
+ sfloat(navvel[4]),
+ sfloat(navvel[5]),
+ sfloat(navvel[6]),
+ ]
+
+ lat = np.radians(gps.latitude)
+ lon = np.radians(gps.longitude)
+ R = np.array([
+ [-np.sin(lat) * np.cos(lon), -np.sin(lon), -np.cos(lat) * np.cos(lon)],
+ [-np.sin(lat) * np.sin(lon), np.cos(lon), -np.cos(lat) * np.sin(lon)],
+ [np.cos(lat), 0, -np.sin(lat)]
+ ])
+
+ vNED = [float(x) for x in R.dot(vECEF)]
+ gps.vNED = vNED
+ gps.speed = np.linalg.norm(vNED)
+
+ # TODO: set these from the module
+ gps.bearingAccuracyDeg = 5.
+ gps.speedAccuracy = 3.
+
+ return msg
+
+
+@retry(attempts=10, delay=0.1)
+def setup(u):
+ at_cmd('AT+CGPS=0')
+ at_cmd('AT+CGPS=1')
+ time.sleep(1.0)
+
+ # setup NAVXXX outputs
+ for i in range(4):
+ u.send(f"$CFGMSG,1,{i},1")
+ for i in (1, 3):
+ u.send(f"$CFGMSG,3,{i},1")
+
+ # 10Hz NAV outputs
+ u.send("$CFGNAV,100,100,1000")
+
+
+def main():
+ wait_for_modem("AT+CGPS?")
+
+ u = Unicore()
+ setup(u)
+
+ state = defaultdict(list)
+ pm = messaging.PubMaster(['gpsLocation'])
+ while True:
+ try:
+ msg = u.recv().decode('utf8').strip()
+ if "DEBUG" in os.environ:
+ print(repr(msg))
+
+ if len(msg) > 0:
+ if checksum(msg) != msg.split('*')[1]:
+ cloudlog.error(f"invalid checksum: {repr(msg)}")
+ continue
+
+ k = msg.split(',')[0]
+ state[k] = msg.split(',')
+ if '$GNRMC' not in msg:
+ continue
+
+ pm.send('gpsLocation', build_msg(state))
+ except Exception:
+ traceback.print_exc()
+ cloudlog.exception("gps.issue")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py
index 7a1e972e19..669c1520db 100755
--- a/tools/lib/logreader.py
+++ b/tools/lib/logreader.py
@@ -89,7 +89,7 @@ def default_valid_file(fn: LogPath) -> bool:
def auto_strategy(rlog_paths: LogPaths, qlog_paths: LogPaths, interactive: bool, valid_file: ValidFileCallable) -> LogPaths:
# auto select logs based on availability
- if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths):
+ if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths) and all(qlog is not None and valid_file(qlog) for qlog in qlog_paths):
if interactive:
if input("Some rlogs were not found, would you like to fallback to qlogs for those segments? (y/n) ").lower() != "y":
return rlog_paths
@@ -172,6 +172,15 @@ def auto_source(sr: SegmentRange, mode=ReadMode.RLOG) -> LogPaths:
SOURCES: list[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,]
exceptions = []
+
+ # for automatic fallback modes, auto_source needs to first check if rlogs exist for any source
+ if mode in [ReadMode.AUTO, ReadMode.AUTO_INTERACTIVE]:
+ for source in SOURCES:
+ try:
+ return check_source(source, sr, ReadMode.RLOG)
+ except Exception:
+ pass
+
# Automatically determine viable source
for source in SOURCES:
try: