FrogPilot setup

This commit is contained in:
FrogAi
2024-01-12 22:39:30 -07:00
parent 9d97e0ecc1
commit 7308c1b35c
60 changed files with 1660 additions and 49 deletions

39
selfdrive/controls/controlsd.py Executable file → Normal file
View File

@@ -5,7 +5,7 @@ import time
import threading
from typing import SupportsFloat
from cereal import car, log
from cereal import car, log, custom
from openpilot.common.numpy_fast import clip
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper, DT_CTRL
from openpilot.common.params import Params
@@ -48,6 +48,8 @@ EventName = car.CarEvent.EventName
ButtonType = car.CarState.ButtonEvent.Type
SafetyModel = car.CarParams.SafetyModel
FrogPilotEventName = custom.FrogPilotEvents
IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput)
CSID_MAP = {"1": EventName.roadCameraError, "2": EventName.wideRoadCameraError, "0": EventName.driverCameraError}
ACTUATOR_FIELDS = tuple(car.CarControl.Actuators.schema.fields.keys())
@@ -64,7 +66,8 @@ class Controls:
# Setup sockets
self.pm = messaging.PubMaster(['sendcan', 'controlsState', 'carState',
'carControl', 'onroadEvents', 'carParams'])
'carControl', 'onroadEvents', 'carParams',
'frogpilotCarControl'])
self.sensor_packets = ["accelerometer", "gyroscope"]
self.camera_packets = ["roadCameraState", "driverCameraState", "wideRoadCameraState"]
@@ -72,14 +75,17 @@ class Controls:
self.log_sock = messaging.sub_sock('androidLog')
self.can_sock = messaging.sub_sock('can', timeout=20)
# FrogPilot variables
self.params = Params()
self.params_memory = Params("/dev/shm/params")
ignore = self.sensor_packets + ['testJoystick']
if SIMULATION:
ignore += ['driverCameraState', 'managerState']
self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration',
'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman',
'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters',
'testJoystick'] + self.camera_packets + self.sensor_packets,
'testJoystick', 'frogpilotLongitudinalPlan'] + self.camera_packets + self.sensor_packets,
ignore_alive=ignore, ignore_avg_freq=['radarState', 'testJoystick'], ignore_valid=['testJoystick', ])
if CI is None:
@@ -90,8 +96,9 @@ class Controls:
num_pandas = len(messaging.recv_one_retry(self.sm.sock['pandaStates']).pandaStates)
experimental_long_allowed = self.params.get_bool("ExperimentalLongitudinalEnabled")
self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], experimental_long_allowed, num_pandas)
self.CS = self.CI.CS
else:
self.CI, self.CP = CI, CI.CP
self.CI, self.CP, self.CS = CI, CI.CP, CI.CS
self.joystick_mode = self.params.get_bool("JoystickDebugMode")
@@ -106,6 +113,7 @@ class Controls:
self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled")
openpilot_enabled_toggle = self.params.get_bool("OpenpilotEnabledToggle")
passive = self.params.get_bool("Passive") or not openpilot_enabled_toggle
self.update_frogpilot_params()
# detect sound card presence and ensure successful init
sounds_available = HARDWARE.get_sound_card_online()
@@ -138,6 +146,7 @@ class Controls:
self.CC = car.CarControl.new_message()
self.CS_prev = car.CarState.new_message()
self.FPCC = custom.FrogPilotCarControl.new_message()
self.AM = AlertManager()
self.events = Events()
@@ -576,10 +585,15 @@ class Controls:
lat_plan = self.sm['lateralPlan']
long_plan = self.sm['longitudinalPlan']
frogpilot_long_plan = self.sm['frogpilotLongitudinalPlan']
CC = car.CarControl.new_message()
CC.enabled = self.enabled
# Gear Check
gear = car.CarState.GearShifter
driving_gear = CS.gearShifter not in (gear.neutral, gear.park, gear.reverse, gear.unknown)
# Check which actuators can be enabled
standstill = CS.vEgo <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill
CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \
@@ -847,6 +861,12 @@ class Controls:
# copy CarControl to pass to CarInterface on the next iteration
self.CC = CC
# Publish FrogPilot variables
fpcs_send = messaging.new_message('frogpilotCarControl')
fpcs_send.valid = CS.canValid
fpcs_send.frogpilotCarControl = self.FPCC
self.pm.send('frogpilotCarControl', fpcs_send)
def step(self):
start_time = time.monotonic()
@@ -885,10 +905,21 @@ class Controls:
while True:
self.step()
self.rk.monitor_time()
# Update FrogPilot parameters
if self.params_memory.get_bool("FrogPilotTogglesUpdated"):
self.update_frogpilot_params()
except SystemExit:
e.set()
t.join()
def update_frogpilot_params(self):
for obj in [self.CI, self.CS]:
if hasattr(obj, 'update_frogpilot_params'):
obj.update_frogpilot_params(self.params)
longitudinal_tune = self.params.get_bool("LongitudinalTune")
def main():
controls = Controls()

View File

@@ -40,7 +40,9 @@ class DesireHelper:
self.prev_one_blinker = False
self.desire = log.LateralPlan.Desire.none
def update(self, carstate, lateral_active, lane_change_prob):
# FrogPilot variables
def update(self, carstate, modeldata, lateral_active, lane_change_prob, frogpilot_planner):
v_ego = carstate.vEgo
one_blinker = carstate.leftBlinker != carstate.rightBlinker
below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN

View File

@@ -4,7 +4,7 @@ import os
from enum import IntEnum
from typing import Dict, Union, Callable, List, Optional
from cereal import log, car
from cereal import log, car, custom
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
from openpilot.common.realtime import DT_CTRL
@@ -16,6 +16,7 @@ AlertStatus = log.ControlsState.AlertStatus
VisualAlert = car.CarControl.HUDControl.VisualAlert
AudibleAlert = car.CarControl.HUDControl.AudibleAlert
EventName = car.CarEvent.EventName
FrogPilotEventName = custom.FrogPilotEvents
# Alert priorities
@@ -44,6 +45,7 @@ class ET:
# get event name from enum
EVENT_NAME = {v: k for k, v in EventName.schema.enumerants.items()}
EVENT_NAME.update({v: k for k, v in FrogPilotEventName.schema.enumerants.items()})
class Events:
@@ -228,7 +230,7 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
if "REPLAY" in os.environ:
branch = "replay"
return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt)
return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot)
def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage")
@@ -964,6 +966,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
ET.NO_ENTRY: NoEntryAlert("Vehicle Sensors Calibrating"),
},
# FrogPilot Events
}

View File

@@ -27,7 +27,7 @@ class LateralPlanner:
self.debug_mode = debug
def update(self, sm):
def update(self, sm, frogpilot_planner):
v_ego_car = sm['carState'].vEgo
# Parse model predictions
@@ -46,9 +46,9 @@ class LateralPlanner:
self.l_lane_change_prob = desire_state[log.LateralPlan.Desire.laneChangeLeft]
self.r_lane_change_prob = desire_state[log.LateralPlan.Desire.laneChangeRight]
lane_change_prob = self.l_lane_change_prob + self.r_lane_change_prob
self.DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob)
self.DH.update(sm['carState'], md, sm['carControl'].latActive, lane_change_prob, frogpilot_planner)
def publish(self, sm, pm):
def publish(self, sm, pm, frogpilot_planner):
plan_send = messaging.new_message('lateralPlan')
plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState', 'modelV2'])
@@ -72,3 +72,5 @@ class LateralPlanner:
lateralPlan.laneChangeDirection = self.DH.lane_change_direction
pm.send('lateralPlan', plan_send)
frogpilot_planner.publish_lateral(sm, pm, self.DH)

View File

@@ -88,7 +88,9 @@ class LongitudinalPlanner:
j = np.zeros(len(T_IDXS_MPC))
return x, v, a, j
def update(self, sm):
def update(self, sm, frogpilot_planner):
frogpilot_planner.update(sm, self.mpc)
if self.param_read_counter % 50 == 0:
self.read_param()
self.param_read_counter += 1
@@ -152,7 +154,7 @@ class LongitudinalPlanner:
self.a_desired = float(interp(self.dt, ModelConstants.T_IDXS[:CONTROL_N], self.a_desired_trajectory))
self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.a_desired + a_prev) / 2.0
def publish(self, sm, pm):
def publish(self, sm, pm, frogpilot_planner):
plan_send = messaging.new_message('longitudinalPlan')
plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState'])
@@ -173,3 +175,5 @@ class LongitudinalPlanner:
longitudinalPlan.personality = self.personality
pm.send('longitudinalPlan', plan_send)
frogpilot_planner.publish_longitudinal(sm, pm, self.mpc)

View File

@@ -10,6 +10,8 @@ from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPl
from openpilot.selfdrive.controls.lib.lateral_planner import LateralPlanner
import cereal.messaging as messaging
from openpilot.selfdrive.frogpilot.functions.frogpilot_planner import FrogPilotPlanner
def cumtrapz(x, t):
return np.concatenate([[0], np.cumsum(((x[0:-1] + x[1:])/2) * np.diff(t))])
@@ -32,29 +34,34 @@ def plannerd_thread():
cloudlog.info("plannerd is waiting for CarParams")
params = Params()
params_memory = Params("/dev/shm/params")
with car.CarParams.from_bytes(params.get("CarParams", block=True)) as msg:
CP = msg
cloudlog.info("plannerd got CarParams: %s", CP.carName)
debug_mode = bool(int(os.getenv("DEBUG", "0")))
frogpilot_planner = FrogPilotPlanner(params)
longitudinal_planner = LongitudinalPlanner(CP)
lateral_planner = LateralPlanner(CP, debug=debug_mode)
pm = messaging.PubMaster(['longitudinalPlan', 'lateralPlan', 'uiPlan'])
sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2'],
pm = messaging.PubMaster(['longitudinalPlan', 'lateralPlan', 'uiPlan', 'frogpilotLateralPlan', 'frogpilotLongitudinalPlan'])
sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2', 'frogpilotNavigation'],
poll=['radarState', 'modelV2'], ignore_avg_freq=['radarState'])
while True:
sm.update()
if sm.updated['modelV2']:
lateral_planner.update(sm)
lateral_planner.publish(sm, pm)
longitudinal_planner.update(sm)
longitudinal_planner.publish(sm, pm)
lateral_planner.update(sm, frogpilot_planner)
lateral_planner.publish(sm, pm, frogpilot_planner)
longitudinal_planner.update(sm, frogpilot_planner)
longitudinal_planner.publish(sm, pm, frogpilot_planner)
publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner)
if params_memory.get_bool("FrogPilotTogglesUpdated"):
frogpilot_planner.update_frogpilot_params(params)
def main():
plannerd_thread()