mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-20 15:54:13 +08:00
BURN THE WITCH
This commit is contained in:
@@ -21,7 +21,7 @@ mkdir -p "${OUT_DIR}"
|
||||
echo
|
||||
|
||||
echo "=== Process Snapshot ==="
|
||||
ps -eo pid,ppid,stat,ni,etime,comm,args | grep -E "(manager.py|selfdrive.ui.ui|/selfdrive/ui/ui|weston|loggerd|encoderd|modeld|dmonitoringmodeld)" || true
|
||||
ps -eo pid,ppid,stat,ni,etime,comm,args | grep -E "(manager.py|selfdrive.ui.ui|/selfdrive/ui/ui.py|weston|loggerd|encoderd|modeld|dmonitoringmodeld)" || true
|
||||
echo
|
||||
|
||||
echo "=== Manager State (tmux service output) ==="
|
||||
@@ -35,7 +35,7 @@ mkdir -p "${OUT_DIR}"
|
||||
echo
|
||||
|
||||
echo "=== UI PID + Watchdog Timestamp Delta ==="
|
||||
for ui_pid in $(pgrep -f "selfdrive.ui.ui|/selfdrive/ui/ui" 2>/dev/null || true); do
|
||||
for ui_pid in $(pgrep -f "selfdrive.ui.ui|/selfdrive/ui/ui.py" 2>/dev/null || true); do
|
||||
echo "ui_pid=${ui_pid}"
|
||||
wd_file="/dev/shm/wd_${ui_pid}"
|
||||
if [[ -f "${wd_file}" ]]; then
|
||||
@@ -74,7 +74,7 @@ PY
|
||||
echo
|
||||
|
||||
echo "=== open files for UI process(es) ==="
|
||||
for ui_pid in $(pgrep -f "selfdrive.ui.ui|/selfdrive/ui/ui" 2>/dev/null || true); do
|
||||
for ui_pid in $(pgrep -f "selfdrive.ui.ui|/selfdrive/ui/ui.py" 2>/dev/null || true); do
|
||||
echo "--- lsof for pid ${ui_pid} ---"
|
||||
lsof -p "${ui_pid}" 2>/dev/null | tail -n 200 || true
|
||||
done
|
||||
|
||||
+14
-38
@@ -24,9 +24,8 @@ Usage:
|
||||
./tools/host <command> [args...]
|
||||
|
||||
Commands:
|
||||
c3 Launch the desktop Qt UI from the isolated host cache.
|
||||
c3 Launch the large raylib UI from the isolated host cache.
|
||||
c4 Launch the small raylib UI from the isolated host cache.
|
||||
raybig Launch the large raylib UI from the isolated host cache.
|
||||
onroad Launch replay plus desktop UI(s) from the isolated host cache.
|
||||
replay Build and run replay from the isolated host cache.
|
||||
cabana Build and run cabana from the isolated host cache.
|
||||
@@ -43,9 +42,8 @@ Notes:
|
||||
- `cabana` uses its own host-runtime bucket, so it can run together with `plotjuggler`.
|
||||
- Other commands that share a bucket still wait on that bucket's lock.
|
||||
- `./build` remains the device-target flow.
|
||||
- For c3/c4/raybig, pass the jobs count first to preserve existing shorthand:
|
||||
- For c3/c4, pass the jobs count first to preserve existing shorthand:
|
||||
./dev c3 8
|
||||
./dev raybig 12
|
||||
- `./onroad --c3 f08912a233c1584f/2022-08-11--18-02-41/1` launches replay plus the selected desktop UI.
|
||||
- `./dev sync` refreshes all host buckets. Use `./dev sync cabana` to sync one.
|
||||
EOF
|
||||
@@ -65,7 +63,7 @@ resolve_host_bucket() {
|
||||
local name="${1:-shared}"
|
||||
|
||||
case "${name}" in
|
||||
shared|default|ui|c3|c4|raybig|onroad|replay|shell)
|
||||
shared|default|ui|c3|c4|onroad|replay|shell)
|
||||
echo "shared"
|
||||
;;
|
||||
cabana)
|
||||
@@ -235,16 +233,13 @@ purge_host_foreign_platform_artifacts() {
|
||||
esac
|
||||
}
|
||||
|
||||
purge_host_desktop_ui_artifacts() {
|
||||
rm -f \
|
||||
"${WORK_DIR}/selfdrive/ui/libqt_widgets.a" \
|
||||
"${WORK_DIR}/selfdrive/ui/libqt_util.a" \
|
||||
"${WORK_DIR}/selfdrive/ui/assets.o" \
|
||||
"${WORK_DIR}/selfdrive/ui/main.o" \
|
||||
"${WORK_DIR}/selfdrive/ui/moc_ui.o" \
|
||||
"${WORK_DIR}/selfdrive/ui/ui.o" \
|
||||
"${WORK_DIR}/selfdrive/ui/ui" \
|
||||
"${WORK_DIR}/cereal/gen/cpp/"*.capnp.o
|
||||
purge_host_generated_objects() {
|
||||
rm -f "${WORK_DIR}/cereal/gen/cpp/"*.capnp.o
|
||||
}
|
||||
|
||||
purge_host_obsolete_ui_artifacts() {
|
||||
find "${WORK_DIR}/selfdrive/ui" -maxdepth 1 -type f \
|
||||
\( -name 'ui' -o -name 'ui.macos' -o -name 'ui.larch64' -o -name '*.o' -o -name '*.a' \) -delete
|
||||
}
|
||||
|
||||
ensure_host_python_tools() {
|
||||
@@ -333,11 +328,6 @@ sync_worktree() {
|
||||
"tools/replay/tests/test_replay"
|
||||
"tools/cabana/cabana"
|
||||
"tools/cabana/tests/test_cabana"
|
||||
"selfdrive/ui/ui"
|
||||
"selfdrive/ui/ui.macos"
|
||||
"selfdrive/ui/ui.larch64"
|
||||
"selfdrive/ui/libqt_widgets.a"
|
||||
"selfdrive/ui/libqt_util.a"
|
||||
"cereal/libcereal.a"
|
||||
"cereal/libsocketmaster.a"
|
||||
"cereal/messaging/bridge"
|
||||
@@ -388,7 +378,8 @@ sync_worktree() {
|
||||
if [[ "${_capnp_before}" != "${_capnp_after}" ]]; then
|
||||
rm -rf "${SP_SCONS_CACHE_DIR:-${HOST_ROOT}/scons_cache}"
|
||||
fi
|
||||
purge_host_desktop_ui_artifacts
|
||||
purge_host_generated_objects
|
||||
purge_host_obsolete_ui_artifacts
|
||||
purge_host_foreign_platform_artifacts
|
||||
rm -f "${WORK_DIR}/third_party/libjson11.a" "${WORK_DIR}/third_party/libkaitai.a"
|
||||
sync_host_generated_headers
|
||||
@@ -478,7 +469,7 @@ launch_c3() {
|
||||
fi
|
||||
|
||||
sync_worktree
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_ui_desktop.sh" "${jobs}" "$@"
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_ui_c3_desktop.sh" "${jobs}" "$@"
|
||||
}
|
||||
|
||||
launch_c4() {
|
||||
@@ -493,18 +484,6 @@ launch_c4() {
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_ui_c4_desktop.sh" "${jobs}" "$@"
|
||||
}
|
||||
|
||||
launch_raybig() {
|
||||
local jobs
|
||||
jobs="$(default_jobs)"
|
||||
if [[ "${1:-}" =~ ^[0-9]+$ ]]; then
|
||||
jobs="$1"
|
||||
shift || true
|
||||
fi
|
||||
|
||||
sync_worktree
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_ui_raybig_desktop.sh" "${jobs}" "$@"
|
||||
}
|
||||
|
||||
launch_onroad() {
|
||||
local jobs
|
||||
jobs="$(default_jobs)"
|
||||
@@ -609,7 +588,7 @@ main() {
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
c3|c4|raybig|onroad|replay|shell|python|pytest)
|
||||
c3|c4|onroad|replay|shell|python|pytest)
|
||||
set_host_bucket "shared"
|
||||
acquire_host_lock "${command} $*"
|
||||
;;
|
||||
@@ -650,9 +629,6 @@ main() {
|
||||
c4)
|
||||
launch_c4 "$@"
|
||||
;;
|
||||
raybig)
|
||||
launch_raybig "$@"
|
||||
;;
|
||||
onroad)
|
||||
launch_onroad "$@"
|
||||
;;
|
||||
|
||||
@@ -527,8 +527,7 @@ manager_artifacts_ready() {
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so" ]] &&
|
||||
[[ -f "${ROOT_DIR}/selfdrive/ui/ui" ]]
|
||||
[[ -f "${ROOT_DIR}/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so" ]]
|
||||
}
|
||||
|
||||
run_manager() {
|
||||
|
||||
@@ -27,24 +27,24 @@ env_var_truthy() {
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./onroad [jobs] [--c3 | --c4 | --raybig | --all | --replay-only] [--galaxy] [-nav] [--offroad] [-alert] [--cem] [--prefix name] <route-or-replay-args...>
|
||||
./onroad [jobs] [--c3 | --c4 | --all | --replay-only] [--galaxy] [-nav] [--offroad] [-alert] [--cem] [--prefix name] <route-or-replay-args...>
|
||||
|
||||
Examples:
|
||||
./onroad <route>
|
||||
./onroad --c3 <route>
|
||||
./onroad --c4 <route> --start 30
|
||||
./onroad --c4 -nav <route>
|
||||
./onroad --raybig --nav --offroad --demo
|
||||
./onroad --c3 --nav --offroad --demo
|
||||
./onroad --c4 --cem --demo
|
||||
./onroad --raybig --cem --demo
|
||||
./onroad --raybig --cem -alert --demo --no-loop
|
||||
./onroad --c3 --cem --demo
|
||||
./onroad --c3 --cem -alert --demo --no-loop
|
||||
./onroad --all <route>
|
||||
./onroad --replay-only --demo --no-vipc --no-loop
|
||||
|
||||
Notes:
|
||||
- This is host/dev only. It uses the isolated host worktree and does not touch the device path.
|
||||
- A private comma connect route still requires tools/lib/auth.py before replay can download it.
|
||||
- If no UI flag is provided, the route's logged device type selects the UI: mici/c4 -> c4, tici/tizi -> raybig unless UseOldUI was enabled.
|
||||
- If no UI flag is provided, the route's logged device type selects the UI: mici/c4 -> c4, all big devices -> c3.
|
||||
- Use multiple UI flags together if you want more than one desktop UI at once.
|
||||
- --galaxy starts a local Galaxy web session with the same preview params and prints the localhost URL. It blocks replay's logged customReserved9 stream so Galaxy can own the live Testing Grounds publisher.
|
||||
- -nav injects a fake navigation demo stream and blocks replay from publishing navInstruction/navRoute.
|
||||
@@ -101,13 +101,8 @@ parse_args() {
|
||||
UI_SELECTION_EXPLICIT=1
|
||||
shift
|
||||
;;
|
||||
--raybig)
|
||||
UI_TARGETS+=(raybig)
|
||||
UI_SELECTION_EXPLICIT=1
|
||||
shift
|
||||
;;
|
||||
--all)
|
||||
UI_TARGETS+=(c3 c4 raybig)
|
||||
UI_TARGETS+=(c3 c4)
|
||||
UI_SELECTION_EXPLICIT=1
|
||||
shift
|
||||
;;
|
||||
@@ -183,7 +178,7 @@ expand_ui_targets() {
|
||||
|
||||
case "${selection,,}" in
|
||||
all|"")
|
||||
UI_TARGETS=(c3 c4 raybig)
|
||||
UI_TARGETS=(c3 c4)
|
||||
return
|
||||
;;
|
||||
none)
|
||||
@@ -199,18 +194,18 @@ expand_ui_targets() {
|
||||
local raw=""
|
||||
for raw in "${raw_targets[@]}"; do
|
||||
case "${raw,,}" in
|
||||
c3|c4|raybig)
|
||||
c3|c4)
|
||||
normalized+=("${raw,,}")
|
||||
;;
|
||||
*)
|
||||
echo "Unknown UI target in --ui: ${raw}" >&2
|
||||
echo "Valid values: all, none, c3, c4, raybig" >&2
|
||||
echo "Valid values: all, none, c3, c4" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local ordered_targets=(c3 c4 raybig)
|
||||
local ordered_targets=(c3 c4)
|
||||
local target=""
|
||||
for target in "${ordered_targets[@]}"; do
|
||||
local candidate=""
|
||||
@@ -224,7 +219,7 @@ expand_ui_targets() {
|
||||
}
|
||||
|
||||
dedupe_ui_targets() {
|
||||
local ordered_targets=(c3 c4 raybig)
|
||||
local ordered_targets=(c3 c4)
|
||||
local deduped=()
|
||||
local target=""
|
||||
for target in "${ordered_targets[@]}"; do
|
||||
@@ -402,7 +397,6 @@ prepare_env() {
|
||||
export USE_WEBCAM=1
|
||||
export SP_C3_FAKE_WIFI=0
|
||||
export SP_C4_FAKE_WIFI=0
|
||||
export SP_RAYBIG_FAKE_WIFI=0
|
||||
export SP_ALLOW_DESKTOP_FAKE_WIFI=0
|
||||
export SP_ONROAD_NAV_DEMO="${NAV_DEMO}"
|
||||
export SP_ONROAD_OFFROAD_DEMO="${OFFROAD_DEMO}"
|
||||
@@ -448,7 +442,7 @@ build_replay() {
|
||||
}
|
||||
|
||||
prepare_c3_runtime() {
|
||||
SP_C3_COMPILE_ONLY=1 "${ROOT_DIR}/scripts/launch_ui_desktop.sh" "${jobs}"
|
||||
SP_KEEP_DESKTOP_RUNTIME_ARTIFACTS=1 SP_C3_COMPILE_ONLY=1 "${ROOT_DIR}/scripts/launch_ui_c3_desktop.sh" "${jobs}"
|
||||
}
|
||||
|
||||
prepare_python_ui_runtime() {
|
||||
@@ -589,22 +583,6 @@ launch_galaxy() {
|
||||
echo "Access Galaxy with ${GALAXY_URL}"
|
||||
}
|
||||
|
||||
launch_c3_ui() {
|
||||
local os_ext="linux"
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
os_ext="macos"
|
||||
fi
|
||||
|
||||
local host_ui="${ROOT_DIR}/selfdrive/ui/ui.${os_ext}"
|
||||
if [[ ! -x "${host_ui}" ]]; then
|
||||
echo "Missing ${host_ui}. C3 build did not produce the desktop binary." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
"${host_ui}" &
|
||||
UI_PIDS+=("$!")
|
||||
}
|
||||
|
||||
launch_python_ui() {
|
||||
local big="$1"
|
||||
(
|
||||
@@ -680,7 +658,7 @@ if [[ "${REPLAY_ONLY}" != "1" && "${UI_SELECTION_EXPLICIT}" == "0" && ${#UI_TARG
|
||||
fi
|
||||
|
||||
if [[ "${REPLAY_ONLY}" != "1" && ${#UI_TARGETS[@]} -eq 0 ]]; then
|
||||
echo "Select at least one UI with --c3, --c4, --raybig, or use --replay-only." >&2
|
||||
echo "Select at least one UI with --c3, --c4, or use --replay-only." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -695,7 +673,7 @@ case " ${UI_TARGETS[*]-} " in
|
||||
esac
|
||||
|
||||
case " ${UI_TARGETS[*]-} " in
|
||||
*" c4 "*|*" raybig "*)
|
||||
*" c4 "*)
|
||||
prepare_python_ui_runtime
|
||||
;;
|
||||
esac
|
||||
@@ -739,16 +717,13 @@ has_raylib=0
|
||||
for local_target in "${UI_TARGETS[@]}"; do
|
||||
case "${local_target}" in
|
||||
c3)
|
||||
launch_c3_ui
|
||||
launch_python_ui 1
|
||||
has_raylib=1
|
||||
;;
|
||||
c4)
|
||||
launch_python_ui 0
|
||||
has_raylib=1
|
||||
;;
|
||||
raybig)
|
||||
launch_python_ui 1
|
||||
has_raylib=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
@@ -47,19 +47,19 @@ export PATH="${ROOT_DIR}/.venv/bin:${PATH}"
|
||||
export PYTHONPATH="${ROOT_DIR}:${ROOT_DIR}/starpilot/third_party"
|
||||
for d in "${ROOT_DIR}"/*_repo; do [[ -d "$d" ]] && export PYTHONPATH="${PYTHONPATH}:$d"; done
|
||||
[[ -d "${ROOT_DIR}/third_party/acados" ]] && export PYTHONPATH="${PYTHONPATH}:${ROOT_DIR}/third_party/acados"
|
||||
export OPENPILOT_ZMQ_NAMESPACE="${OPENPILOT_ZMQ_NAMESPACE:-desktop-raybig-$$}"
|
||||
export OPENPILOT_ZMQ_NAMESPACE="${OPENPILOT_ZMQ_NAMESPACE:-desktop-c3-$$}"
|
||||
export BIG=1
|
||||
export NOBOARD=1
|
||||
export SIMULATION=1
|
||||
export SKIP_FW_QUERY=1
|
||||
export USE_WEBCAM=1
|
||||
export PRIME_TYPE="${PRIME_TYPE:-0}"
|
||||
export SP_RAYBIG_FAKE_DRIVE_STATS="${SP_RAYBIG_FAKE_DRIVE_STATS:-1}"
|
||||
export SP_C3_FAKE_DRIVE_STATS="${SP_C3_FAKE_DRIVE_STATS:-1}"
|
||||
|
||||
backup_dir="$(mktemp -d /tmp/starpilot_raybig_ui_backup.XXXXXX)"
|
||||
backup_dir="$(mktemp -d /tmp/starpilot_c3_ui_backup.XXXXXX)"
|
||||
backup_manifest="${backup_dir}/.artifact_manifest"
|
||||
PRE_TRACKED_DIRTY="$(mktemp /tmp/starpilot_raybig_pretracked.XXXXXX)"
|
||||
POST_TRACKED_DIRTY="$(mktemp /tmp/starpilot_raybig_posttracked.XXXXXX)"
|
||||
PRE_TRACKED_DIRTY="$(mktemp /tmp/starpilot_c3_pretracked.XXXXXX)"
|
||||
POST_TRACKED_DIRTY="$(mktemp /tmp/starpilot_c3_posttracked.XXXXXX)"
|
||||
FAKE_WIFI_PID=""
|
||||
|
||||
runtime_artifacts=(
|
||||
@@ -175,7 +175,7 @@ prepare_common_host_artifacts() {
|
||||
|
||||
prepare_msgq_host_artifacts() {
|
||||
# Clear mixed-arch Python extension objects from both msgq trees. These
|
||||
# commonly conflict after switching between ./build (larch64) and ./raybig (macOS).
|
||||
# commonly conflict after switching between ./build (larch64) and ./c3 (macOS).
|
||||
remove_if_elf "msgq/ipc_pyx.o"
|
||||
remove_if_elf "msgq/visionipc/visionipc_pyx.o"
|
||||
remove_if_elf "msgq_repo/msgq/ipc_pyx.o"
|
||||
@@ -268,12 +268,12 @@ run_scons() {
|
||||
fi
|
||||
}
|
||||
|
||||
kill_stale_raybig_ui() {
|
||||
kill_stale_c3_ui() {
|
||||
pkill -f "selfdrive/ui/ui.py" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
start_fake_wifi() {
|
||||
if [[ ! "${SP_RAYBIG_FAKE_WIFI:-1}" =~ ^(1|true|yes|on)$ ]]; then
|
||||
if [[ ! "${SP_C3_FAKE_WIFI:-1}" =~ ^(1|true|yes|on)$ ]]; then
|
||||
export SP_ALLOW_DESKTOP_FAKE_WIFI=0
|
||||
return
|
||||
fi
|
||||
@@ -339,8 +339,8 @@ PY
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${SP_RAYBIG_COMPILE_ONLY:-0}" == "1" ]]; then
|
||||
echo "Raybig runtime artifacts prepared."
|
||||
if [[ "${SP_C3_COMPILE_ONLY:-0}" == "1" ]]; then
|
||||
echo "C3 runtime artifacts prepared."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -356,6 +356,6 @@ params.put_bool("IsDriverViewEnabled", False)
|
||||
PY
|
||||
|
||||
seed_starpilot_theme
|
||||
kill_stale_raybig_ui
|
||||
kill_stale_c3_ui
|
||||
start_fake_wifi
|
||||
"${PY_BIN}" selfdrive/ui/ui.py "$@"
|
||||
@@ -1,265 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
if [[ ! -f .venv/bin/activate ]]; then
|
||||
echo "Missing .venv. Run tools/install_python_dependencies.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
default_jobs() {
|
||||
if command -v nproc >/dev/null 2>&1; then
|
||||
nproc
|
||||
elif command -v sysctl >/dev/null 2>&1; then
|
||||
sysctl -n hw.ncpu
|
||||
else
|
||||
echo 8
|
||||
fi
|
||||
}
|
||||
|
||||
jobs="$(default_jobs)"
|
||||
if [[ "${1:-}" =~ ^[0-9]+$ ]]; then
|
||||
jobs="$1"
|
||||
shift || true
|
||||
fi
|
||||
|
||||
OS_EXT="linux"
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
OS_EXT="macos"
|
||||
fi
|
||||
HOST_UI="${ROOT_DIR}/selfdrive/ui/ui.${OS_EXT}"
|
||||
PRE_TRACKED_DIRTY="$(mktemp /tmp/starpilot_c3_pretracked.XXXXXX)"
|
||||
POST_TRACKED_DIRTY="$(mktemp /tmp/starpilot_c3_posttracked.XXXXXX)"
|
||||
BACKUP_DIR="$(mktemp -d /tmp/starpilot_c3_backup.XXXXXX)"
|
||||
BACKUP_MANIFEST="${BACKUP_DIR}/.artifact_manifest"
|
||||
FAKE_WIFI_PID=""
|
||||
|
||||
runtime_artifacts=(
|
||||
"selfdrive/ui/ui"
|
||||
"common/libcommon.a"
|
||||
"common/transformations/libtransformations.a"
|
||||
"cereal/libsocketmaster.a"
|
||||
"msgq_repo/libmsgq.a"
|
||||
"msgq_repo/libvisionipc.a"
|
||||
"common/params_pyx.so"
|
||||
"common/transformations/transformations.so"
|
||||
"msgq_repo/msgq/ipc_pyx.so"
|
||||
"msgq_repo/msgq/visionipc/visionipc_pyx.so"
|
||||
)
|
||||
|
||||
collect_tracked_dirty() {
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
if ! git -C "${ROOT_DIR}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
git -C "${ROOT_DIR}" status --porcelain --untracked-files=no | sed -E 's/^.. //'
|
||||
}
|
||||
|
||||
backup_artifact() {
|
||||
local rel="$1"
|
||||
local src="${ROOT_DIR}/${rel}"
|
||||
echo "${rel}" >> "${BACKUP_MANIFEST}"
|
||||
if [[ -f "${src}" ]]; then
|
||||
mkdir -p "${BACKUP_DIR}/$(dirname "${rel}")"
|
||||
cp -f "${src}" "${BACKUP_DIR}/${rel}"
|
||||
fi
|
||||
}
|
||||
|
||||
restore_runtime_artifacts() {
|
||||
if [[ ! -d "${BACKUP_DIR}" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -f "${BACKUP_MANIFEST}" ]]; then
|
||||
while IFS= read -r rel; do
|
||||
[[ -z "${rel}" ]] && continue
|
||||
if [[ -f "${BACKUP_DIR}/${rel}" ]]; then
|
||||
cp -f "${BACKUP_DIR}/${rel}" "${ROOT_DIR}/${rel}"
|
||||
else
|
||||
rm -f "${ROOT_DIR}/${rel}"
|
||||
fi
|
||||
done < "${BACKUP_MANIFEST}"
|
||||
fi
|
||||
|
||||
rm -rf "${BACKUP_DIR}"
|
||||
}
|
||||
|
||||
restore_new_tracked_changes() {
|
||||
if ! collect_tracked_dirty > "${POST_TRACKED_DIRTY}"; then
|
||||
return
|
||||
fi
|
||||
|
||||
while IFS= read -r path; do
|
||||
[[ -z "${path}" ]] && continue
|
||||
if ! grep -Fxq "${path}" "${PRE_TRACKED_DIRTY}"; then
|
||||
git -C "${ROOT_DIR}" checkout -- "${path}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done < "${POST_TRACKED_DIRTY}"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
restore_runtime_artifacts
|
||||
restore_new_tracked_changes
|
||||
stop_fake_wifi
|
||||
rm -f "${PRE_TRACKED_DIRTY}" "${POST_TRACKED_DIRTY}"
|
||||
}
|
||||
|
||||
start_fake_wifi() {
|
||||
if [[ ! "${SP_C3_FAKE_WIFI:-1}" =~ ^(1|true|yes|on)$ ]]; then
|
||||
export SP_ALLOW_DESKTOP_FAKE_WIFI=0
|
||||
return
|
||||
fi
|
||||
|
||||
export SP_ALLOW_DESKTOP_FAKE_WIFI=1
|
||||
"${ROOT_DIR}/.venv/bin/python3" selfdrive/debug/fake_wifi.py --network wifi --strength great --interval 0.2 &
|
||||
FAKE_WIFI_PID=$!
|
||||
}
|
||||
|
||||
seed_starpilot_theme() {
|
||||
"${ROOT_DIR}/.venv/bin/python3" - <<'PY'
|
||||
from openpilot.starpilot.common.starpilot_functions import seed_desktop_theme_assets
|
||||
|
||||
seed_desktop_theme_assets()
|
||||
PY
|
||||
}
|
||||
|
||||
starpilot_theme_runtime_ok() {
|
||||
"${ROOT_DIR}/.venv/bin/python3" - <<'PY'
|
||||
import openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
import openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx # noqa: F401
|
||||
PY
|
||||
}
|
||||
|
||||
ensure_starpilot_theme_runtime() {
|
||||
if starpilot_theme_runtime_ok >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Preparing C3 StarPilot theme runtime extensions..."
|
||||
remove_if_elf "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
remove_if_elf "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so"
|
||||
scons -j"${jobs}" \
|
||||
selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so \
|
||||
selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so
|
||||
}
|
||||
|
||||
stop_fake_wifi() {
|
||||
if [[ -n "${FAKE_WIFI_PID}" ]]; then
|
||||
kill "${FAKE_WIFI_PID}" >/dev/null 2>&1 || true
|
||||
FAKE_WIFI_PID=""
|
||||
fi
|
||||
}
|
||||
|
||||
archive_is_aarch64_elf() {
|
||||
local path="$1"
|
||||
[[ -f "${path}" ]] || return 1
|
||||
if command -v readelf >/dev/null 2>&1; then
|
||||
readelf -h "${path}" 2>/dev/null | grep -iq "aarch64"
|
||||
else
|
||||
objdump -a "${path}" 2>/dev/null | head -n 12 | grep -iqE "elf64-littleaarch64|aarch64"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_if_elf() {
|
||||
local rel="$1"
|
||||
local path="${ROOT_DIR}/${rel}"
|
||||
if [[ -f "${path}" ]] && file "${path}" | grep -q "ELF"; then
|
||||
rm -f "${path}"
|
||||
fi
|
||||
}
|
||||
|
||||
purge_objects() {
|
||||
local root="$1"
|
||||
if [[ -d "${root}" ]]; then
|
||||
find "${root}" -type f \( -name '*.o' -o -name '*.os' \) -delete
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_host_artifacts() {
|
||||
if archive_is_aarch64_elf "${ROOT_DIR}/common/libcommon.a"; then
|
||||
rm -f "${ROOT_DIR}/common/libcommon.a" "${ROOT_DIR}/common/params_pyx.o"
|
||||
purge_objects "${ROOT_DIR}/common"
|
||||
fi
|
||||
|
||||
if archive_is_aarch64_elf "${ROOT_DIR}/cereal/libsocketmaster.a"; then
|
||||
rm -f "${ROOT_DIR}/cereal/libsocketmaster.a"
|
||||
purge_objects "${ROOT_DIR}/cereal/messaging"
|
||||
fi
|
||||
|
||||
if archive_is_aarch64_elf "${ROOT_DIR}/common/transformations/libtransformations.a"; then
|
||||
rm -f "${ROOT_DIR}/common/transformations/libtransformations.a" \
|
||||
"${ROOT_DIR}/common/transformations/transformations.o"
|
||||
purge_objects "${ROOT_DIR}/common/transformations"
|
||||
fi
|
||||
|
||||
if archive_is_aarch64_elf "${ROOT_DIR}/msgq_repo/libmsgq.a" || archive_is_aarch64_elf "${ROOT_DIR}/msgq_repo/libvisionipc.a"; then
|
||||
rm -f "${ROOT_DIR}/msgq_repo/libmsgq.a" "${ROOT_DIR}/msgq_repo/libvisionipc.a"
|
||||
purge_objects "${ROOT_DIR}/msgq_repo/msgq"
|
||||
purge_objects "${ROOT_DIR}/msgq_repo/msgq/visionipc"
|
||||
fi
|
||||
|
||||
remove_if_elf "common/params_pyx.so"
|
||||
remove_if_elf "common/transformations/transformations.so"
|
||||
remove_if_elf "msgq_repo/msgq/ipc_pyx.so"
|
||||
remove_if_elf "msgq_repo/msgq/visionipc/visionipc_pyx.so"
|
||||
|
||||
purge_objects "${ROOT_DIR}/selfdrive/ui"
|
||||
purge_objects "${ROOT_DIR}/starpilot/ui"
|
||||
rm -f "${ROOT_DIR}/selfdrive/ui/libqt_widgets.a" "${ROOT_DIR}/selfdrive/ui/libqt_util.a"
|
||||
rm -f "${ROOT_DIR}/selfdrive/ui/ui"
|
||||
}
|
||||
|
||||
collect_tracked_dirty > "${PRE_TRACKED_DIRTY}" || true
|
||||
trap cleanup EXIT
|
||||
|
||||
for rel in "${runtime_artifacts[@]}"; do
|
||||
backup_artifact "${rel}"
|
||||
done
|
||||
|
||||
source .venv/bin/activate
|
||||
if [[ -d /opt/homebrew/bin ]]; then
|
||||
export PATH="/opt/homebrew/bin:${PATH}"
|
||||
fi
|
||||
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
# Keep desktop host builds on Apple toolchain even if shell exports Homebrew llvm.
|
||||
export CC="/usr/bin/clang"
|
||||
export CXX="/usr/bin/clang++"
|
||||
export AR="/usr/bin/ar"
|
||||
export RANLIB="/usr/bin/ranlib"
|
||||
fi
|
||||
unset CPATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
|
||||
|
||||
prepare_host_artifacts
|
||||
|
||||
export PYTHONPATH="${ROOT_DIR}:${ROOT_DIR}/starpilot/third_party"
|
||||
for d in "${ROOT_DIR}"/*_repo; do [[ -d "$d" ]] && export PYTHONPATH="${PYTHONPATH}:$d"; done
|
||||
[[ -d "${ROOT_DIR}/third_party/acados" ]] && export PYTHONPATH="${PYTHONPATH}:${ROOT_DIR}/third_party/acados"
|
||||
export OPENPILOT_ZMQ_NAMESPACE="${OPENPILOT_ZMQ_NAMESPACE:-desktop-c3-$$}"
|
||||
|
||||
export SP_DISABLE_AUTO_DEVICE_SCONS=1
|
||||
scons -j"${jobs}" selfdrive/ui/ui
|
||||
|
||||
cp -f "${ROOT_DIR}/selfdrive/ui/ui" "${HOST_UI}"
|
||||
cleanup
|
||||
trap - EXIT
|
||||
|
||||
if [[ "${SP_C3_COMPILE_ONLY:-0}" == "1" ]]; then
|
||||
echo "C3 UI binary prepared."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ensure_starpilot_theme_runtime
|
||||
seed_starpilot_theme
|
||||
start_fake_wifi
|
||||
trap stop_fake_wifi EXIT
|
||||
"${HOST_UI}" "$@"
|
||||
rc=$?
|
||||
stop_fake_wifi
|
||||
trap - EXIT
|
||||
exit "${rc}"
|
||||
@@ -9,14 +9,14 @@ usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
scripts/starpilot_build_flow.sh verify
|
||||
scripts/starpilot_build_flow.sh mac [jobs]
|
||||
scripts/starpilot_build_flow.sh mac
|
||||
scripts/starpilot_build_flow.sh device [jobs]
|
||||
scripts/starpilot_build_flow.sh laptop-setup [device-host]
|
||||
scripts/starpilot_build_flow.sh laptop-device [jobs]
|
||||
|
||||
Modes:
|
||||
verify Check critical StarPilot parity build guards in-tree.
|
||||
mac Run macOS developer validation build (Qt UI + Python compile checks).
|
||||
mac Run macOS developer Python validation checks.
|
||||
device Run full on-device build (comma hardware only) and set prebuilt flag.
|
||||
laptop-setup Prepare laptop device-build environment (venv + image + sysroot).
|
||||
laptop-device Run full device-target build in Linux/aarch64 container on laptop.
|
||||
@@ -61,20 +61,6 @@ verify_tree() {
|
||||
echo "OK: timed.py guards timezonefinder usage."
|
||||
fi
|
||||
|
||||
if ! rg -q "if os.path.isfile\\(\"/TICI\"\\)" common/spinner.py; then
|
||||
echo "FAIL: common/spinner.py missing device-only legacy spinner path."
|
||||
failed=1
|
||||
else
|
||||
echo "OK: spinner uses device-only legacy fallback."
|
||||
fi
|
||||
|
||||
if ! rg -q "if os.path.isfile\\(\"/TICI\"\\)" common/text_window.py; then
|
||||
echo "FAIL: common/text_window.py missing device-only legacy text path."
|
||||
failed=1
|
||||
else
|
||||
echo "OK: text window uses device-only legacy fallback."
|
||||
fi
|
||||
|
||||
if ! source .venv/bin/activate >/dev/null 2>&1; then
|
||||
echo "FAIL: .venv is required for loggerd import checks."
|
||||
failed=1
|
||||
@@ -107,7 +93,6 @@ PY
|
||||
}
|
||||
|
||||
build_mac() {
|
||||
local jobs="${1:-8}"
|
||||
require_venv
|
||||
source .venv/bin/activate
|
||||
|
||||
@@ -129,8 +114,6 @@ build_mac() {
|
||||
starpilot/system/the_galaxy \
|
||||
starpilot/system/galaxy
|
||||
|
||||
SP_DISABLE_AUTO_DEVICE_SCONS=1 scons -j"${jobs}" selfdrive/ui/ui
|
||||
|
||||
echo "mac build validation complete."
|
||||
}
|
||||
|
||||
@@ -166,7 +149,7 @@ main() {
|
||||
verify_tree
|
||||
;;
|
||||
mac)
|
||||
build_mac "${1:-8}"
|
||||
build_mac
|
||||
;;
|
||||
device)
|
||||
build_device "${1:-$(nproc)}"
|
||||
|
||||
Reference in New Issue
Block a user