mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-08 08:34:49 +08:00
./onroad
This commit is contained in:
6
onroad
Executable file
6
onroad
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
exec "${ROOT_DIR}/scripts/host_tool_runner.sh" onroad "$@"
|
||||
@@ -27,6 +27,7 @@ Commands:
|
||||
c3 Launch the desktop Qt 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.
|
||||
plotjuggler Run PlotJuggler helper from the isolated host cache.
|
||||
@@ -43,6 +44,7 @@ Notes:
|
||||
- For c3/c4/raybig, 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
|
||||
}
|
||||
@@ -61,7 +63,7 @@ resolve_host_bucket() {
|
||||
local name="${1:-shared}"
|
||||
|
||||
case "${name}" in
|
||||
shared|default|ui|c3|c4|raybig|replay|shell)
|
||||
shared|default|ui|c3|c4|raybig|onroad|replay|shell)
|
||||
echo "shared"
|
||||
;;
|
||||
cabana)
|
||||
@@ -212,6 +214,17 @@ purge_host_python_artifacts() {
|
||||
"${WORK_DIR}/msgq_repo/msgq/visionipc/visionipc_pyx.cpp"
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
ensure_host_python_tools() {
|
||||
ensure_venv
|
||||
|
||||
@@ -237,6 +250,22 @@ ensure_host_python_tools() {
|
||||
)
|
||||
}
|
||||
|
||||
sync_host_generated_headers() {
|
||||
if ! command -v capnpc >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
|
||||
(
|
||||
cd "${WORK_DIR}"
|
||||
capnpc --src-prefix=cereal \
|
||||
cereal/log.capnp \
|
||||
cereal/car.capnp \
|
||||
cereal/legacy.capnp \
|
||||
cereal/custom.capnp \
|
||||
-o c++:cereal/gen/cpp/
|
||||
)
|
||||
}
|
||||
|
||||
sync_worktree() {
|
||||
ensure_venv
|
||||
|
||||
@@ -264,6 +293,8 @@ sync_worktree() {
|
||||
"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"
|
||||
@@ -294,7 +325,9 @@ sync_worktree() {
|
||||
done
|
||||
|
||||
rsync "${rsync_args[@]}" "${ROOT_DIR}/" "${WORK_DIR}/"
|
||||
purge_host_desktop_ui_artifacts
|
||||
rm -f "${WORK_DIR}/third_party/libjson11.a" "${WORK_DIR}/third_party/libkaitai.a"
|
||||
sync_host_generated_headers
|
||||
ensure_host_python_tools
|
||||
rm -rf "${WORK_DIR}/.venv"
|
||||
ln -s "${HOST_VENV}" "${WORK_DIR}/.venv"
|
||||
@@ -396,6 +429,18 @@ launch_raybig() {
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_ui_raybig_desktop.sh" "${jobs}" "$@"
|
||||
}
|
||||
|
||||
launch_onroad() {
|
||||
local jobs
|
||||
jobs="$(default_jobs)"
|
||||
if [[ "${1:-}" =~ ^[0-9]+$ ]]; then
|
||||
jobs="$1"
|
||||
shift || true
|
||||
fi
|
||||
|
||||
sync_worktree
|
||||
run_in_worktree "${WORK_DIR}/scripts/launch_onroad_desktop.sh" "${jobs}" "$@"
|
||||
}
|
||||
|
||||
launch_replay() {
|
||||
local jobs
|
||||
jobs="$(default_jobs)"
|
||||
@@ -473,7 +518,7 @@ main() {
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
c3|c4|raybig|replay|shell)
|
||||
c3|c4|raybig|onroad|replay|shell)
|
||||
set_host_bucket "shared"
|
||||
acquire_host_lock "${command} $*"
|
||||
;;
|
||||
@@ -517,6 +562,9 @@ main() {
|
||||
raybig)
|
||||
launch_raybig "$@"
|
||||
;;
|
||||
onroad)
|
||||
launch_onroad "$@"
|
||||
;;
|
||||
replay)
|
||||
launch_replay "$@"
|
||||
;;
|
||||
|
||||
386
scripts/launch_onroad_desktop.sh
Executable file
386
scripts/launch_onroad_desktop.sh
Executable file
@@ -0,0 +1,386 @@
|
||||
#!/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
|
||||
}
|
||||
|
||||
env_var_truthy() {
|
||||
[[ "${1:-}" =~ ^(1|true|yes|on)$ ]]
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./onroad [jobs] (--c3 | --c4 | --raybig | --all | --replay-only) [--prefix name] <route-or-replay-args...>
|
||||
|
||||
Examples:
|
||||
./onroad --c3 f08912a233c1584f/2022-08-11--18-02-41/1
|
||||
./onroad --c4 f08912a233c1584f/2022-08-11--18-02-41/1 --start 30
|
||||
./onroad --all f08912a233c1584f/2022-08-11--18-02-41/1
|
||||
./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.
|
||||
- Use multiple UI flags together if you want more than one desktop UI at once.
|
||||
EOF
|
||||
}
|
||||
|
||||
jobs="$(default_jobs)"
|
||||
if [[ "${1:-}" =~ ^[0-9]+$ ]]; then
|
||||
jobs="$1"
|
||||
shift || true
|
||||
fi
|
||||
|
||||
PREFIX_ARG=""
|
||||
REPLAY_ARGS=()
|
||||
UI_TARGETS=()
|
||||
LEGACY_UI_SELECTION=""
|
||||
REPLAY_ONLY=0
|
||||
REPLAY_PID=""
|
||||
UI_PIDS=()
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--c3)
|
||||
UI_TARGETS+=(c3)
|
||||
shift
|
||||
;;
|
||||
--c4)
|
||||
UI_TARGETS+=(c4)
|
||||
shift
|
||||
;;
|
||||
--raybig)
|
||||
UI_TARGETS+=(raybig)
|
||||
shift
|
||||
;;
|
||||
--all)
|
||||
UI_TARGETS+=(c3 c4 raybig)
|
||||
shift
|
||||
;;
|
||||
--replay-only)
|
||||
REPLAY_ONLY=1
|
||||
shift
|
||||
;;
|
||||
--ui)
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Missing value for --ui" >&2
|
||||
exit 1
|
||||
fi
|
||||
LEGACY_UI_SELECTION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--ui=*)
|
||||
LEGACY_UI_SELECTION="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
-p|--prefix)
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Missing value for $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
PREFIX_ARG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prefix=*)
|
||||
PREFIX_ARG="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
REPLAY_ARGS+=("$@")
|
||||
break
|
||||
;;
|
||||
*)
|
||||
REPLAY_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
expand_ui_targets() {
|
||||
local selection="${1// /}"
|
||||
|
||||
case "${selection,,}" in
|
||||
all|"")
|
||||
UI_TARGETS=(c3 c4 raybig)
|
||||
return
|
||||
;;
|
||||
none)
|
||||
UI_TARGETS=()
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
local raw_targets=()
|
||||
IFS=',' read -r -a raw_targets <<< "${selection}"
|
||||
|
||||
local normalized=()
|
||||
local raw=""
|
||||
for raw in "${raw_targets[@]}"; do
|
||||
case "${raw,,}" in
|
||||
c3|c4|raybig)
|
||||
normalized+=("${raw,,}")
|
||||
;;
|
||||
*)
|
||||
echo "Unknown UI target in --ui: ${raw}" >&2
|
||||
echo "Valid values: all, none, c3, c4, raybig" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local ordered_targets=(c3 c4 raybig)
|
||||
local target=""
|
||||
for target in "${ordered_targets[@]}"; do
|
||||
local candidate=""
|
||||
for candidate in "${normalized[@]}"; do
|
||||
if [[ "${candidate}" == "${target}" ]]; then
|
||||
UI_TARGETS+=("${target}")
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
dedupe_ui_targets() {
|
||||
local ordered_targets=(c3 c4 raybig)
|
||||
local deduped=()
|
||||
local target=""
|
||||
for target in "${ordered_targets[@]}"; do
|
||||
local candidate=""
|
||||
for candidate in "${UI_TARGETS[@]-}"; do
|
||||
if [[ "${candidate}" == "${target}" ]]; then
|
||||
deduped+=("${target}")
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
UI_TARGETS=("${deduped[@]-}")
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
trap - EXIT INT TERM
|
||||
|
||||
local pid=""
|
||||
for pid in "${UI_PIDS[@]-}"; do
|
||||
if [[ -n "${pid}" ]]; then
|
||||
kill "${pid}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
if [[ -n "${REPLAY_PID}" ]]; then
|
||||
kill "${REPLAY_PID}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
for pid in "${UI_PIDS[@]-}"; do
|
||||
if [[ -n "${pid}" ]]; then
|
||||
wait "${pid}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
if [[ -n "${REPLAY_PID}" ]]; then
|
||||
wait "${REPLAY_PID}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
prepare_env() {
|
||||
source .venv/bin/activate
|
||||
|
||||
if [[ -d /opt/homebrew/bin ]]; then
|
||||
export PATH="/opt/homebrew/bin:${PATH}"
|
||||
fi
|
||||
|
||||
export PATH="${ROOT_DIR}/.venv/bin:${PATH}"
|
||||
export PYTHONPATH="${ROOT_DIR}:${ROOT_DIR}/starpilot/third_party"
|
||||
local repo_dir=""
|
||||
for repo_dir in "${ROOT_DIR}"/*_repo; do
|
||||
[[ -d "${repo_dir}" ]] && export PYTHONPATH="${PYTHONPATH}:${repo_dir}"
|
||||
done
|
||||
[[ -d "${ROOT_DIR}/third_party/acados" ]] && export PYTHONPATH="${PYTHONPATH}:${ROOT_DIR}/third_party/acados"
|
||||
|
||||
export BASEDIR="${ROOT_DIR}"
|
||||
export NOBOARD=1
|
||||
export SIMULATION=1
|
||||
export SKIP_FW_QUERY=1
|
||||
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
|
||||
|
||||
if [[ "$(uname -s)" == "Darwin" ]] || env_var_truthy "${ZMQ:-0}"; then
|
||||
if [[ -n "${PREFIX_ARG}" || -n "${OPENPILOT_PREFIX:-}" ]]; then
|
||||
echo "Ignoring OPENPILOT_PREFIX because the ZMQ backend does not support prefixes." >&2
|
||||
fi
|
||||
unset OPENPILOT_PREFIX
|
||||
else
|
||||
export OPENPILOT_PREFIX="${PREFIX_ARG:-${OPENPILOT_PREFIX:-desktop-onroad-$$}}"
|
||||
fi
|
||||
}
|
||||
|
||||
seed_params() {
|
||||
"${ROOT_DIR}/.venv/bin/python3" - <<'PY'
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.version import terms_version, training_version
|
||||
|
||||
params = Params()
|
||||
params.put("HasAcceptedTerms", terms_version)
|
||||
params.put("CompletedTrainingVersion", training_version)
|
||||
params.put_bool("OpenpilotEnabledToggle", True)
|
||||
params.put_bool("IsDriverViewEnabled", False)
|
||||
params.put_bool("ForceOnroad", False)
|
||||
params.put_bool("ForceOffroad", False)
|
||||
PY
|
||||
}
|
||||
|
||||
build_replay() {
|
||||
SP_DISABLE_AUTO_DEVICE_SCONS=1 "${ROOT_DIR}/.venv/bin/scons" --extras -j"${jobs}" tools/replay/replay
|
||||
}
|
||||
|
||||
prepare_c3_runtime() {
|
||||
SP_C3_COMPILE_ONLY=1 "${ROOT_DIR}/scripts/launch_ui_desktop.sh" "${jobs}"
|
||||
}
|
||||
|
||||
prepare_python_ui_runtime() {
|
||||
SP_KEEP_DESKTOP_RUNTIME_ARTIFACTS=1 SP_C4_COMPILE_ONLY=1 "${ROOT_DIR}/scripts/launch_ui_c4_desktop.sh" "${jobs}"
|
||||
}
|
||||
|
||||
launch_replay() {
|
||||
local replay_cmd=(
|
||||
"${ROOT_DIR}/tools/replay/replay"
|
||||
--headless
|
||||
--dcam
|
||||
--ecam
|
||||
)
|
||||
replay_cmd+=("${REPLAY_ARGS[@]}")
|
||||
|
||||
"${replay_cmd[@]}" &
|
||||
REPLAY_PID=$!
|
||||
|
||||
sleep 1
|
||||
if ! kill -0 "${REPLAY_PID}" >/dev/null 2>&1; then
|
||||
wait "${REPLAY_PID}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
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"
|
||||
(
|
||||
export BIG="${big}"
|
||||
exec "${ROOT_DIR}/.venv/bin/python3" "${ROOT_DIR}/selfdrive/ui/ui.py"
|
||||
) &
|
||||
UI_PIDS+=("$!")
|
||||
}
|
||||
|
||||
parse_args "$@"
|
||||
|
||||
if [[ -n "${LEGACY_UI_SELECTION}" ]]; then
|
||||
expand_ui_targets "${LEGACY_UI_SELECTION}"
|
||||
fi
|
||||
|
||||
if [[ "${REPLAY_ONLY}" == "1" ]]; then
|
||||
UI_TARGETS=()
|
||||
else
|
||||
dedupe_ui_targets
|
||||
fi
|
||||
|
||||
if [[ ${#REPLAY_ARGS[@]} -eq 0 ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
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
|
||||
exit 1
|
||||
fi
|
||||
|
||||
prepare_env
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "Using OPENPILOT_PREFIX=${OPENPILOT_PREFIX:-<default>}"
|
||||
echo "Preparing replay and desktop UI runtime..."
|
||||
|
||||
build_replay
|
||||
|
||||
case " ${UI_TARGETS[*]-} " in
|
||||
*" c3 "*)
|
||||
prepare_c3_runtime
|
||||
;;
|
||||
esac
|
||||
|
||||
case " ${UI_TARGETS[*]-} " in
|
||||
*" c4 "*|*" raybig "*)
|
||||
prepare_python_ui_runtime
|
||||
;;
|
||||
esac
|
||||
|
||||
seed_params
|
||||
|
||||
echo "Starting replay: ${REPLAY_ARGS[*]}"
|
||||
launch_replay
|
||||
|
||||
if [[ ${#UI_TARGETS[@]} -eq 0 ]]; then
|
||||
echo "Replay is running without UI windows. Press Ctrl-C to stop."
|
||||
wait "${REPLAY_PID}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Launching UIs: ${UI_TARGETS[*]}"
|
||||
|
||||
local_target=""
|
||||
for local_target in "${UI_TARGETS[@]}"; do
|
||||
case "${local_target}" in
|
||||
c3)
|
||||
launch_c3_ui
|
||||
;;
|
||||
c4)
|
||||
launch_python_ui 0
|
||||
;;
|
||||
raybig)
|
||||
launch_python_ui 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
wait "${UI_PIDS[@]}"
|
||||
@@ -110,8 +110,10 @@ cleanup() {
|
||||
kill "${FAKE_WIFI_PID}" >/dev/null 2>&1 || true
|
||||
wait "${FAKE_WIFI_PID}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
restore_runtime_artifacts
|
||||
restore_new_tracked_changes
|
||||
if [[ ! "${SP_KEEP_DESKTOP_RUNTIME_ARTIFACTS:-0}" =~ ^(1|true|yes|on)$ ]]; then
|
||||
restore_runtime_artifacts
|
||||
restore_new_tracked_changes
|
||||
fi
|
||||
rm -f "${PRE_TRACKED_DIRTY}" "${POST_TRACKED_DIRTY}"
|
||||
}
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ prepare_host_artifacts() {
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -201,6 +202,8 @@ 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
|
||||
|
||||
|
||||
@@ -110,8 +110,10 @@ cleanup() {
|
||||
kill "${FAKE_WIFI_PID}" >/dev/null 2>&1 || true
|
||||
wait "${FAKE_WIFI_PID}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
restore_runtime_artifacts
|
||||
restore_new_tracked_changes
|
||||
if [[ ! "${SP_KEEP_DESKTOP_RUNTIME_ARTIFACTS:-0}" =~ ^(1|true|yes|on)$ ]]; then
|
||||
restore_runtime_artifacts
|
||||
restore_new_tracked_changes
|
||||
fi
|
||||
rm -f "${PRE_TRACKED_DIRTY}" "${POST_TRACKED_DIRTY}"
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ All three entrypoints do the same thing. `./dev` is the shortest general-purpose
|
||||
### Available host commands
|
||||
|
||||
- `./dev replay [args...]`
|
||||
- `./onroad [jobs] (--c3 | --c4 | --raybig | --all | --replay-only) <route-or-replay-args...>`
|
||||
- `./dev cabana [args...]`
|
||||
- `./dev plotjuggler [args...]`
|
||||
- `./dev juggle [args...]`
|
||||
@@ -91,6 +92,9 @@ Examples:
|
||||
|
||||
```bash
|
||||
./dev replay
|
||||
./onroad --c3 f08912a233c1584f/2022-08-11--18-02-41/1
|
||||
./onroad --c4 f08912a233c1584f/2022-08-11--18-02-41/1 --start 30
|
||||
./onroad --all f08912a233c1584f/2022-08-11--18-02-41/1
|
||||
./dev plotjuggler --help
|
||||
./dev cabana
|
||||
./c3 8
|
||||
@@ -159,6 +163,12 @@ Use `./dev ...` when:
|
||||
- you want host-native `.so` files separated from the main repo
|
||||
- you do not want AI tools or git status confused by temporary build churn
|
||||
|
||||
Use `./onroad ...` when:
|
||||
|
||||
- you want a recorded route to drive the desktop UI(s) on PC
|
||||
- you need replay and UI to share the same isolated host runtime and messaging prefix
|
||||
- you want the default side-by-side desktop UI launch without running separate replay/UI commands
|
||||
|
||||
Use `./c3`, `./c4`, or `./raybig` when:
|
||||
|
||||
- you want the desktop UI variants
|
||||
|
||||
@@ -77,6 +77,7 @@ Options:
|
||||
--no-vipc do not output video
|
||||
--all do output all messages including uiDebug, userBookmark.
|
||||
this may causes issues when used along with UI
|
||||
--headless run replay without the ncurses console UI
|
||||
|
||||
Arguments:
|
||||
route the drive to replay. find your drives at
|
||||
@@ -91,6 +92,12 @@ tools/replay/replay <route-name>
|
||||
cd selfdrive/ui && ./ui.py
|
||||
```
|
||||
|
||||
For the StarPilot host workflow, the combined desktop launcher is:
|
||||
|
||||
```bash
|
||||
./onroad --c3 <route-name>
|
||||
```
|
||||
|
||||
## Work with plotjuggler
|
||||
If you want to use replay with plotjuggler, you can stream messages by running:
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/util.h"
|
||||
#include "common/prefix.h"
|
||||
#include "tools/replay/consoleui.h"
|
||||
#include "tools/replay/replay.h"
|
||||
@@ -31,6 +32,7 @@ Options:
|
||||
--no-hw-decoder Disable HW video decoding
|
||||
--no-vipc Do not output video
|
||||
--all Output all messages including bookmarkButton, uiDebug, userBookmark
|
||||
--headless Run replay without the ncurses console UI
|
||||
-h, --help Show this help message
|
||||
)";
|
||||
|
||||
@@ -42,6 +44,7 @@ struct ReplayConfig {
|
||||
std::string prefix;
|
||||
uint32_t flags = REPLAY_FLAG_NONE;
|
||||
bool auto_source = false;
|
||||
bool headless = false;
|
||||
int start_seconds = 0;
|
||||
int cache_segments = -1;
|
||||
float playback_speed = -1;
|
||||
@@ -66,6 +69,7 @@ bool parseArgs(int argc, char *argv[], ReplayConfig &config) {
|
||||
{"no-hw-decoder", no_argument, nullptr, 0},
|
||||
{"no-vipc", no_argument, nullptr, 0},
|
||||
{"all", no_argument, nullptr, 0},
|
||||
{"headless", no_argument, nullptr, 0},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, 0, nullptr, 0}, // Terminating entry
|
||||
};
|
||||
@@ -100,6 +104,7 @@ bool parseArgs(int argc, char *argv[], ReplayConfig &config) {
|
||||
std::string name = cli_options[option_index].name;
|
||||
if (name == "demo") config.route = DEMO_ROUTE;
|
||||
else if (name == "auto") config.auto_source = true;
|
||||
else if (name == "headless") config.headless = true;
|
||||
else config.flags |= flag_map.at(name);
|
||||
break;
|
||||
}
|
||||
@@ -149,6 +154,15 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config.headless) {
|
||||
replay.start(config.start_seconds);
|
||||
ExitHandler do_exit;
|
||||
while (!do_exit) {
|
||||
util::sleep_for(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConsoleUI console_ui(&replay);
|
||||
replay.start(config.start_seconds);
|
||||
return console_ui.exec();
|
||||
|
||||
Reference in New Issue
Block a user