mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-07 22:52:06 +08:00
oopsie
This commit is contained in:
@@ -120,6 +120,7 @@ def parse_args() -> argparse.Namespace:
|
||||
parser.add_argument("--transition-step", type=float, default=0.75, help="Seconds between transition-window samples.")
|
||||
parser.add_argument("--max-frames-per-route", type=int, default=1200, help="Maximum frames to score per route.")
|
||||
parser.add_argument("--max-candidates-per-route", type=int, default=500, help="Maximum review candidates to keep per route.")
|
||||
parser.add_argument("--max-candidates-per-frame", type=int, default=1, help="Maximum detector candidates to keep from a single video frame. 0 keeps all.")
|
||||
parser.add_argument("--max-negatives-per-route", type=int, default=60, help="Maximum empty/no-candidate frames to keep per route.")
|
||||
parser.add_argument("--min-proposal-confidence", type=float, default=0.025, help="Loose detector confidence floor for review candidates.")
|
||||
parser.add_argument("--no-read-min-proposal-confidence", type=float, default=0.12, help="Keep no-value detector boxes above this confidence.")
|
||||
@@ -375,8 +376,7 @@ def cluster_key(route_id: str, segment: int, time_s: float, frame_shape: tuple[i
|
||||
time_bucket = int(math.floor(time_s / max(dedupe_seconds, 0.1)))
|
||||
grid_x = int(center_x * 12)
|
||||
grid_y = int(center_y * 8)
|
||||
value = candidate["candidate_speed_limit_mph"] or "none"
|
||||
return f"{route_id}|{segment}|{time_bucket}|{candidate['class_id']}|{value}|{grid_x}|{grid_y}"
|
||||
return f"{route_id}|{segment}|{time_bucket}|{candidate['class_id']}|{grid_x}|{grid_y}"
|
||||
|
||||
|
||||
def candidate_record_key(route_key: str, segment: int, time_s: float, index: int) -> str:
|
||||
@@ -423,17 +423,25 @@ def mine_route(route_id: str, daemon: slv.SpeedLimitVisionDaemon, args: argparse
|
||||
full_detection = daemon._detect_sign(frame_bgr) if args.include_full_detection else None
|
||||
proposals = daemon._collect_detector_classifier_proposals(frame_bgr)
|
||||
candidate_index = 0
|
||||
kept_any = False
|
||||
frame_candidates: list[tuple[int, dict[str, object], object]] = []
|
||||
for proposal in proposals:
|
||||
candidate = analyze_proposal(daemon, frame_bgr, proposal, full_detection, context, args)
|
||||
if candidate is None:
|
||||
continue
|
||||
candidate_index += 1
|
||||
x1, y1, x2, y2 = candidate["crop_bbox"]
|
||||
crop = frame_bgr[y1:y2, x1:x2]
|
||||
frame_candidates.append((candidate_index, candidate, crop))
|
||||
|
||||
frame_candidates.sort(key=lambda item: float(item[1]["review_priority"]), reverse=True)
|
||||
if args.max_candidates_per_frame > 0:
|
||||
frame_candidates = frame_candidates[:args.max_candidates_per_frame]
|
||||
kept_any = bool(frame_candidates)
|
||||
|
||||
for candidate_index, candidate, crop in frame_candidates:
|
||||
record_key = candidate_record_key(route_key, segment.segment, time_s, candidate_index)
|
||||
frame_path = frame_dir / f"{record_key}.jpg"
|
||||
crop_path = crop_dir / f"{record_key}_crop.jpg"
|
||||
x1, y1, x2, y2 = candidate["crop_bbox"]
|
||||
crop = frame_bgr[y1:y2, x1:x2]
|
||||
row = {
|
||||
"record_key": record_key,
|
||||
"route": route_id,
|
||||
|
||||
@@ -560,8 +560,8 @@ IONIQ_6_HIGH_SPEED_RIGHT_TURN_IN_FF_LAT_WIDTH = 0.035
|
||||
IONIQ_6_LOW_SPEED_PID_RESET_SPEED = 0.1 * CV.MPH_TO_MS
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_LAT_START = 0.90
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_LAT_WIDTH = 0.18
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_LEFT = 0.06
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_RIGHT = 0.17
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_LEFT = 0.03
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_RIGHT = 0.11
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_UNWIND_LEFT = 0.78
|
||||
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_UNWIND_RIGHT = 1.10
|
||||
IONIQ_6_OUTPUT_TAPER_SPEED = 8.5
|
||||
|
||||
@@ -24,7 +24,6 @@ from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.common.watchdog import WATCHDOG_FN
|
||||
|
||||
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
|
||||
PYTHON_PROCESS_START_METHOD = os.getenv("PYTHON_PROCESS_START_METHOD", "subprocess")
|
||||
|
||||
DEBUG_ENV_KEYS = (
|
||||
"XDG_RUNTIME_DIR",
|
||||
@@ -644,7 +643,7 @@ class NativeProcess(ManagerProcess):
|
||||
|
||||
|
||||
class PythonProcess(ManagerProcess):
|
||||
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None, nice=None):
|
||||
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None, nice=None, start_method=None):
|
||||
self.name = name
|
||||
self.module = module
|
||||
self.should_run = should_run
|
||||
@@ -652,6 +651,7 @@ class PythonProcess(ManagerProcess):
|
||||
self.sigkill = sigkill
|
||||
self.watchdog_max_dt = watchdog_max_dt
|
||||
self.nice = nice
|
||||
self.start_method = start_method
|
||||
self.launcher = launcher
|
||||
|
||||
def prepare(self) -> None:
|
||||
@@ -682,14 +682,15 @@ class PythonProcess(ManagerProcess):
|
||||
name = self.name if "modeld" not in self.name else "MainProcess"
|
||||
|
||||
cloudlog.info(f"starting python {self.module}")
|
||||
if PYTHON_PROCESS_START_METHOD == "subprocess":
|
||||
start_method = self.start_method or os.getenv("PYTHON_PROCESS_START_METHOD", "fork")
|
||||
if start_method == "subprocess":
|
||||
launcher_code = (
|
||||
"from openpilot.system.manager.process import launcher; "
|
||||
f"launcher({self.module!r}, {self.name!r}, {self.nice!r})"
|
||||
)
|
||||
self.proc = SubprocessProcess(subprocess.Popen([sys.executable, "-c", launcher_code]))
|
||||
else:
|
||||
self.proc = multiprocessing.get_context(PYTHON_PROCESS_START_METHOD).Process(
|
||||
self.proc = multiprocessing.get_context(start_method).Process(
|
||||
name=name,
|
||||
target=self.launcher,
|
||||
args=(self.module, self.name, self.nice),
|
||||
|
||||
@@ -7,10 +7,42 @@ from types import SimpleNamespace
|
||||
from cereal import car
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.hardware import HARDWARE, PC, TICI
|
||||
from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess
|
||||
|
||||
WEBCAM = os.getenv("USE_WEBCAM") is not None
|
||||
UI_WATCHDOG_MAX_DT = int(os.getenv("UI_WATCHDOG_MAX_DT", "10"))
|
||||
device_type = HARDWARE.get_device_type()
|
||||
|
||||
|
||||
def _env_bool(name: str) -> bool | None:
|
||||
value = os.getenv(name)
|
||||
if value is None:
|
||||
return None
|
||||
return value.strip().lower() in ("1", "true", "yes", "on")
|
||||
|
||||
|
||||
def python_ui_enabled(device_type: str) -> bool:
|
||||
for env_name in ("USE_PYTHON_UI", "USE_RAYLIB_UI"):
|
||||
enabled = _env_bool(env_name)
|
||||
if enabled is not None:
|
||||
return enabled
|
||||
|
||||
native_ui = _env_bool("USE_NATIVE_UI")
|
||||
if native_ui is not None:
|
||||
return not native_ui
|
||||
|
||||
return device_type not in ("tici", "tizi")
|
||||
|
||||
|
||||
def python_process_start_method(uses_python_ui: bool, is_pc: bool = PC) -> str:
|
||||
# Native/QT UI devices rely on fork copy-on-write to keep onroad memory low.
|
||||
# Python/raylib UI uses subprocess to avoid fork/import-lock boot hangs.
|
||||
return "fork" if is_pc or not uses_python_ui else "subprocess"
|
||||
|
||||
|
||||
PYTHON_UI = python_ui_enabled(device_type)
|
||||
os.environ.setdefault("PYTHON_PROCESS_START_METHOD", python_process_start_method(PYTHON_UI))
|
||||
|
||||
from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess
|
||||
|
||||
def driverview(started: bool, params: Params, CP: car.CarParams, starpilot_toggles: SimpleNamespace) -> bool:
|
||||
return started or params.get_bool("IsDriverViewEnabled")
|
||||
@@ -143,12 +175,10 @@ procs += [
|
||||
PythonProcess("galaxy", "starpilot.system.galaxy.galaxy", always_run, nice=19),
|
||||
]
|
||||
|
||||
device_type = HARDWARE.get_device_type()
|
||||
if device_type in ("tici", "tizi"):
|
||||
procs.append(NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=UI_WATCHDOG_MAX_DT))
|
||||
else:
|
||||
# C4 (mici) runs the Python raylib UI path.
|
||||
if PYTHON_UI:
|
||||
procs.append(PythonProcess("ui", "selfdrive.ui.ui", always_run, watchdog_max_dt=UI_WATCHDOG_MAX_DT))
|
||||
else:
|
||||
procs.append(NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=UI_WATCHDOG_MAX_DT))
|
||||
|
||||
procs += [
|
||||
PythonProcess("device_syncd", "starpilot.system.device_syncd", always_run),
|
||||
|
||||
@@ -9,7 +9,7 @@ from cereal import car
|
||||
from openpilot.common.params import Params, ParamKeyFlag
|
||||
import openpilot.system.manager.manager as manager
|
||||
from openpilot.system.manager.process import ensure_running
|
||||
from openpilot.system.manager.process_config import managed_processes, procs
|
||||
from openpilot.system.manager.process_config import managed_processes, procs, python_process_start_method, python_ui_enabled
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
|
||||
os.environ['FAKEUPLOAD'] = "1"
|
||||
@@ -111,6 +111,18 @@ class TestManager:
|
||||
assert names.index("the_galaxy") < ui_idx
|
||||
assert names.index("galaxy") < ui_idx
|
||||
|
||||
def test_python_process_start_method_follows_ui_implementation(self):
|
||||
assert python_process_start_method(False, False) == "fork"
|
||||
assert python_process_start_method(True, False) == "subprocess"
|
||||
assert python_process_start_method(True, True) == "fork"
|
||||
|
||||
def test_python_ui_env_override(self, monkeypatch):
|
||||
monkeypatch.setenv("USE_RAYLIB_UI", "1")
|
||||
assert python_ui_enabled("tici") is True
|
||||
|
||||
monkeypatch.setenv("USE_RAYLIB_UI", "0")
|
||||
assert python_ui_enabled("mici") is False
|
||||
|
||||
def test_manager_startup_toggles_use_params_only(self, tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("GIT_BRANCH", "StarPilot")
|
||||
params = FileBackedFakeParams(tmp_path / "params", {
|
||||
|
||||
Reference in New Issue
Block a user