version: dragonpilot development version for EON/C2

date: 2024-02-28T16:32:56
commit: af29cad3e29308622bbbcec7445c15e5433961ec
This commit is contained in:
dragonpilot
2024-02-28 16:12:38 +08:00
committed by Vehicle Researcher
parent be05ffa5bf
commit 3c195b3af7
48 changed files with 571 additions and 324 deletions
+8
View File
@@ -1,3 +1,11 @@
2024-02-27
========================
* Fixed door lock/unlock for Toyotas.
* otisserv and fileserv only for offroad.
* Enabling otisserv for offroad status and snapshot.
* Toyota: improve longitudinal control (https://github.com/commaai/openpilot/pull/30697)
* Updated manager/ modules
2024-02-26
========================
* applied transform patch. (https://github.com/commaai/openpilot/pull/31495)
Binary file not shown.
Binary file not shown.
+138
View File
@@ -0,0 +1,138 @@
'''
rick:
this file is identical to system/swaglog.py, put a copy here to reduce code changes when updating from op master branch.
'''
import logging
import os
import time
import warnings
from pathlib import Path
from logging.handlers import BaseRotatingHandler
import zmq
from openpilot.common.logging_extra import SwagLogger, SwagFormatter, SwagLogFileFormatter
from openpilot.system.hardware import PC
if PC:
SWAGLOG_DIR = os.path.join(str(Path.home()), ".comma", "log")
else:
SWAGLOG_DIR = "/data/log/"
def get_file_handler():
Path(SWAGLOG_DIR).mkdir(parents=True, exist_ok=True)
base_filename = os.path.join(SWAGLOG_DIR, "swaglog")
handler = SwaglogRotatingFileHandler(base_filename)
return handler
class SwaglogRotatingFileHandler(BaseRotatingHandler):
def __init__(self, base_filename, interval=60, max_bytes=1024*256, backup_count=2500, encoding=None):
super().__init__(base_filename, mode="a", encoding=encoding, delay=True)
self.base_filename = base_filename
self.interval = interval # seconds
self.max_bytes = max_bytes
self.backup_count = backup_count
self.log_files = self.get_existing_logfiles()
log_indexes = [f.split(".")[-1] for f in self.log_files]
self.last_file_idx = max([int(i) for i in log_indexes if i.isdigit()] or [-1])
self.last_rollover = None
self.doRollover()
def _open(self):
self.last_rollover = time.monotonic()
self.last_file_idx += 1
next_filename = f"{self.base_filename}.{self.last_file_idx:010}"
stream = open(next_filename, self.mode, encoding=self.encoding)
self.log_files.insert(0, next_filename)
return stream
def get_existing_logfiles(self):
log_files = list()
base_dir = os.path.dirname(self.base_filename)
for fn in os.listdir(base_dir):
fp = os.path.join(base_dir, fn)
if fp.startswith(self.base_filename) and os.path.isfile(fp):
log_files.append(fp)
return sorted(log_files)
def shouldRollover(self, record):
size_exceeded = self.max_bytes > 0 and self.stream.tell() >= self.max_bytes
time_exceeded = self.interval > 0 and self.last_rollover + self.interval <= time.monotonic()
return size_exceeded or time_exceeded
def doRollover(self):
if self.stream:
self.stream.close()
self.stream = self._open()
if self.backup_count > 0:
while len(self.log_files) > self.backup_count:
to_delete = self.log_files.pop()
if os.path.exists(to_delete): # just being safe, should always exist
os.remove(to_delete)
class UnixDomainSocketHandler(logging.Handler):
def __init__(self, formatter):
logging.Handler.__init__(self)
self.setFormatter(formatter)
self.pid = None
self.zctx = None
self.sock = None
def __del__(self):
if self.sock is not None:
self.sock.close()
if self.zctx is not None:
self.zctx.term()
def connect(self):
self.zctx = zmq.Context()
self.sock = self.zctx.socket(zmq.PUSH)
self.sock.setsockopt(zmq.LINGER, 10)
self.sock.connect("ipc:///tmp/logmessage")
self.pid = os.getpid()
def emit(self, record):
if os.getpid() != self.pid:
# TODO suppresses warning about forking proc with zmq socket, fix root cause
warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<zmq.*>")
self.connect()
msg = self.format(record).rstrip('\n')
# print("SEND".format(repr(msg)))
try:
s = chr(record.levelno)+msg
self.sock.send(s.encode('utf8'), zmq.NOBLOCK)
except zmq.error.Again:
# drop :/
pass
def add_file_handler(log):
"""
Function to add the file log handler to swaglog.
This can be used to store logs when logmessaged is not running.
"""
handler = get_file_handler()
handler.setFormatter(SwagLogFileFormatter(log))
log.addHandler(handler)
cloudlog = log = SwagLogger()
log.setLevel(logging.DEBUG)
outhandler = logging.StreamHandler()
print_level = os.environ.get('LOGPRINT', 'warning')
if print_level == 'debug':
outhandler.setLevel(logging.DEBUG)
elif print_level == 'info':
outhandler.setLevel(logging.INFO)
elif print_level == 'warning':
outhandler.setLevel(logging.WARNING)
log.addHandler(outhandler)
# logs are sent through IPC before writing to disk to prevent disk I/O blocking
log.addHandler(UnixDomainSocketHandler(SwagFormatter(log)))
+1 -1
View File
@@ -1 +1 @@
#define COMMA_VERSION "2024.02.26"
#define COMMA_VERSION "2024.02.28"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+37 -4
View File
@@ -12,6 +12,7 @@ from openpilot.common.params import Params
SteerControlType = car.CarParams.SteerControlType
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
# LKA limits
# EPS faults if you apply torque while the steering rate is above 100 deg/s for too long
@@ -26,6 +27,12 @@ MAX_USER_TORQUE = 500
MAX_LTA_ANGLE = 94.9461 # deg
MAX_LTA_DRIVER_TORQUE_ALLOWANCE = 150 # slightly above steering pressed allows some resistance when changing lanes
# PCM compensatory force calculation threshold
# a variation in accel command is more pronounced at higher speeds, let compensatory forces ramp to zero before
# applying when speed is high
COMPENSATORY_CALCULATION_THRESHOLD_V = [-0.3, -0.25, 0.] # m/s^2
COMPENSATORY_CALCULATION_THRESHOLD_BP = [0., 11., 23.] # m/s
# rick - toyota auto lock / unlock
GearShifter = car.CarState.GearShifter
UNLOCK_CMD = b'\x40\x05\x30\x11\x00\x40\x00\x00'
@@ -59,6 +66,7 @@ class CarController:
self.last_standstill = False
self.standstill_req = False
self.steer_rate_counter = 0
self.prohibit_neg_calculation = True
self.packer = CANPacker(dbc_name)
self.gas = 0
@@ -89,6 +97,7 @@ class CarController:
hud_control = CC.hudControl
pcm_cancel_cmd = CC.cruiseControl.cancel
lat_active = CC.latActive and abs(CS.out.steeringTorque) < MAX_USER_TORQUE
stopping = actuators.longControlState == LongCtrlState.stopping
# *** control msgs ***
can_sends = []
@@ -211,7 +220,28 @@ class CarController:
interceptor_gas_cmd = clip(pedal_command, 0., MAX_INTERCEPTOR_GAS)
else:
interceptor_gas_cmd = 0.
pcm_accel_cmd = clip(actuators.accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
# prohibit negative compensatory calculations when first activating long after accelerator depression or engagement
if not CC.longActive:
self.prohibit_neg_calculation = True
comp_thresh = interp(CS.out.vEgo, COMPENSATORY_CALCULATION_THRESHOLD_BP, COMPENSATORY_CALCULATION_THRESHOLD_V)
# don't reset until a reasonable compensatory value is reached
if CS.pcm_neutral_force > comp_thresh * self.CP.mass:
self.prohibit_neg_calculation = False
# NO_STOP_TIMER_CAR will creep if compensation is applied when stopping or stopped, don't compensate when stopped or stopping
should_compensate = True
if (self.CP.carFingerprint in NO_STOP_TIMER_CAR and actuators.accel < 1e-3 or stopping) or CS.out.vEgo < 1e-3:
should_compensate = False
# limit minimum to only positive until first positive is reached after engagement, don't calculate when long isn't active
if CC.longActive and should_compensate and not self.prohibit_neg_calculation:
accel_offset = CS.pcm_neutral_force / self.CP.mass
else:
accel_offset = 0.
# only calculate pcm_accel_cmd when long is active to prevent disengagement from accelerator depression
if CC.longActive:
pcm_accel_cmd = clip(actuators.accel + accel_offset, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
else:
pcm_accel_cmd = 0.
# TODO: probably can delete this. CS.pcm_acc_status uses a different signal
# than CS.cruiseState.enabled. confirm they're not meaningfully different
@@ -236,15 +266,18 @@ class CarController:
# we can spam can to cancel the system even if we are using lat only control
if (self.frame % 3 == 0 and self.CP.openpilotLongitudinalControl) or pcm_cancel_cmd:
lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged
# when stopping, send -2.5 raw acceleration immediately to prevent vehicle from creeping, else send actuators.accel
accel_raw = -2.5 if stopping else actuators.accel
# Lexus IS uses a different cancellation message
if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR:
can_sends.append(toyotacan.create_acc_cancel_command(self.packer))
elif self.CP.openpilotLongitudinalControl:
can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert))
can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, accel_raw, pcm_cancel_cmd,
self.standstill_req, lead, CS.acc_type, fcw_alert))
self.accel = pcm_accel_cmd
else:
can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False))
can_sends.append(toyotacan.create_accel_command(self.packer, 0, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False))
if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl:
# send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd.
@@ -259,7 +292,7 @@ class CarController:
# - there is something to stop displaying
send_ui = False
if ((fcw_alert or steer_alert) and not self.alert_active) or \
(not (fcw_alert or steer_alert) and self.alert_active):
(not (fcw_alert or steer_alert) and self.alert_active):
send_ui = True
self.alert_active = not self.alert_active
elif pcm_cancel_cmd:
+1
View File
@@ -200,6 +200,7 @@ class CarState(CarStateBase):
ret.cruiseState.standstill = self.pcm_acc_status == 7
ret.cruiseState.enabled = bool(cp.vl["PCM_CRUISE"]["CRUISE_ACTIVE"])
ret.cruiseState.nonAdaptive = cp.vl["PCM_CRUISE"]["CRUISE_STATE"] in (1, 2, 3, 4, 5, 6)
self.pcm_neutral_force = cp.vl["PCM_CRUISE"]["NEUTRAL_FORCE"]
ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"])
ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0
+14 -16
View File
@@ -259,23 +259,21 @@ class CarInterface(CarInterfaceBase):
# to a negative value, so it won't matter.
ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else MIN_ACC_SPEED
# on stock Toyota this is -2.5
ret.stopAccel = -2.5
tune = ret.longitudinalTuning
tune.deadzoneBP = [0., 9.]
tune.deadzoneV = [.0, .15]
if candidate in TSS2_CAR or ret.enableGasInterceptor:
tune.kpBP = [0., 5., 20.]
tune.kpV = [1.3, 1.0, 0.7]
tune.kiBP = [0., 5., 12., 20., 27.]
tune.kiV = [.35, .23, .20, .17, .1]
if candidate in TSS2_CAR:
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25
ret.stoppingDecelRate = 0.3 # reach stopping target smoothly
else:
tune.kpBP = [0., 5., 35.]
tune.kiBP = [0., 35.]
tune.kpV = [3.6, 2.4, 1.5]
tune.kiV = [0.54, 0.36]
tune.deadzoneBP = [0., 16., 20., 30.]
tune.deadzoneV = [.04, .05, .08, .15]
ret.stoppingDecelRate = 0.17 # This is okay for TSS-P
if candidate in TSS2_CAR:
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25
ret.stoppingDecelRate = 0.009 # reach stopping target smoothly
tune.kpBP = [0., 5.]
tune.kpV = [0.8, 1.]
tune.kiBP = [0., 5.]
tune.kiV = [0.3, 1.]
return ret
+3 -2
View File
@@ -33,10 +33,10 @@ def create_lta_steer_command(packer, steer_control_type, steer_angle, steer_req,
return packer.make_can_msg("STEERING_LTA", 0, values)
def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert):
def create_accel_command(packer, accel, accel_raw, pcm_cancel, standstill_req, lead, acc_type, fcw_alert):
# TODO: find the exact canceling bit that does not create a chime
values = {
"ACCEL_CMD": accel,
"ACCEL_CMD": accel, # compensated accel command
"ACC_TYPE": acc_type,
"DISTANCE": 0,
"MINI_CAR": lead,
@@ -45,6 +45,7 @@ def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_ty
"CANCEL_REQ": pcm_cancel,
"ALLOW_LONG_PRESS": 1,
"ACC_CUT_IN": fcw_alert, # only shown when ACC enabled
"ACCEL_CMD_ALT": accel_raw, # raw accel command, pcm uses this to calculate a compensatory force
}
return packer.make_can_msg("ACC_CONTROL", 0, values)
+1 -1
View File
@@ -72,7 +72,7 @@ class Controls:
self.dp_gps_ok_once = False
# Ensure the current branch is cached, otherwise the first iteration of controlsd lags
self.branch = get_short_branch("")
self.branch = get_short_branch()
# Setup sockets
self.pm = pm
@@ -21,25 +21,25 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Version = 2024-02-26
# Version = 2024-02-28
from common.numpy_fast import interp
# d-e2e, from modeldata.h
TRAJECTORY_SIZE = 33
LEAD_WINDOW_SIZE = 3
LEAD_PROB = 0.6
LEAD_PROB = 0.5
SLOW_DOWN_WINDOW_SIZE = 5
SLOW_DOWN_PROB = 0.6
SLOW_DOWN_WINDOW_SIZE = 3
SLOW_DOWN_PROB = 0.5
SLOW_DOWN_BP = [0., 10., 20., 30., 40., 50., 55.]
SLOW_DOWN_DIST = [10, 30., 50., 70., 80., 90., 120.]
SLOWNESS_WINDOW_SIZE = 20
SLOWNESS_PROB = 0.6
SLOWNESS_WINDOW_SIZE = 10
SLOWNESS_PROB = 0.5
SLOWNESS_CRUISE_OFFSET = 1.05
DANGEROUS_TTC_WINDOW_SIZE = 5
DANGEROUS_TTC_WINDOW_SIZE = 3
DANGEROUS_TTC = 2.0
HIGHWAY_CRUISE_KPH = 70
@@ -49,7 +49,7 @@ STOP_AND_GO_FRAME = 60
SET_MODE_TIMEOUT = 10
MPC_FCW_WINDOW_SIZE = 10
MPC_FCW_PROB = 0.6
MPC_FCW_PROB = 0.5
class SNG_State:
off = 0
@@ -129,18 +129,18 @@ class DynamicEndtoEndController:
# fcw detection
self._mpc_fcw_gmac.add_data(self._mpc_fcw_crash_cnt > 0)
self._has_mpc_fcw = self._mpc_fcw_gmac.get_moving_average() >= MPC_FCW_PROB
self._has_mpc_fcw = self._mpc_fcw_gmac.get_moving_average() > MPC_FCW_PROB
# nav enable detection
self._has_nav_enabled = md.navEnabled
# lead detection
self._lead_gmac.add_data(lead_one.status)
self._has_lead_filtered = self._lead_gmac.get_moving_average() >= LEAD_PROB
self._has_lead_filtered = self._lead_gmac.get_moving_average() > LEAD_PROB
# slow down detection
self._slow_down_gmac.add_data(len(md.orientation.x) == len(md.position.x) == TRAJECTORY_SIZE and md.position.x[TRAJECTORY_SIZE - 1] < interp(self._v_ego_kph, SLOW_DOWN_BP, SLOW_DOWN_DIST))
self._has_slow_down = self._slow_down_gmac.get_moving_average() >= SLOW_DOWN_PROB
self._has_slow_down = self._slow_down_gmac.get_moving_average() > SLOW_DOWN_PROB
# blinker detection
self._has_blinkers = car_state.leftBlinker or car_state.rightBlinker
@@ -162,7 +162,7 @@ class DynamicEndtoEndController:
# slowness detection
if not self._has_standstill:
self._slowness_gmac.add_data(self._v_ego_kph <= (self._v_cruise_kph*SLOWNESS_CRUISE_OFFSET))
self._has_slowness = self._slowness_gmac.get_moving_average() >= SLOWNESS_PROB
self._has_slowness = self._slowness_gmac.get_moving_average() > SLOWNESS_PROB
# dangerous TTC detection
if not self._has_lead_filtered and self._has_lead_filtered_prev:
@@ -180,23 +180,23 @@ class DynamicEndtoEndController:
self._has_lead_filtered_prev = self._has_lead_filtered
self._frame += 1
def _blended_priority_mode(self):
def _radarless_mode(self):
# when mpc fcw crash prob is high
# use blended to slow down quickly
if self._has_mpc_fcw:
self._set_mode('blended')
return
# when blinker is on and speed is driving below highway cruise speed: blended
# we dont want it to switch mode at higher speed, blended may trigger hard brake
if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH:
self._set_mode('blended')
return
# # when blinker is on and speed is driving below highway cruise speed: blended
# # we dont want it to switch mode at higher speed, blended may trigger hard brake
# if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH:
# self._set_mode('blended')
# return
# when at highway cruise and SNG: blended
# ensuring blended mode is used because acc is bad at catching SNG lead car
# especially those who accel very fast and then brake very hard.
if self._sng_state == SNG_State.going and self._v_cruise_kph < HIGHWAY_CRUISE_KPH:
if self._sng_state == SNG_State.going and self._v_cruise_kph >= HIGHWAY_CRUISE_KPH:
self._set_mode('blended')
return
@@ -225,7 +225,7 @@ class DynamicEndtoEndController:
self._set_mode('blended')
def _acc_priority_mode(self):
def _radar_mode(self):
# when mpc fcw crash prob is high
# use blended to slow down quickly
if self._has_mpc_fcw:
@@ -266,9 +266,9 @@ class DynamicEndtoEndController:
if self._is_enabled:
self._update(car_state, lead_one, md, controls_state)
if radar_unavailable:
self._blended_priority_mode()
self._radarless_mode()
else:
self._acc_priority_mode()
self._radar_mode()
self._mode_prev = self._mode
return self._mode
@@ -345,7 +345,7 @@
},
"json_file": "/data/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/acados_ocp_long.json",
"model": {
"con_h_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegpcaaaaaaaaaaaaaafaaaaaaabgpfngjgogegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpfngbgihchcaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaacbaaaaaamgfgbgegpfegbgoghgfgchpfggbgdgehpgchegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhchbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaa",
"con_h_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegpcaaaaaaaaaaaaaafaaaaaaabgpfngjgogegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpfngbgihchcaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaacbaaaaaamgfgbgegpfegbgoghgfgchpfggbgdgehpgchegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhchbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaa",
"con_h_expr_e": null,
"con_phi_expr": null,
"con_phi_expr_e": null,
@@ -368,9 +368,9 @@
"cost_r_in_psi_expr": null,
"cost_r_in_psi_expr_0": null,
"cost_r_in_psi_expr_e": null,
"cost_y_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg",
"cost_y_expr_0": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg",
"cost_y_expr_e": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajggaaaaaaaegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbg",
"cost_y_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg",
"cost_y_expr_0": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegkaaaaaaaaaaaaaaagaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbgegpcaaaaaaaaaaaaaafaaaaaaakgpffghgpg",
"cost_y_expr_e": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaakaaaaaaaihpfpgcgdhehbgdgmgfgegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegbaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegeaaaaaaaaaaaaaaaeglaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgfaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaamgfgbgegpfehpfggpgmgmgpghhcheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachaaaaaaaaaaaagbaeegbaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaajgkaaaaaaachcaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaabgpffghgpgegcaaaaaaaaaaaaaaachbbaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaagaaaaaaaahchfgghpfbg",
"disc_dyn_expr": null,
"dyn_disc_fun": null,
"dyn_disc_fun_jac": null,
@@ -54,7 +54,7 @@ T_IDXS = np.array(T_IDXS_LST)
FCW_IDXS = T_IDXS < 5.0
T_DIFFS = np.diff(T_IDXS, prepend=[0.])
COMFORT_BRAKE = 2.5
STOP_DISTANCE = 6.0
STOP_DISTANCE = 5.5
def get_jerk_factor(personality=log.LongitudinalPersonality.standard):
if personality==log.LongitudinalPersonality.relaxed:
@@ -109,8 +109,8 @@ def get_stopped_equivalence_factor_krkeegen(v_lead, v_ego):
if np.all(v_lead - v_ego > 0):
v_diff_offset = ((v_lead - v_ego) * 1.)
v_diff_offset = np.clip(v_diff_offset, 0, STOP_DISTANCE / 2)
v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego)/10), 0)
distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset
v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego**2)/10), 0)
distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset * 1.2
return distance
def gen_long_model():
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+21 -21
View File
@@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_err_fun(double *nom_x, double *delta_x, double *out_1964954299455970933);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_6003963640381126063);
void car_H_mod_fun(double *state, double *out_1207008555950061675);
void car_f_fun(double *state, double dt, double *out_2803172193991338453);
void car_F_fun(double *state, double dt, double *out_4664417582021608014);
void car_h_25(double *state, double *unused, double *out_8570962910733009665);
void car_H_25(double *state, double *unused, double *out_1998904563998531603);
void car_h_24(double *state, double *unused, double *out_2751191583816658395);
void car_H_24(double *state, double *unused, double *out_6775987843813639291);
void car_h_30(double *state, double *unused, double *out_4933513382478987315);
void car_H_30(double *state, double *unused, double *out_1869565616855291533);
void car_h_26(double *state, double *unused, double *out_2501630051949713498);
void car_H_26(double *state, double *unused, double *out_1742598754875524621);
void car_h_27(double *state, double *unused, double *out_8932271310074879516);
void car_H_27(double *state, double *unused, double *out_305197694945133378);
void car_h_29(double *state, double *unused, double *out_5877023235380649750);
void car_H_29(double *state, double *unused, double *out_2379796961169683717);
void car_h_28(double *state, double *unused, double *out_5895485258630546831);
void car_H_28(double *state, double *unused, double *out_4343427232735009968);
void car_h_31(double *state, double *unused, double *out_5381229435042917038);
void car_H_31(double *state, double *unused, double *out_2029550525875492031);
void car_err_fun(double *nom_x, double *delta_x, double *out_8989390406176655642);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_872949834645227037);
void car_H_mod_fun(double *state, double *out_6190064514277074980);
void car_f_fun(double *state, double dt, double *out_5737342647877877229);
void car_F_fun(double *state, double dt, double *out_6498734987852944578);
void car_h_25(double *state, double *unused, double *out_358371148521877751);
void car_H_25(double *state, double *unused, double *out_3752758241963538269);
void car_h_24(double *state, double *unused, double *out_4557978488111553664);
void car_H_24(double *state, double *unused, double *out_993751085002970765);
void car_h_30(double *state, double *unused, double *out_7522901502232171434);
void car_H_30(double *state, double *unused, double *out_6271091200470786896);
void car_h_26(double *state, double *unused, double *out_2521228234571325789);
void car_H_26(double *state, double *unused, double *out_7057284211724338870);
void car_h_27(double *state, double *unused, double *out_1301881001423540186);
void car_H_27(double *state, double *unused, double *out_8494685271654730113);
void car_h_29(double *state, double *unused, double *out_2895729189507225245);
void car_H_29(double *state, double *unused, double *out_6781322544785179080);
void car_h_28(double *state, double *unused, double *out_9068663034437199427);
void car_H_28(double *state, double *unused, double *out_1698923527715648506);
void car_h_31(double *state, double *unused, double *out_3995820676775900101);
void car_H_31(double *state, double *unused, double *out_6431076109490987394);
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
void car_set_mass(double x);
void car_set_rotational_inertia(double x);
+13 -13
View File
@@ -5,18 +5,18 @@ void gnss_update_6(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void gnss_update_20(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void gnss_update_7(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void gnss_update_21(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void gnss_err_fun(double *nom_x, double *delta_x, double *out_8519908807701444381);
void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_7494726988393394594);
void gnss_H_mod_fun(double *state, double *out_6213794081998936506);
void gnss_f_fun(double *state, double dt, double *out_7557732014251175831);
void gnss_F_fun(double *state, double dt, double *out_3784107475037224440);
void gnss_h_6(double *state, double *sat_pos, double *out_1045706946388579730);
void gnss_H_6(double *state, double *sat_pos, double *out_6469468708647551695);
void gnss_h_20(double *state, double *sat_pos, double *out_4390939550384841311);
void gnss_H_20(double *state, double *sat_pos, double *out_4150453882875260635);
void gnss_h_7(double *state, double *sat_pos_vel, double *out_882947065038288714);
void gnss_H_7(double *state, double *sat_pos_vel, double *out_4769832076722140500);
void gnss_h_21(double *state, double *sat_pos_vel, double *out_882947065038288714);
void gnss_H_21(double *state, double *sat_pos_vel, double *out_4769832076722140500);
void gnss_err_fun(double *nom_x, double *delta_x, double *out_8157223566737921768);
void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_2044125793472420016);
void gnss_H_mod_fun(double *state, double *out_9173041979963174697);
void gnss_f_fun(double *state, double dt, double *out_1618057822244112223);
void gnss_F_fun(double *state, double dt, double *out_2095238804530870251);
void gnss_h_6(double *state, double *sat_pos, double *out_8758992661908707843);
void gnss_H_6(double *state, double *sat_pos, double *out_3561767187659398853);
void gnss_h_20(double *state, double *sat_pos, double *out_2943069687929850059);
void gnss_H_20(double *state, double *sat_pos, double *out_2968919167798348741);
void gnss_h_7(double *state, double *sat_pos_vel, double *out_4774871104966573529);
void gnss_H_7(double *state, double *sat_pos_vel, double *out_149136905432068571);
void gnss_h_21(double *state, double *sat_pos_vel, double *out_4774871104966573529);
void gnss_H_21(double *state, double *sat_pos_vel, double *out_149136905432068571);
void gnss_predict(double *in_x, double *in_P, double *in_Q, double dt);
}
Binary file not shown.
+24 -24
View File
@@ -10,29 +10,29 @@ void live_update_32(double *in_x, double *in_P, double *in_z, double *in_R, doub
void live_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void live_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void live_update_33(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void live_H(double *in_vec, double *out_2427080946257414198);
void live_err_fun(double *nom_x, double *delta_x, double *out_4499017012837728402);
void live_inv_err_fun(double *nom_x, double *true_x, double *out_4568239191987130813);
void live_H_mod_fun(double *state, double *out_7466442051496209266);
void live_f_fun(double *state, double dt, double *out_7616316395018437217);
void live_F_fun(double *state, double dt, double *out_3738746660903124007);
void live_h_4(double *state, double *unused, double *out_5102933337023237333);
void live_H_4(double *state, double *unused, double *out_7235994504100796541);
void live_h_9(double *state, double *unused, double *out_6101034663185489335);
void live_H_9(double *state, double *unused, double *out_51224431163650929);
void live_h_10(double *state, double *unused, double *out_1900712798164773370);
void live_H_10(double *state, double *unused, double *out_4820155672142958661);
void live_h_12(double *state, double *unused, double *out_8879026316650247416);
void live_H_12(double *state, double *unused, double *out_6614895479053202874);
void live_h_35(double *state, double *unused, double *out_1924620734251358832);
void live_H_35(double *state, double *unused, double *out_3869332446728189165);
void live_h_32(double *state, double *unused, double *out_1566775458117550308);
void live_H_32(double *state, double *unused, double *out_8625923032509862606);
void live_h_13(double *state, double *unused, double *out_5786152235345498787);
void live_H_13(double *state, double *unused, double *out_1965575430518687731);
void live_h_14(double *state, double *unused, double *out_6101034663185489335);
void live_H_14(double *state, double *unused, double *out_51224431163650929);
void live_h_33(double *state, double *unused, double *out_1672775015514148260);
void live_H_33(double *state, double *unused, double *out_718775442089331561);
void live_H(double *in_vec, double *out_6974567924666299102);
void live_err_fun(double *nom_x, double *delta_x, double *out_2493100912041570996);
void live_inv_err_fun(double *nom_x, double *true_x, double *out_7217190665066253352);
void live_H_mod_fun(double *state, double *out_6899062083944887710);
void live_f_fun(double *state, double dt, double *out_252278658732009113);
void live_F_fun(double *state, double dt, double *out_4169121626430309510);
void live_h_4(double *state, double *unused, double *out_2184045668377535913);
void live_H_4(double *state, double *unused, double *out_5091087556127760923);
void live_h_9(double *state, double *unused, double *out_8158653303070436890);
void live_H_9(double *state, double *unused, double *out_2196131379136686547);
void live_h_10(double *state, double *unused, double *out_6830468309703972597);
void live_H_10(double *state, double *unused, double *out_8221089086801312150);
void live_h_12(double *state, double *unused, double *out_3698550038738074472);
void live_H_12(double *state, double *unused, double *out_6974398140539057697);
void live_h_35(double *state, double *unused, double *out_3507821483290070437);
void live_H_35(double *state, double *unused, double *out_1724425498755153547);
void live_h_32(double *state, double *unused, double *out_1049805558840064954);
void live_H_32(double *state, double *unused, double *out_1593260713814413078);
void live_h_13(double *state, double *unused, double *out_1881416958735212550);
void live_H_13(double *state, double *unused, double *out_5911629335895004065);
void live_h_14(double *state, double *unused, double *out_8158653303070436890);
void live_H_14(double *state, double *unused, double *out_2196131379136686547);
void live_h_33(double *state, double *unused, double *out_7532622185414820130);
void live_H_33(double *state, double *unused, double *out_8472160794518560882);
void live_predict(double *in_x, double *in_P, double *in_Q, double dt);
}
Binary file not shown.
Binary file not shown.
+6 -4
View File
@@ -9,7 +9,7 @@ from openpilot.common.basedir import BASEDIR
from openpilot.common.spinner import Spinner
from openpilot.common.text_window import TextWindow
from openpilot.system.hardware import AGNOS
from openpilot.system.swaglog import cloudlog, add_file_handler
from openpilot.common.swaglog import cloudlog, add_file_handler
from openpilot.system.version import is_dirty
MAX_CACHE_SIZE = 4e9 if "CI" in os.environ else 2e9
@@ -19,19 +19,21 @@ TOTAL_SCONS_NODES = 2560
MAX_BUILD_PROGRESS = 100
PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt'))
def build(spinner: Spinner, dirty: bool = False) -> None:
def build(spinner: Spinner, dirty: bool = False, minimal: bool = False) -> None:
env = os.environ.copy()
env['SCONS_PROGRESS'] = "1"
nproc = os.cpu_count()
if nproc is None:
nproc = 2
nproc =3
extra_args = ["--minimal"] if minimal else []
# building with all cores can result in using too
# much memory, so retry with less parallelism
compile_output: List[bytes] = []
for n in (nproc, nproc/2, 1):
compile_output.clear()
scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate"], cwd=BASEDIR, env=env, stderr=subprocess.PIPE)
scons: subprocess.Popen = subprocess.Popen(["scons", f"-j{int(n)}", "--cache-populate", *extra_args], cwd=BASEDIR, env=env, stderr=subprocess.PIPE)
assert scons.stderr is not None
# Read progress from stderr and update spinner
+26 -2
View File
@@ -1,9 +1,16 @@
import errno
import fcntl
import os
import sys
import fcntl
import errno
import pathlib
import shutil
import signal
import subprocess
import tempfile
import threading
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
def unblock_stdout() -> None:
# get a non-blocking stdout
@@ -41,3 +48,20 @@ def unblock_stdout() -> None:
def write_onroad_params(started, params):
params.put_bool("IsOnroad", started)
params.put_bool("IsOffroad", not started)
def save_bootlog():
# copy current params
tmp = tempfile.mkdtemp()
params_dirname = pathlib.Path(Params().get_param_path()).name
params_dir = os.path.join(tmp, params_dirname)
shutil.copytree(Params().get_param_path(), params_dir, dirs_exist_ok=True)
def fn(tmpdir):
env = os.environ.copy()
env['PARAMS_COPY_PATH'] = tmpdir
subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), env=env)
shutil.rmtree(tmpdir)
t = threading.Thread(target=fn, args=(tmp, ))
t.daemon = True
t.start()
+20 -28
View File
@@ -19,10 +19,11 @@ from openpilot.selfdrive.manager.helpers import unblock_stdout, write_onroad_par
from openpilot.selfdrive.manager.process import ensure_running
from openpilot.selfdrive.manager.process_config import managed_processes
from openpilot.selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID
from openpilot.system.swaglog import cloudlog, add_file_handler
from openpilot.common.swaglog import cloudlog, add_file_handler
from openpilot.system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \
get_normalized_origin, terms_version, training_version, \
is_tested_branch, is_release_branch
get_normalized_origin, terms_version, training_version, \
is_tested_branch, is_release_branch, get_commit_date
import json
from openpilot.selfdrive.car.fingerprints import all_known_cars, all_legacy_fingerprint_cars
@@ -38,6 +39,8 @@ def manager_init() -> None:
params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START)
params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION)
params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
if is_release_branch():
params.clear_all(ParamKeyType.DEVELOPMENT_ONLY)
default_params: List[Tuple[str, Union[str, bytes]]] = [
("CompletedTrainingVersion", "0"),
@@ -98,13 +101,6 @@ def manager_init() -> None:
if params.get(k) is None:
params.put(k, v)
# is this dashcam?
if os.getenv("PASSIVE") is not None:
params.put_bool("Passive", bool(int(os.getenv("PASSIVE", "0"))))
if params.get("Passive") is None:
raise Exception("Passive must be set to continue")
# Create folders needed for msgq
try:
os.mkdir("/dev/shm")
@@ -117,9 +113,10 @@ def manager_init() -> None:
params.put("Version", get_version())
params.put("TermsVersion", terms_version)
params.put("TrainingVersion", training_version)
params.put("GitCommit", get_commit(default=""))
params.put("GitBranch", get_short_branch(default=""))
params.put("GitRemote", get_origin(default=""))
params.put("GitCommit", get_commit())
params.put("GitCommitDate", get_commit_date())
params.put("GitBranch", get_short_branch())
params.put("GitRemote", get_origin())
params.put_bool("IsTestedBranch", is_tested_branch())
params.put_bool("IsReleaseBranch", is_release_branch())
@@ -131,6 +128,9 @@ def manager_init() -> None:
serial = params.get("HardwareSerial")
raise Exception(f"Registration failed for device {serial}")
os.environ['DONGLE_ID'] = dongle_id # Needed for swaglog
os.environ['GIT_ORIGIN'] = get_normalized_origin() # Needed for swaglog
os.environ['GIT_BRANCH'] = get_short_branch() # Needed for swaglog
os.environ['GIT_COMMIT'] = get_commit() # Needed for swaglog
if not is_dirty():
os.environ['CLEAN'] = '1'
@@ -145,8 +145,7 @@ def manager_init() -> None:
dirty=is_dirty(),
device=HARDWARE.get_device_type())
def manager_prepare() -> None:
# preimport all processes
for p in managed_processes.values():
p.prepare()
@@ -192,7 +191,7 @@ def manager_thread() -> None:
if not params.get_bool("dp_otisserv"):
ignore += ["otisserv"]
sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState'])
sm = messaging.SubMaster(['deviceState', 'carParams'], poll='deviceState')
pm = messaging.PubMaster(['managerState'])
write_onroad_params(False, params)
@@ -201,7 +200,7 @@ def manager_thread() -> None:
started_prev = False
while True:
sm.update()
sm.update(1000)
started = sm['deviceState'].started
@@ -218,7 +217,7 @@ def manager_thread() -> None:
ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore)
running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
running = ' '.join("{}{}\u001b[0m".format("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc)
print(running)
cloudlog.debug(running)
@@ -243,17 +242,8 @@ def manager_thread() -> None:
def main() -> None:
prepare_only = os.getenv("PREPAREONLY") is not None
manager_init()
# Start UI early so prepare can happen in the background
if not prepare_only:
managed_processes['ui'].start()
manager_prepare()
if prepare_only:
if os.getenv("PREPAREONLY") is not None:
return
# SystemExit on sigterm
@@ -298,6 +288,8 @@ if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("got CTRL-C, exiting")
except Exception:
add_file_handler(cloudlog)
cloudlog.exception("Manager failed to start")
+21 -39
View File
@@ -8,14 +8,14 @@ from typing import Optional, Callable, List, ValuesView
from abc import ABC, abstractmethod
from multiprocessing import Process
from setproctitle import setproctitle # pylint: disable=no-name-in-module
from setproctitle import setproctitle
from cereal import car, log
import cereal.messaging as messaging
import openpilot.selfdrive.sentry as sentry
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.system.swaglog import cloudlog
from openpilot.common.swaglog import cloudlog
WATCHDOG_FN = "/dev/shm/wd_"
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
@@ -89,9 +89,7 @@ def join_process(process: Process, timeout: float) -> None:
class ManagerProcess(ABC):
daemon = False
sigkill = False
onroad = True
offroad = False
callback: Optional[Callable[[bool, Params, car.CarParams], bool]] = None
should_run: Callable[[bool, Params, car.CarParams], bool]
proc: Optional[Process] = None
enabled = True
name = ""
@@ -121,7 +119,7 @@ class ManagerProcess(ABC):
fn = WATCHDOG_FN + str(self.proc.pid)
with open(fn, "rb") as f:
# TODO: why can't pylint find struct.unpack?
self.last_watchdog_time = struct.unpack('Q', f.read())[0] # pylint: disable=no-member
self.last_watchdog_time = struct.unpack('Q', f.read())[0]
except Exception:
pass
@@ -193,15 +191,12 @@ class ManagerProcess(ABC):
class NativeProcess(ManagerProcess):
def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None):
def __init__(self, name, cwd, cmdline, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
self.name = name
self.cwd = cwd
self.cmdline = cmdline
self.should_run = should_run
self.enabled = enabled
self.onroad = onroad
self.offroad = offroad
self.callback = callback
self.unkillable = unkillable
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = nativelauncher
@@ -226,14 +221,11 @@ class NativeProcess(ManagerProcess):
class PythonProcess(ManagerProcess):
def __init__(self, name, module, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None):
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
self.name = name
self.module = module
self.should_run = should_run
self.enabled = enabled
self.onroad = onroad
self.offroad = offroad
self.callback = callback
self.unkillable = unkillable
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = launcher
@@ -268,10 +260,12 @@ class DaemonProcess(ManagerProcess):
self.module = module
self.param_name = param_name
self.enabled = enabled
self.onroad = True
self.offroad = True
self.params = None
@staticmethod
def should_run(started, params, CP):
return True
def prepare(self) -> None:
pass
@@ -292,11 +286,11 @@ class DaemonProcess(ManagerProcess):
pass
cloudlog.info(f"starting daemon {self.name}")
proc = subprocess.Popen(['python', '-m', self.module], # pylint: disable=subprocess-popen-preexec-fn
stdin=open('/dev/null'),
stdout=open('/dev/null', 'w'),
stderr=open('/dev/null', 'w'),
preexec_fn=os.setpgrp)
proc = subprocess.Popen(['python', '-m', self.module],
stdin=open('/dev/null'),
stdout=open('/dev/null', 'w'),
stderr=open('/dev/null', 'w'),
preexec_fn=os.setpgrp)
self.params.put(self.param_name, str(proc.pid))
@@ -311,26 +305,14 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None
running = []
for p in procs:
# Conditions that make a process run
run = any((
p.offroad and not started,
p.onroad and started,
))
if p.callback is not None and None not in (params, CP):
run = run or p.callback(started, params, CP)
# Conditions that block a process from starting
run = run and not any((
not p.enabled,
p.name in not_run,
))
if run:
p.start()
if p.enabled and p.name not in not_run and p.should_run(started, params, CP):
running.append(p)
else:
p.stop(block=False)
p.check_watchdog(started)
for p in running:
p.start()
return running
+47 -40
View File
@@ -10,22 +10,20 @@ NO_IR_CTRL = os.path.isfile('/data/media/0/no_ir_ctrl')
WEBCAM = os.getenv("USE_WEBCAM") is not None
def driverview(started: bool, params: Params, CP: car.CarParams) -> bool:
return params.get_bool("IsDriverViewEnabled") # type: ignore
return started or params.get_bool("IsDriverViewEnabled")
def notcar(started: bool, params: Params, CP: car.CarParams) -> bool:
return CP.notCar # type: ignore
return started and CP.notCar
def iscar(started: bool, params: Params, CP: car.CarParams) -> bool:
return not CP.notCar
return started and not CP.notCar
def logging(started, params, CP: car.CarParams) -> bool:
run = (not CP.notCar) or not params.get_bool("DisableLogging")
return started and run
def ublox_available() -> bool:
if EON:
return True
return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps')
return True if EON else os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps')
def ublox(started, params, CP: car.CarParams) -> bool:
use_ublox = ublox_available()
@@ -36,65 +34,74 @@ def ublox(started, params, CP: car.CarParams) -> bool:
def qcomgps(started, params, CP: car.CarParams) -> bool:
return started and not ublox_available()
def always_run(started, params, CP: car.CarParams) -> bool:
return True
def only_onroad(started: bool, params, CP: car.CarParams) -> bool:
return started
def only_offroad(started, params, CP: car.CarParams) -> bool:
return not started
procs = [
NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], callback=driverview),
NativeProcess("clocksd", "system/clocksd", ["./clocksd"]),
NativeProcess("logcatd", "system/logcatd", ["./logcatd"]),
NativeProcess("proclogd", "system/proclogd", ["./proclogd"]),
PythonProcess("logmessaged", "system.logmessaged", offroad=True),
NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], driverview),
NativeProcess("clocksd", "system/clocksd", ["./clocksd"], only_onroad),
NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad),
NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad),
PythonProcess("logmessaged", "system.logmessaged", always_run),
# PythonProcess("micd", "system.micd", callback=iscar),
# PythonProcess("timezoned", "system.timezoned", enabled=not PC, offroad=True),
DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"),
NativeProcess("dmonitoringmodeld", "selfdrive/hybrid_modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM) and not NO_IR_CTRL, callback=driverview),
NativeProcess("dmonitoringmodeld", "selfdrive/hybrid_modeld", ["./dmonitoringmodeld"], driverview, enabled=(not PC or WEBCAM) and not NO_IR_CTRL),
# NativeProcess("encoderd", "system/loggerd", ["./encoderd"]),
# NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], onroad=False, callback=notcar),
NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging),
NativeProcess("modeld", "selfdrive/hybrid_modeld" if not Params().get_bool("dp_0813") else "selfdrive/legacy_modeld", ["./modeld"]),
NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], logging),
NativeProcess("modeld", "selfdrive/hybrid_modeld" if not Params().get_bool("dp_0813") else "selfdrive/legacy_modeld", ["./modeld"], only_onroad),
# NativeProcess("mapsd", "selfdrive/navd", ["./mapsd"]),
# NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"]),
NativeProcess("sensord", "system/sensord", ["./sensord"], enabled=not PC, offroad=EON),
NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if not PC else None)),
NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"]),
NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]),
NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False),
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"),
PythonProcess("torqued", "selfdrive.locationd.torqued"),
PythonProcess("controlsd", "selfdrive.controls.controlsd"),
PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True),
PythonProcess("dmonitoringd", "selfdrive.legacy_monitoring.dmonitoringd", enabled=(not PC or WEBCAM) and not NO_IR_CTRL, callback=driverview),
NativeProcess("sensord", "system/sensord", ["./sensord"], always_run if EON else only_onroad, enabled=not PC),
NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)),
NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], only_onroad),
NativeProcess("locationd", "selfdrive/locationd", ["./locationd"], only_onroad),
NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], always_run, enabled=False),
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad),
PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad),
PythonProcess("controlsd", "selfdrive.controls.controlsd", only_onroad),
PythonProcess("deleter", "selfdrive.loggerd.deleter", always_run),
PythonProcess("dmonitoringd", "selfdrive.legacy_monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM) and not NO_IR_CTRL),
# PythonProcess("laikad", "selfdrive.locationd.laikad"),
# PythonProcess("rawgpsd", "system.sensord.rawgps.rawgpsd", enabled=TICI, onroad=False, callback=qcomgps),
# PythonProcess("navd", "selfdrive.navd.navd"),
PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True),
PythonProcess("paramsd", "selfdrive.locationd.paramsd"),
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], enabled=not PC, onroad=False, callback=ublox),
PythonProcess("pandad", "selfdrive.boardd.pandad", always_run),
PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=not PC),
# PythonProcess("pigeond", "system.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox),
PythonProcess("plannerd", "selfdrive.controls.plannerd"),
PythonProcess("radard", "selfdrive.controls.radard"),
PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True),
PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True),
PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True),
# PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True),
PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad),
PythonProcess("radard", "selfdrive.controls.radard", only_onroad),
PythonProcess("thermald", "selfdrive.thermald.thermald", always_run),
PythonProcess("tombstoned", "selfdrive.tombstoned", always_run, enabled=not PC),
PythonProcess("updated", "selfdrive.updated", only_offroad, enabled=not PC),
PythonProcess("uploader", "selfdrive.loggerd.uploader", only_offroad),
# PythonProcess("statsd", "selfdrive.statsd", offroad=True),
# debug procs
NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, callback=notcar),
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),
# rick - webjoystick needs aiohttp, install additional modules manually: pip install aiohttp aiortc
# PythonProcess("webjoystick", "tools.bodyteleop.web", onroad=False, callback=notcar),
# EON only
PythonProcess("rtshield", "selfdrive.rtshield", enabled=EON),
PythonProcess("shutdownd", "system.hardware.eon.shutdownd", enabled=EON),
PythonProcess("androidd", "system.hardware.eon.androidd", enabled=EON, offroad=True),
PythonProcess("rtshield", "selfdrive.rtshield", only_onroad, enabled=EON),
PythonProcess("shutdownd", "system.hardware.eon.shutdownd", only_onroad, enabled=EON),
PythonProcess("androidd", "system.hardware.eon.androidd", always_run, enabled=EON),
# mapd
PythonProcess("mapd", "selfdrive.mapd.mapd"),
PythonProcess("mapd", "selfdrive.mapd.mapd", only_onroad),
# gpxd
# PythonProcess("gpxd", "selfdrive.dragonpilot.gpxd"),
# PythonProcess("gpx_uploader", "selfdrive.dragonpilot.gpx_uploader", offroad=True),
NativeProcess("otisserv", "selfdrive/dragonpilot", ['./otisserv'], offroad=True),
NativeProcess("fileserv", "selfdrive/dragonpilot", ['./fileserv'], offroad=True),
NativeProcess("otisserv", "selfdrive/dragonpilot", ['./otisserv'], only_offroad),
NativeProcess("fileserv", "selfdrive/dragonpilot", ['./fileserv'], only_offroad),
]
managed_processes = {p.name: p for p in procs}
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -20,7 +20,7 @@ def main():
# 0 for shutdown, 1 for reboot
prop = getprop("sys.shutdown.requested")
if prop is not None and len(prop) > 0:
# os.system("pkill -9 loggerd")
os.system("pkill -9 loggerd")
params.put("LastSystemShutdown", f"'{prop}' {datetime.datetime.now()}")
os.sync()
+58
View File
@@ -0,0 +1,58 @@
import os
from pathlib import Path
from openpilot.system.hardware import PC
DEFAULT_DOWNLOAD_CACHE_ROOT = "/tmp/comma_download_cache"
class Paths:
@staticmethod
def comma_home() -> str:
return os.path.join(str(Path.home()), ".comma" + os.environ.get("OPENPILOT_PREFIX", ""))
@staticmethod
def log_root() -> str:
if os.environ.get('LOG_ROOT', False):
return os.environ['LOG_ROOT']
elif PC:
return str(Path(Paths.comma_home()) / "media" / "0" / "realdata")
else:
return '/data/media/0/realdata/'
@staticmethod
def swaglog_root() -> str:
if PC:
return os.path.join(Paths.comma_home(), "log")
else:
return "/data/log/"
@staticmethod
def swaglog_ipc() -> str:
return "ipc:///tmp/logmessage" + os.environ.get("OPENPILOT_PREFIX", "")
@staticmethod
def download_cache_root() -> str:
if os.environ.get('COMMA_CACHE', False):
return os.environ['COMMA_CACHE'] + "/"
return DEFAULT_DOWNLOAD_CACHE_ROOT + os.environ.get("OPENPILOT_PREFIX", "") + "/"
@staticmethod
def persist_root() -> str:
if PC:
return os.path.join(Paths.comma_home(), "persist")
else:
return "/persist/"
@staticmethod
def stats_root() -> str:
if PC:
return str(Path(Paths.comma_home()) / "stats")
else:
return "/data/stats/"
@staticmethod
def config_root() -> str:
if PC:
return Paths.comma_home()
else:
return "/tmp/.comma"
Binary file not shown.
Binary file not shown.
Binary file not shown.
+26 -29
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env python3
import os
import subprocess
from typing import List, Optional
from typing import List, Optional, TypeVar
from functools import lru_cache
from openpilot.common.basedir import BASEDIR
from openpilot.system.swaglog import cloudlog
from openpilot.common.swaglog import cloudlog
RELEASE_BRANCHES = ['release3-staging', 'dashcam3-staging', 'release3', 'dashcam3', 'nightly']
TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging']
@@ -13,7 +13,7 @@ TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging']
training_version: bytes = b"0.2.0"
terms_version: bytes = b"2"
_RT = TypeVar("_RT")
def cache(user_function, /):
return lru_cache(maxsize=None)(user_function)
@@ -30,41 +30,42 @@ def run_cmd_default(cmd: List[str], default: Optional[str] = None) -> Optional[s
@cache
def get_commit(branch: str = "HEAD", default: Optional[str] = None) -> Optional[str]:
return run_cmd_default(["git", "rev-parse", branch], default=default)
def get_commit(branch: str = "HEAD") -> str:
return run_cmd_default(["git", "rev-parse", branch])
@cache
def get_short_branch(default: Optional[str] = None) -> Optional[str]:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"], default=default)
def get_commit_date(commit: str = "HEAD") -> str:
return run_cmd_default(["git", "show", "--no-patch", "--format='%ct %ci'", commit])
@cache
def get_branch(default: Optional[str] = None) -> Optional[str]:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], default=default)
def get_short_branch() -> str:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"])
@cache
def get_origin(default: Optional[str] = None) -> Optional[str]:
def get_branch() -> str:
return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"])
@cache
def get_origin() -> str:
try:
local_branch = run_cmd(["git", "name-rev", "--name-only", "HEAD"])
tracking_remote = run_cmd(["git", "config", "branch." + local_branch + ".remote"])
return run_cmd(["git", "config", "remote." + tracking_remote + ".url"])
except subprocess.CalledProcessError: # Not on a branch, fallback
return run_cmd_default(["git", "config", "--get", "remote.origin.url"], default=default)
return run_cmd_default(["git", "config", "--get", "remote.origin.url"])
@cache
def get_normalized_origin(default: Optional[str] = None) -> Optional[str]:
origin: Optional[str] = get_origin()
if origin is None:
return default
return origin.replace("git@", "", 1) \
.replace(".git", "", 1) \
.replace("https://", "", 1) \
.replace(":", "/", 1)
def get_normalized_origin() -> str:
return get_origin() \
.replace("git@", "", 1) \
.replace(".git", "", 1) \
.replace("https://", "", 1) \
.replace(":", "/", 1)
@cache
@@ -75,7 +76,7 @@ def get_version() -> str:
@cache
def get_short_version() -> str:
return get_version().split('-')[0] # type: ignore
return get_version().split('-')[0]
@cache
def is_prebuilt() -> bool:
@@ -86,12 +87,7 @@ def is_prebuilt() -> bool:
def is_comma_remote() -> bool:
# note to fork maintainers, this is used for release metrics. please do not
# touch this to get rid of the orange startup alert. there's better ways to do that
origin: Optional[str] = get_origin()
if origin is None:
return False
return origin.startswith(('git@github.com:commaai', 'https://github.com/commaai'))
return get_normalized_origin() == "github.com/commaai/openpilot"
@cache
def is_tested_branch() -> bool:
@@ -105,7 +101,7 @@ def is_release_branch() -> bool:
def is_dirty() -> bool:
origin = get_origin()
branch = get_branch()
if (origin is None) or (branch is None):
if not origin or not branch:
return True
dirty = False
@@ -141,3 +137,4 @@ if __name__ == "__main__":
print(f"Branch: {get_branch()}")
print(f"Short branch: {get_short_branch()}")
print(f"Prebuilt: {is_prebuilt()}")
print(f"Commit date: {get_commit_date()}")