FrogPilot setup - FrogPilot functions
This commit is contained in:
parent
1cfa307f80
commit
396e471a5e
@ -207,6 +207,9 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
|
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
|
||||||
{"UpdaterLastFetchTime", PERSISTENT},
|
{"UpdaterLastFetchTime", PERSISTENT},
|
||||||
{"Version", PERSISTENT},
|
{"Version", PERSISTENT},
|
||||||
|
|
||||||
|
// FrogPilot parameters
|
||||||
|
{"ParamConversionVersion", PERSISTENT},
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -565,4 +565,6 @@ tinygrad_repo/tinygrad/runtime/ops_gpu.py
|
|||||||
tinygrad_repo/tinygrad/shape/*
|
tinygrad_repo/tinygrad/shape/*
|
||||||
tinygrad_repo/tinygrad/*.py
|
tinygrad_repo/tinygrad/*.py
|
||||||
|
|
||||||
|
selfdrive/frogpilot/frogpilot_process.py
|
||||||
|
selfdrive/frogpilot/controls/frogpilot_planner.py
|
||||||
selfdrive/frogpilot/controls/lib/frogpilot_functions.py
|
selfdrive/frogpilot/controls/lib/frogpilot_functions.py
|
||||||
|
@ -840,6 +840,12 @@ class Controls:
|
|||||||
|
|
||||||
self.CS_prev = CS
|
self.CS_prev = CS
|
||||||
|
|
||||||
|
# Update FrogPilot events
|
||||||
|
self.update_frogpilot_events(CS)
|
||||||
|
|
||||||
|
# Update FrogPilot variables
|
||||||
|
self.update_frogpilot_variables(CS)
|
||||||
|
|
||||||
def read_personality_param(self):
|
def read_personality_param(self):
|
||||||
try:
|
try:
|
||||||
return int(self.params.get('LongitudinalPersonality'))
|
return int(self.params.get('LongitudinalPersonality'))
|
||||||
@ -867,6 +873,15 @@ class Controls:
|
|||||||
e.set()
|
e.set()
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
|
def update_frogpilot_events(self, CS):
|
||||||
|
|
||||||
|
def update_frogpilot_variables(self, CS):
|
||||||
|
self.driving_gear = CS.gearShifter not in (GearShifter.neutral, GearShifter.park, GearShifter.reverse, GearShifter.unknown)
|
||||||
|
|
||||||
|
fpcc_send = messaging.new_message('frogpilotCarControl')
|
||||||
|
fpcc_send.valid = CS.canValid
|
||||||
|
fpcc_send.frogpilotCarControl = self.FPCC
|
||||||
|
self.pm.send('frogpilotCarControl', fpcc_send)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
config_realtime_process(4, Priority.CTRL_HIGH)
|
config_realtime_process(4, Priority.CTRL_HIGH)
|
||||||
|
@ -58,11 +58,11 @@ STOP_DISTANCE = 6.0
|
|||||||
|
|
||||||
def get_jerk_factor(personality=log.LongitudinalPersonality.standard):
|
def get_jerk_factor(personality=log.LongitudinalPersonality.standard):
|
||||||
if personality==log.LongitudinalPersonality.relaxed:
|
if personality==log.LongitudinalPersonality.relaxed:
|
||||||
return 1.0
|
return 1.0, 1.0
|
||||||
elif personality==log.LongitudinalPersonality.standard:
|
elif personality==log.LongitudinalPersonality.standard:
|
||||||
return 1.0
|
return 1.0, 1.0
|
||||||
elif personality==log.LongitudinalPersonality.aggressive:
|
elif personality==log.LongitudinalPersonality.aggressive:
|
||||||
return 0.5
|
return 0.5, 0.5
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("Longitudinal personality not supported")
|
raise NotImplementedError("Longitudinal personality not supported")
|
||||||
|
|
||||||
@ -271,11 +271,10 @@ class LongitudinalMpc:
|
|||||||
for i in range(N):
|
for i in range(N):
|
||||||
self.solver.cost_set(i, 'Zl', Zl)
|
self.solver.cost_set(i, 'Zl', Zl)
|
||||||
|
|
||||||
def set_weights(self, prev_accel_constraint=True, personality=log.LongitudinalPersonality.standard):
|
def set_weights(self, acceleration_jerk_factor=1.0, speed_jerk_factor=1.0, prev_accel_constraint=True, personality=log.LongitudinalPersonality.standard):
|
||||||
jerk_factor = get_jerk_factor(personality)
|
|
||||||
if self.mode == 'acc':
|
if self.mode == 'acc':
|
||||||
a_change_cost = A_CHANGE_COST if prev_accel_constraint else 0
|
a_change_cost = acceleration_jerk_factor if prev_accel_constraint else 0
|
||||||
cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, jerk_factor * a_change_cost, jerk_factor * J_EGO_COST]
|
cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, a_change_cost, speed_jerk_factor]
|
||||||
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST]
|
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST]
|
||||||
elif self.mode == 'blended':
|
elif self.mode == 'blended':
|
||||||
a_change_cost = 40.0 if prev_accel_constraint else 0
|
a_change_cost = 40.0 if prev_accel_constraint else 0
|
||||||
@ -330,8 +329,7 @@ class LongitudinalMpc:
|
|||||||
self.cruise_min_a = min_a
|
self.cruise_min_a = min_a
|
||||||
self.max_a = max_a
|
self.max_a = max_a
|
||||||
|
|
||||||
def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard):
|
def update(self, radarstate, v_cruise, x, v, a, j, t_follow, personality=log.LongitudinalPersonality.standard):
|
||||||
t_follow = get_T_FOLLOW(personality)
|
|
||||||
v_ego = self.x0[1]
|
v_ego = self.x0[1]
|
||||||
self.status = radarstate.leadOne.status or radarstate.leadTwo.status
|
self.status = radarstate.leadOne.status or radarstate.leadTwo.status
|
||||||
|
|
||||||
|
@ -115,11 +115,12 @@ class LongitudinalPlanner:
|
|||||||
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
|
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
|
||||||
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
|
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
|
||||||
|
|
||||||
self.mpc.set_weights(prev_accel_constraint, personality=sm['controlsState'].personality)
|
self.mpc.set_weights(sm['frogpilotPlan'].accelerationJerk, sm['frogpilotPlan'].speedJerk, prev_accel_constraint, personality=sm['controlsState'].personality)
|
||||||
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
|
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
|
||||||
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
|
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
|
||||||
x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error)
|
x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error)
|
||||||
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['controlsState'].personality)
|
self.mpc.update(sm['radarState'], sm['frogpilotPlan'].vCruise, x, v, a, j, sm['frogpilotPlan'].tFollow,
|
||||||
|
personality=sm['controlsState'].personality)
|
||||||
|
|
||||||
self.v_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.v_solution)
|
self.v_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.v_solution)
|
||||||
self.a_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.a_solution)
|
self.a_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.a_solution)
|
||||||
|
82
selfdrive/frogpilot/controls/frogpilot_planner.py
Normal file
82
selfdrive/frogpilot/controls/frogpilot_planner.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import cereal.messaging as messaging
|
||||||
|
|
||||||
|
from cereal import car, log
|
||||||
|
|
||||||
|
from openpilot.common.conversions import Conversions as CV
|
||||||
|
from openpilot.common.numpy_fast import interp
|
||||||
|
from openpilot.common.params import Params
|
||||||
|
|
||||||
|
from openpilot.selfdrive.car.interfaces import ACCEL_MIN, ACCEL_MAX
|
||||||
|
from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_UNSET
|
||||||
|
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import A_CHANGE_COST, J_EGO_COST, COMFORT_BRAKE, STOP_DISTANCE, get_jerk_factor, \
|
||||||
|
get_safe_obstacle_distance, get_stopped_equivalence_factor, get_T_FOLLOW
|
||||||
|
from openpilot.selfdrive.controls.lib.longitudinal_planner import A_CRUISE_MIN, Lead, get_max_accel
|
||||||
|
|
||||||
|
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import CITY_SPEED_LIMIT, CRUISING_SPEED, calculate_lane_width, calculate_road_curvature
|
||||||
|
|
||||||
|
GearShifter = car.CarState.GearShifter
|
||||||
|
|
||||||
|
class FrogPilotPlanner:
|
||||||
|
def __init__(self):
|
||||||
|
self.params_memory = Params("/dev/shm/params")
|
||||||
|
|
||||||
|
self.acceleration_jerk = 0
|
||||||
|
self.frame = 0
|
||||||
|
self.road_curvature = 0
|
||||||
|
self.speed_jerk = 0
|
||||||
|
|
||||||
|
def update(self, carState, controlsState, frogpilotCarControl, frogpilotCarState, frogpilotNavigation, liveLocationKalman, modelData, radarState):
|
||||||
|
self.lead_one = radarState.leadOne
|
||||||
|
|
||||||
|
v_cruise_kph = min(controlsState.vCruise, V_CRUISE_UNSET)
|
||||||
|
v_cruise = v_cruise_kph * CV.KPH_TO_MS
|
||||||
|
|
||||||
|
v_ego = max(carState.vEgo, 0)
|
||||||
|
v_lead = self.lead_one.vLead
|
||||||
|
|
||||||
|
lead_distance = self.lead_one.dRel
|
||||||
|
|
||||||
|
self.base_acceleration_jerk, self.base_speed_jerk = get_jerk_factor(controlsState.personality)
|
||||||
|
self.t_follow = get_T_FOLLOW(controlsState.personality)
|
||||||
|
|
||||||
|
if self.lead_one.status:
|
||||||
|
self.update_follow_values(lead_distance, stopping_distance, v_ego, v_lead)
|
||||||
|
else:
|
||||||
|
self.acceleration_jerk = self.base_acceleration_jerk
|
||||||
|
self.speed_jerk = self.base_speed_jerk
|
||||||
|
|
||||||
|
self.road_curvature = calculate_road_curvature(modelData, v_ego)
|
||||||
|
self.v_cruise = self.update_v_cruise(carState, controlsState, frogpilotCarState, frogpilotNavigation, liveLocationKalman, modelData, v_cruise, v_ego)
|
||||||
|
|
||||||
|
self.frame += 1
|
||||||
|
|
||||||
|
def update_follow_values(self, lead_distance, stopping_distance, v_ego, v_lead):
|
||||||
|
|
||||||
|
def update_v_cruise(self, carState, controlsState, frogpilotCarState, frogpilotNavigation, liveLocationKalman, modelData, v_cruise, v_ego):
|
||||||
|
v_cruise_cluster = max(controlsState.vCruiseCluster, controlsState.vCruise) * CV.KPH_TO_MS
|
||||||
|
v_cruise_diff = v_cruise_cluster - v_cruise
|
||||||
|
|
||||||
|
v_ego_cluster = max(carState.vEgoCluster, v_ego)
|
||||||
|
v_ego_diff = v_ego_cluster - v_ego
|
||||||
|
|
||||||
|
targets = []
|
||||||
|
filtered_targets = [target if target > CRUISING_SPEED else v_cruise for target in targets]
|
||||||
|
|
||||||
|
return min(filtered_targets)
|
||||||
|
|
||||||
|
def publish(self, sm, pm):
|
||||||
|
frogpilot_plan_send = messaging.new_message('frogpilotPlan')
|
||||||
|
frogpilot_plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState'])
|
||||||
|
frogpilotPlan = frogpilot_plan_send.frogpilotPlan
|
||||||
|
|
||||||
|
frogpilotPlan.accelerationJerk = A_CHANGE_COST * float(self.acceleration_jerk)
|
||||||
|
frogpilotPlan.accelerationJerkStock = A_CHANGE_COST * float(self.base_acceleration_jerk)
|
||||||
|
frogpilotPlan.speedJerk = J_EGO_COST * float(self.speed_jerk)
|
||||||
|
frogpilotPlan.speedJerkStock = J_EGO_COST * float(self.base_speed_jerk)
|
||||||
|
frogpilotPlan.tFollow = float(self.t_follow)
|
||||||
|
|
||||||
|
frogpilotPlan.vCruise = float(self.v_cruise)
|
||||||
|
|
||||||
|
pm.send('frogpilotPlan', frogpilot_plan_send)
|
@ -1,10 +1,61 @@
|
|||||||
|
import datetime
|
||||||
import filecmp
|
import filecmp
|
||||||
|
import glob
|
||||||
|
import numpy as np
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from openpilot.common.basedir import BASEDIR
|
from openpilot.common.basedir import BASEDIR
|
||||||
|
from openpilot.common.numpy_fast import interp
|
||||||
|
from openpilot.common.params import Params
|
||||||
|
from openpilot.common.params_pyx import UnknownKeyName
|
||||||
from openpilot.system.hardware import HARDWARE
|
from openpilot.system.hardware import HARDWARE
|
||||||
|
from openpilot.system.version import get_short_branch, get_commit_date
|
||||||
|
|
||||||
|
CITY_SPEED_LIMIT = 25 # 55mph is typically the minimum speed for highways
|
||||||
|
CRUISING_SPEED = 5 # Roughly the speed cars go when not touching the gas while in drive
|
||||||
|
PROBABILITY = 0.6 # 60% chance of condition being true
|
||||||
|
THRESHOLD = 5 # Time threshold (0.25s)
|
||||||
|
|
||||||
|
def calculate_lane_width(lane, current_lane, road_edge):
|
||||||
|
lane_x, lane_y = np.array(lane.x), np.array(lane.y)
|
||||||
|
edge_x, edge_y = np.array(road_edge.x), np.array(road_edge.y)
|
||||||
|
current_x, current_y = np.array(current_lane.x), np.array(current_lane.y)
|
||||||
|
|
||||||
|
lane_y_interp = np.interp(current_x, lane_x[lane_x.argsort()], lane_y[lane_x.argsort()])
|
||||||
|
road_edge_y_interp = np.interp(current_x, edge_x[edge_x.argsort()], edge_y[edge_x.argsort()])
|
||||||
|
|
||||||
|
distance_to_lane = np.mean(np.abs(current_y - lane_y_interp))
|
||||||
|
distance_to_road_edge = np.mean(np.abs(current_y - road_edge_y_interp))
|
||||||
|
|
||||||
|
return min(distance_to_lane, distance_to_road_edge)
|
||||||
|
|
||||||
|
def calculate_road_curvature(modelData, v_ego):
|
||||||
|
orientation_rate = np.array(np.abs(modelData.orientationRate.z))
|
||||||
|
velocity = np.array(modelData.velocity.x)
|
||||||
|
max_pred_lat_acc = np.amax(orientation_rate * velocity)
|
||||||
|
return max_pred_lat_acc / (v_ego**2)
|
||||||
|
|
||||||
|
class MovingAverageCalculator:
|
||||||
|
def __init__(self):
|
||||||
|
self.data = []
|
||||||
|
self.total = 0
|
||||||
|
|
||||||
|
def add_data(self, value):
|
||||||
|
if len(self.data) == THRESHOLD:
|
||||||
|
self.total -= self.data.pop(0)
|
||||||
|
self.data.append(value)
|
||||||
|
self.total += value
|
||||||
|
|
||||||
|
def get_moving_average(self):
|
||||||
|
if len(self.data) == 0:
|
||||||
|
return None
|
||||||
|
return self.total / len(self.data)
|
||||||
|
|
||||||
|
def reset_data(self):
|
||||||
|
self.data = []
|
||||||
|
self.total = 0
|
||||||
|
|
||||||
class FrogPilotFunctions:
|
class FrogPilotFunctions:
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -17,6 +68,61 @@ class FrogPilotFunctions:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Unexpected error occurred: {e}")
|
print(f"Unexpected error occurred: {e}")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def convert_params(cls, params, params_storage, params_tracking):
|
||||||
|
if params.get("InstallDate") == "November 21, 2023 - 02:10PM":
|
||||||
|
params.remove("InstallDate")
|
||||||
|
|
||||||
|
version = 2
|
||||||
|
|
||||||
|
try:
|
||||||
|
if params_storage.check_key("ParamConversionVersion"):
|
||||||
|
current_version = params_storage.get_int("ParamConversionVersion")
|
||||||
|
if current_version == version:
|
||||||
|
print("Params already converted, moving on.")
|
||||||
|
return
|
||||||
|
print("Converting params...")
|
||||||
|
except UnknownKeyName:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def convert_param_mappings(param_mappings, remove_from, min_value=-1):
|
||||||
|
for key, (getter, setter) in param_mappings.items():
|
||||||
|
try:
|
||||||
|
value = getter(key)
|
||||||
|
if value > min_value:
|
||||||
|
setter(key, value)
|
||||||
|
remove_from.remove(key)
|
||||||
|
except UnknownKeyName:
|
||||||
|
pass
|
||||||
|
|
||||||
|
param_mappings = {
|
||||||
|
"FrogPilotDrives": (params.get_int, params_tracking.put_int),
|
||||||
|
"FrogPilotKilometers": (params.get_float, params_tracking.put_float),
|
||||||
|
"FrogPilotMinutes": (params.get_float, params_tracking.put_float)
|
||||||
|
}
|
||||||
|
convert_param_mappings(param_mappings, params, 0)
|
||||||
|
|
||||||
|
param_storage_mappings = {
|
||||||
|
"FrogPilotDrives": (params_storage.get_int, params_tracking.put_int),
|
||||||
|
"FrogPilotKilometers": (params_storage.get_float, params_tracking.put_float),
|
||||||
|
"FrogPilotMinutes": (params_storage.get_float, params_tracking.put_float)
|
||||||
|
}
|
||||||
|
convert_param_mappings(param_storage_mappings, params_storage, 0)
|
||||||
|
|
||||||
|
def convert_param(key, action_func):
|
||||||
|
try:
|
||||||
|
if params_storage.check_key(key):
|
||||||
|
value = params_storage.get_bool(key)
|
||||||
|
if value:
|
||||||
|
action_func()
|
||||||
|
except UnknownKeyName:
|
||||||
|
pass
|
||||||
|
|
||||||
|
convert_param("DisableOnroadUploads", lambda: (params.put("DeviceManagement", "True"), params.put("NoUploads", "True")))
|
||||||
|
|
||||||
|
print("Params successfully converted!")
|
||||||
|
params_storage.put_int("ParamConversionVersion", version)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_frogpilot(cls):
|
def setup_frogpilot(cls):
|
||||||
frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
|
frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
|
||||||
|
4
selfdrive/frogpilot/controls/lib/frogpilot_variables.py
Normal file
4
selfdrive/frogpilot/controls/lib/frogpilot_variables.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CITY_SPEED_LIMIT = 25 # 55mph is typically the minimum speed for highways
|
||||||
|
CRUISING_SPEED = 5 # Roughly the speed cars go when not touching the gas while in drive
|
||||||
|
PROBABILITY = 0.6 # 60% chance of condition being true
|
||||||
|
THRESHOLD = 5 # Time threshold (0.25s)
|
80
selfdrive/frogpilot/frogpilot_process.py
Normal file
80
selfdrive/frogpilot/frogpilot_process.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import datetime
|
||||||
|
import http.client
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import urllib.error
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
import cereal.messaging as messaging
|
||||||
|
|
||||||
|
from cereal import log
|
||||||
|
from openpilot.common.params import Params
|
||||||
|
from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process
|
||||||
|
from openpilot.common.time import system_time_valid
|
||||||
|
from openpilot.system.hardware import HARDWARE
|
||||||
|
|
||||||
|
from openpilot.selfdrive.frogpilot.controls.frogpilot_planner import FrogPilotPlanner
|
||||||
|
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import FrogPilotFunctions
|
||||||
|
|
||||||
|
WIFI = log.DeviceState.NetworkType.wifi
|
||||||
|
|
||||||
|
def github_pinged(url="https://github.com", timeout=5):
|
||||||
|
try:
|
||||||
|
urllib.request.urlopen(url, timeout=timeout)
|
||||||
|
return True
|
||||||
|
except (urllib.error.URLError, socket.timeout, http.client.RemoteDisconnected):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def time_checks(deviceState, now, params, params_memory):
|
||||||
|
screen_off = deviceState.screenBrightnessPercent == 0
|
||||||
|
wifi_connection = deviceState.networkType == WIFI
|
||||||
|
|
||||||
|
def frogpilot_thread():
|
||||||
|
config_realtime_process(5, Priority.CTRL_LOW)
|
||||||
|
|
||||||
|
params = Params()
|
||||||
|
params_memory = Params("/dev/shm/params")
|
||||||
|
|
||||||
|
frogpilot_functions = FrogPilotFunctions()
|
||||||
|
frogpilot_planner = FrogPilotPlanner()
|
||||||
|
|
||||||
|
first_run = True
|
||||||
|
time_validated = system_time_valid()
|
||||||
|
|
||||||
|
pm = messaging.PubMaster(['frogpilotPlan'])
|
||||||
|
sm = messaging.SubMaster(['carState', 'controlsState', 'deviceState', 'frogpilotCarControl', 'frogpilotCarState', 'frogpilotNavigation',
|
||||||
|
'frogpilotPlan', 'liveLocationKalman', 'longitudinalPlan', 'modelV2', 'radarState'],
|
||||||
|
poll='modelV2', ignore_avg_freq=['radarState'])
|
||||||
|
|
||||||
|
while True:
|
||||||
|
sm.update()
|
||||||
|
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
deviceState = sm['deviceState']
|
||||||
|
started = deviceState.started
|
||||||
|
|
||||||
|
if started and sm.updated['modelV2']:
|
||||||
|
frogpilot_planner.update(sm['carState'], sm['controlsState'], sm['frogpilotCarControl'], sm['frogpilotCarState'],
|
||||||
|
sm['frogpilotNavigation'], sm['liveLocationKalman'], sm['modelV2'], sm['radarState'])
|
||||||
|
frogpilot_planner.publish(sm, pm)
|
||||||
|
|
||||||
|
if not time_validated:
|
||||||
|
time_validated = system_time_valid()
|
||||||
|
if not time_validated:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if now.second == 0 or first_run:
|
||||||
|
if not started and github_pinged():
|
||||||
|
time_checks(deviceState, now, params, params_memory)
|
||||||
|
|
||||||
|
first_run = False
|
||||||
|
|
||||||
|
time.sleep(DT_MDL)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
frogpilot_thread()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -24,7 +24,19 @@ from openpilot.system.version import is_dirty, get_commit, get_version, get_orig
|
|||||||
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import FrogPilotFunctions
|
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import FrogPilotFunctions
|
||||||
|
|
||||||
|
|
||||||
def manager_init() -> None:
|
def frogpilot_boot_functions(frogpilot_functions):
|
||||||
|
try:
|
||||||
|
while not system_time_valid():
|
||||||
|
print("Waiting for system time to become valid...")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An unexpected error occurred: {e}")
|
||||||
|
|
||||||
|
def manager_init(frogpilot_functions) -> None:
|
||||||
|
frogpilot_boot = threading.Thread(target=frogpilot_boot_functions, args=(frogpilot_functions,))
|
||||||
|
frogpilot_boot.start()
|
||||||
|
|
||||||
save_bootlog()
|
save_bootlog()
|
||||||
|
|
||||||
params = Params()
|
params = Params()
|
||||||
@ -34,6 +46,8 @@ def manager_init() -> None:
|
|||||||
if is_release_branch():
|
if is_release_branch():
|
||||||
params.clear_all(ParamKeyType.DEVELOPMENT_ONLY)
|
params.clear_all(ParamKeyType.DEVELOPMENT_ONLY)
|
||||||
|
|
||||||
|
frogpilot_functions.convert_params(params, params_storage)
|
||||||
|
|
||||||
default_params: list[tuple[str, str | bytes]] = [
|
default_params: list[tuple[str, str | bytes]] = [
|
||||||
("CompletedTrainingVersion", "0"),
|
("CompletedTrainingVersion", "0"),
|
||||||
("DisengageOnAccelerator", "0"),
|
("DisengageOnAccelerator", "0"),
|
||||||
@ -180,7 +194,7 @@ def manager_thread() -> None:
|
|||||||
def main(frogpilot_functions) -> None:
|
def main(frogpilot_functions) -> None:
|
||||||
frogpilot_functions.setup_frogpilot()
|
frogpilot_functions.setup_frogpilot()
|
||||||
|
|
||||||
manager_init()
|
manager_init(frogpilot_functions)
|
||||||
if os.getenv("PREPAREONLY") is not None:
|
if os.getenv("PREPAREONLY") is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@ procs = [
|
|||||||
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),
|
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),
|
||||||
PythonProcess("webrtcd", "system.webrtc.webrtcd", notcar),
|
PythonProcess("webrtcd", "system.webrtc.webrtcd", notcar),
|
||||||
PythonProcess("webjoystick", "tools.bodyteleop.web", notcar),
|
PythonProcess("webjoystick", "tools.bodyteleop.web", notcar),
|
||||||
|
|
||||||
|
# FrogPilot processes
|
||||||
|
PythonProcess("frogpilot_process", "selfdrive.frogpilot.frogpilot_process", always_run),
|
||||||
]
|
]
|
||||||
|
|
||||||
managed_processes = {p.name: p for p in procs}
|
managed_processes = {p.name: p for p in procs}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user