BURN THE WITCH

This commit is contained in:
firestar5683
2026-08-14 22:36:56 -05:00
parent c2e2c24e8c
commit 603f9b56f9
253 changed files with 512 additions and 46786 deletions
+2 -8
View File
@@ -23,11 +23,6 @@ on:
type: boolean
default: true
required: false
build_ui:
description: "Build UI (selfdrive/ui)"
type: boolean
default: true
required: false
build_params:
description: "Build params Python extension"
type: boolean
@@ -156,7 +151,6 @@ jobs:
fi
TARGETS=()
[[ "${{ inputs.build_ui }}" == "true" ]] && TARGETS+=("selfdrive/ui/ui")
[[ "${{ inputs.build_params }}" == "true" ]] && TARGETS+=("common/params_pyx.so")
[[ "${{ inputs.build_cereal }}" == "true" ]] && TARGETS+=("cereal/messaging/bridge")
if [[ "${{ inputs.build_panda }}" == "true" ]]; then
@@ -184,8 +178,8 @@ jobs:
fi
if [[ ${#TARGETS[@]} -eq 0 ]]; then
echo "No partial targets selected; defaulting to UI + panda"
TARGETS=("selfdrive/ui/ui" "panda/board/obj/panda.bin.signed")
echo "No partial targets selected; defaulting to panda"
TARGETS=("panda/board/obj/panda.bin.signed")
fi
echo "Running partial build for targets: ${TARGETS[*]}"
-3
View File
@@ -54,9 +54,6 @@ cereal/gen
selfdrive/ui/translations/tmp
selfdrive/car/tests/cars_dump
system/camerad/test/ae_gray_test
selfdrive/ui/ui.macos
selfdrive/ui/ui.larch64
.coverage*
coverage.xml
htmlcov
+1 -16
View File
@@ -11,14 +11,6 @@
"tools/sim/run_bridge.py"
]
},
{
"id": "cpp_process",
"type": "pickString",
"description": "Select the process to debug",
"options": [
"selfdrive/ui/ui"
]
},
{
"id": "args",
"description": "Arguments to pass to the process",
@@ -40,13 +32,6 @@
"justMyCode": true,
"args": "${input:args}"
},
{
"name": "C++: openpilot Process",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/${input:cpp_process}",
"cwd": "${workspaceFolder}"
},
{
"name": "Attach LLDB to Replay drive",
"type": "lldb",
@@ -82,4 +67,4 @@
]
}
]
}
}
+1 -114
View File
@@ -37,10 +37,6 @@ AddOption('--coverage',
action='store_true',
help='build with test coverage options')
AddOption('--clazy',
action='store_true',
help='build with clazy')
AddOption('--ccflags',
action='store',
type='string',
@@ -354,116 +350,7 @@ else:
np_version = SCons.Script.Value(np.__version__)
Export('envCython', 'np_version')
# Qt build environment
qt_env = env.Clone()
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "DBus", "Xml"]
qt_libs = []
if arch == "Darwin":
qt_env['QTDIR'] = f"{brew_prefix}/opt/qt@5"
qt_dirs = [
os.path.join(qt_env['QTDIR'], "include"),
]
qt_dirs += [f"{qt_env['QTDIR']}/include/Qt{m}" for m in qt_modules]
qt_env["LINKFLAGS"] += ["-F" + os.path.join(qt_env['QTDIR'], "lib")]
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin"))
else:
if arch == "larch64":
qt_env.PrependENVPath('PATH', Dir("#third_party/qt5/larch64/bin/").abspath)
# For laptop/device builds that mount an AGNOS sysroot, always prefer Qt
# headers from that sysroot to keep headers/libs ABI-matched (Qt 5.12.x).
if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
qt_install_prefix = tici_libpath("/usr")
qt_install_headers = tici_libpath("/usr/include/aarch64-linux-gnu/qt5")
else:
qmake = os.environ.get("SP_QMAKE", "qmake")
qt_install_prefix = subprocess.check_output([qmake, '-query', 'QT_INSTALL_PREFIX'], encoding='utf8').strip()
qt_install_headers = subprocess.check_output([qmake, '-query', 'QT_INSTALL_HEADERS'], encoding='utf8').strip()
qt_env['QTDIR'] = qt_install_prefix
qt_dirs = [
f"{qt_install_headers}",
]
qt_gui_path = os.path.join(qt_install_headers, "QtGui")
qt_gui_dirs = [d for d in os.listdir(qt_gui_path) if os.path.isdir(os.path.join(qt_gui_path, d))]
qt_dirs += [f"{qt_install_headers}/QtGui/{qt_gui_dirs[0]}/QtGui", ] if qt_gui_dirs else []
qt_dirs += [f"{qt_install_headers}/Qt{m}" for m in qt_modules]
qt_libs = [f"Qt5{m}" for m in qt_modules]
if arch == "larch64":
qt_libs += ["GLESv2", "wayland-client"]
elif arch != "Darwin":
qt_libs += ["GL"]
qt_env['QT3DIR'] = qt_env['QTDIR']
qt_env.Tool('qt3')
if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
qt_tool_bin = tici_libpath("/usr/lib/qt5/bin")
qt_tool_root = tici_libpath("/")
qt_arm_moc = os.path.join(qt_tool_bin, "moc")
qt_arm_uic = os.path.join(qt_tool_bin, "uic")
qt_arm_rcc = os.path.join(qt_tool_bin, "rcc")
qt_host_bin = os.environ.get("SP_QT_HOST_BIN", "/usr/lib/qt5/bin")
qt_host_moc = os.environ.get("SP_QT_HOST_MOC", os.path.join(qt_host_bin, "moc"))
qt_host_uic = os.environ.get("SP_QT_HOST_UIC", os.path.join(qt_host_bin, "uic"))
qt_host_rcc = os.environ.get("SP_QT_HOST_RCC", "rcc")
if platform.machine() in ("aarch64", "arm64"):
if "SP_QT_HOST_MOC" in os.environ:
qt_env['QT3_MOC'] = qt_host_moc
elif os.path.isfile(qt_arm_moc):
qt_env['QT3_MOC'] = qt_arm_moc
if "SP_QT_HOST_UIC" in os.environ:
qt_env['QT3_UIC'] = qt_host_uic
elif os.path.isfile(qt_arm_uic):
qt_env['QT3_UIC'] = qt_arm_uic
if "SP_QT_HOST_RCC" in os.environ:
qt_env['SP_QT_RCC'] = qt_host_rcc
elif os.path.isfile(qt_arm_rcc):
qt_env['SP_QT_RCC'] = qt_arm_rcc
else:
qt_qemu = shutil.which("qemu-aarch64-static") or shutil.which("qemu-aarch64")
if qt_qemu and os.path.isfile(qt_arm_moc):
qt_env['QT3_MOC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_moc}"
else:
qt_env['QT3_MOC'] = qt_host_moc
if qt_qemu and os.path.isfile(qt_arm_uic):
qt_env['QT3_UIC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_uic}"
else:
qt_env['QT3_UIC'] = qt_host_uic
if qt_qemu and os.path.isfile(qt_arm_rcc):
qt_env['SP_QT_RCC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_rcc}"
else:
qt_env['SP_QT_RCC'] = qt_host_rcc
qt_env['CPPPATH'] += qt_dirs + ["#third_party/qrcode"]
qt_flags = [
"-D_REENTRANT",
"-DQT_NO_DEBUG",
"-DQT_WIDGETS_LIB",
"-DQT_GUI_LIB",
"-DQT_CORE_LIB",
"-DQT_MESSAGELOGCONTEXT",
]
qt_env['CXXFLAGS'] += qt_flags
qt_env['LIBPATH'] += ['#selfdrive/ui', ]
qt_env['LIBS'] = qt_libs
if GetOption("clazy"):
checks = [
"level0",
"level1",
"no-range-loop",
"no-non-pod-global-static",
]
qt_env['CXX'] = 'clazy'
qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0]
qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks)
Export('env', 'qt_env', 'arch', 'real_arch')
Export('env', 'arch', 'real_arch')
# Build common module
SConscript(['common/SConscript'])
-3
View File
@@ -46,9 +46,6 @@ while [[ $# -gt 0 ]]; do
shortcut_includes_panda=1
add_panda_targets
;;
--ui|-ui)
shortcut_targets+=("selfdrive/ui/ui")
;;
--cereal|-cereal)
shortcut_targets+=(
"cereal/libcereal.a"
-2
View File
@@ -137,8 +137,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"SecOCKey", {PERSISTENT | DONT_LOG, STRING}},
{"ShowDebugInfo", {PERSISTENT, BOOL}},
{"ShowAllToggles", {PERSISTENT, BOOL, "0", "0", 3}},
{"TryRaylibUI", {PERSISTENT, BOOL, "1"}},
{"UseOldUI", {PERSISTENT, BOOL, "0", std::nullopt, 0, SETTINGS_SIMPLE}},
{"UsePrebuilt", {PERSISTENT, BOOL, "1"}},
{"RouteCount", {PERSISTENT, INT, "0"}},
{"SnoozeUpdate", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
-13
View File
@@ -7,19 +7,6 @@ class Spinner:
def __init__(self):
self.spinner_proc = None
# Prefer the legacy compiled spinner on device.
legacy_spinner = os.path.join(BASEDIR, "selfdrive", "ui", "spinner")
if os.path.isfile("/TICI") and os.path.isfile(legacy_spinner) and os.access(legacy_spinner, os.X_OK):
try:
self.spinner_proc = subprocess.Popen([legacy_spinner],
stdin=subprocess.PIPE,
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
close_fds=True)
return
except OSError:
self.spinner_proc = None
# Raylib spinner requires Python deps from the repo virtualenv.
spinner_cwd = os.path.join(BASEDIR, "system", "ui")
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
-12
View File
@@ -9,18 +9,6 @@ class TextWindow:
def __init__(self, text):
self.text_proc = None
# Prefer the legacy compiled text window on device.
legacy_text = os.path.join(BASEDIR, "selfdrive", "ui", "text")
if os.path.isfile("/TICI") and os.path.isfile(legacy_text) and os.access(legacy_text, os.X_OK):
try:
self.text_proc = subprocess.Popen([legacy_text, text],
stdin=subprocess.PIPE,
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
close_fds=True)
return
except OSError:
self.text_proc = None
text_cwd = os.path.join(BASEDIR, "system", "ui")
venv_python = os.path.join(BASEDIR, ".venv", "bin", "python")
python_exec = venv_python if os.path.isfile(venv_python) else "python3"
+1 -1
View File
@@ -203,6 +203,6 @@ Compilation validates JIT capture/replay, pickle round-trip, finite outputs, met
2. Confirm `modeld` stays running.
3. Confirm finite `modelV2` path, lane-line, lead, pose, and action data.
4. Confirm `driverStateV2` on both supported camera resolutions.
5. Test download, selection, deletion, randomization, migration, and fallback in QT, raylib/mici, and Galaxy.
5. Test download, selection, deletion, randomization, migration, and fallback in both device UIs and Galaxy.
The built-in RDF artifact is `selfdrive/modeld/models/driving_tinygrad.pkl`. If migration cannot download the selected v23 artifact, StarPilot switches to that built-in model.
+1 -1
View File
@@ -48,7 +48,7 @@ Use `./dev` for host-native tools. It creates and reuses an isolated environment
./dev shell
```
For desktop UI work, use `./c3`, `./c4`, or `./raybig`. These commands use the same isolated host environment.
For desktop UI work, use `./c3` or `./c4`. These commands use the same isolated host environment.
Use `./build` when you need comma-compatible device artifacts. This is the expected validation for changes that affect compiled device code or runtime behavior:
+5 -7
View File
@@ -2,7 +2,7 @@
This flow builds **device-target (`larch64`) binaries on your laptop** using a Linux/aarch64 container and a synced comma sysroot.
For the full StarPilot branch workflow, including host-native shorthand tools such as `./dev`, `./c3`, `./c4`, and `./raybig`, see the [StarPilot development guide](https://github.com/firestar5683/StarPilot/blob/Dom/tools/STARPILOT_DEVELOPMENT.md).
For the full StarPilot branch workflow, including host-native shorthand tools such as `./dev`, `./c3`, and `./c4`, see the [StarPilot development guide](https://github.com/firestar5683/StarPilot/blob/Dom/tools/STARPILOT_DEVELOPMENT.md).
## Prerequisites
@@ -71,10 +71,10 @@ This runs:
- `SP_TICI_SYSROOT=/opt/tici-sysroot`
- `touch prebuilt`
To run `scons` targets explicitly in the same device-compatible environment:
To run SCons targets explicitly in the same device-compatible environment:
```bash
scripts/laptop_device_build.sh scons selfdrive/ui/ui
scripts/laptop_device_build.sh scons common/params_pyx.so
```
On macOS, once `.comma_sysroot` is present, plain `scons ...` auto-routes to this containerized device build.
@@ -112,7 +112,6 @@ Preferred host-side shorthand commands on this branch:
```bash
./c3
./c4
./raybig
./dev replay
./dev cabana
./dev plotjuggler
@@ -120,10 +119,9 @@ Preferred host-side shorthand commands on this branch:
These commands use the isolated `.host_runtime` cache so host-native artifacts do not churn the main tree.
Legacy direct script entrypoints still exist if needed:
Direct script entrypoints are also available:
```bash
scripts/launch_ui_desktop.sh
scripts/launch_ui_c3_desktop.sh
scripts/launch_ui_c4_desktop.sh
scripts/launch_ui_raybig_desktop.sh
```
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec "${ROOT_DIR}/scripts/host_tool_runner.sh" raybig "$@"
+3 -3
View File
@@ -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
View File
@@ -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 "$@"
;;
+1 -2
View File
@@ -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() {
+16 -41
View File
@@ -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 "$@"
-265
View File
@@ -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}"
+3 -20
View File
@@ -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)}"
-2
View File
@@ -1,4 +1,2 @@
*.cc
fonts/*.fnt
fonts/*.png
translations_assets.qrc
-20
View File
@@ -1,20 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="bootstrap-icons.svg">../../third_party/bootstrap/bootstrap-icons.svg</file>
<file>images/button_continue_triangle.svg</file>
<file>icons/circled_check.svg</file>
<file>icons/circled_slash.svg</file>
<file>icons/eye_open.svg</file>
<file>icons/eye_closed.svg</file>
<file>icons/close.svg</file>
<file>icons/lock_closed.svg</file>
<file>icons/checkmark.svg</file>
<file>icons/warning.png</file>
<file>icons/wifi_strength_low.svg</file>
<file>icons/wifi_strength_medium.svg</file>
<file>icons/wifi_strength_high.svg</file>
<file>icons/wifi_strength_full.svg</file>
<file alias="languages.json">../ui/translations/languages.json</file>
</qresource>
</RCC>
@@ -52,6 +52,9 @@ HYUNDAI_ELANTRA_STOPPED_LEAD_MAX_EGO_SPEED = 2.0
HYUNDAI_ELANTRA_STOPPED_LEAD_MAX_SPEED = 0.5
HYUNDAI_ELANTRA_STOPPED_LEAD_MIN_CLOSING_SPEED = 0.25
HYUNDAI_ELANTRA_STOPPED_LEAD_MAX_CREEP_ACCEL = 0.05
HYUNDAI_SANTA_FE_FINAL_STOP_MAX_SPEED = 1.0
HYUNDAI_SANTA_FE_FINAL_STOP_CAP_BP = [0.0, 0.2, 0.5, HYUNDAI_SANTA_FE_FINAL_STOP_MAX_SPEED]
HYUNDAI_SANTA_FE_FINAL_STOP_CAP_V = [-0.25, -0.30, -0.50, -0.90]
def get_bolt_acc_pedal_friction_bias(output_accel, a_target, v_ego):
@@ -131,6 +134,9 @@ class LongControlVehicleTuning:
self.is_hyundai_elantra_2021 = bool(
CP.brand == "hyundai" and str(getattr(CP, "carFingerprint", "")) == "HYUNDAI_ELANTRA_2021"
)
self.is_hyundai_santa_fe_2022 = bool(
CP.brand == "hyundai" and str(getattr(CP, "carFingerprint", "")) == "HYUNDAI_SANTA_FE_2022"
)
self.is_bolt_acc_pedal_friction_car = bool(
CP.brand == "gm" and
CP.enableGasInterceptorDEPRECATED and
@@ -153,6 +159,14 @@ class LongControlVehicleTuning:
def shape_stopping_accel(self, output_accel, a_target, should_stop, v_ego, has_lead, stop_accel):
"""Release a stale hard lead brake once the stop target has eased."""
if (
self.is_hyundai_santa_fe_2022 and
v_ego <= HYUNDAI_SANTA_FE_FINAL_STOP_MAX_SPEED and
a_target <= 0.1
):
final_stop_cap = float(interp(v_ego, HYUNDAI_SANTA_FE_FINAL_STOP_CAP_BP, HYUNDAI_SANTA_FE_FINAL_STOP_CAP_V))
return max(float(output_accel), final_stop_cap)
if (
not self.is_hyundai_elantra_2021 or
not has_lead or not should_stop or v_ego > 2.0 or
@@ -1217,6 +1217,15 @@ def test_gm_stock_truck_target_filter_bypasses_low_speed_and_other_cars():
assert bolt_tuning.shape_gm_truck_accel_target(-0.10, 20.0, False) == pytest.approx(-0.10)
def test_santa_fe_final_stop_cap_softens_only_last_kmh():
CP = make_longcontrol_cp(brand="hyundai", carFingerprint="HYUNDAI_SANTA_FE_2022")
tuning = LongControl(CP).vehicle_tuning
assert tuning.shape_stopping_accel(-2.0, -0.2, True, 0.2, False, -2.0) == pytest.approx(-0.30)
assert tuning.shape_stopping_accel(-2.0, -0.2, True, 1.5, False, -2.0) == pytest.approx(-2.0)
assert tuning.shape_stopping_accel(-2.0, 0.3, False, 0.2, False, -2.0) == pytest.approx(-2.0)
def test_toyota_sienna_target_filter_smooths_mild_high_speed_handoffs():
CP = make_longcontrol_cp(brand="toyota", carFingerprint=TOYOTA_CAR.TOYOTA_SIENNA_4TH_GEN)
tuning = vehicle_tunes.LongControlVehicleTuning(CP)
+28 -123
View File
@@ -1,128 +1,33 @@
import json
import os
Import('env', 'qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations')
Import('env', 'arch', 'common')
base_libs = [common, messaging, visionipc, transformations,
'm', 'OpenCL', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"]
if GetOption('extras') and arch != "Darwin":
raylib_env = env.Clone()
raylib_env['LIBPATH'] += [f'#third_party/raylib/{arch}/']
raylib_env['LINKFLAGS'].append('-Wl,-strip-debug')
base_libs += ['avcodec', 'avformat', 'avutil', 'swresample', 'yuv']
raylib_libs = common + ["raylib"]
if arch == "larch64":
raylib_libs += ["GLESv2", "wayland-client", "wayland-egl", "EGL"]
else:
raylib_libs += ["GL"]
# OpenMAX is only available in the device-target runtime/sysroot. Host desktop
# UI builds on Linux should not need or link it.
if arch == 'larch64':
base_libs.append('OmxCore')
release = "release3"
installers = [
("openpilot", release),
("openpilot_test", f"{release}-staging"),
("openpilot_nightly", "nightly"),
("openpilot_internal", "nightly-dev"),
]
if arch == 'larch64':
base_libs.append('EGL')
cont = raylib_env.Command("installer/continue_openpilot.o", "installer/continue_openpilot.sh",
"ld -r -b binary -o $TARGET $SOURCE")
inter = raylib_env.Command("installer/inter_ttf.o", "installer/inter-ascii.ttf",
"ld -r -b binary -o $TARGET $SOURCE")
for name, branch in installers:
defines = {'BRANCH': f"'\"{branch}\"'"}
if "internal" in name:
defines['INTERNAL'] = "1"
if arch == "Darwin":
del base_libs[base_libs.index('OpenCL')]
qt_env['FRAMEWORKS'] += ['OpenCL']
# FIXME: remove this once we're on 5.15 (24.04)
qt_env['CXXFLAGS'] += ["-Wno-deprecated-declarations"]
qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"], LIBS=base_libs)
widgets_src = ["qt/widgets/input.cc", "qt/prime_state.cc",
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
"qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"]
starpilot_widgets_src = ["../../starpilot/ui/qt/widgets/starpilot_controls.cc"]
widgets_src += starpilot_widgets_src
widgets = qt_env.Library("qt_widgets", widgets_src, LIBS=base_libs)
Export('widgets')
qt_libs = [widgets, qt_util] + base_libs
qt_src = ["main.cc", "ui.cc", "qt/sidebar.cc", "qt/body.cc",
"qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc",
"qt/offroad/software_settings.cc", "qt/offroad/developer_panel.cc", "qt/offroad/onboarding.cc",
"qt/offroad/driverview.cc", "qt/offroad/experimental_mode.cc",
"qt/onroad/onroad_home.cc", "qt/onroad/annotated_camera.cc", "qt/onroad/model.cc",
"qt/onroad/buttons.cc", "qt/onroad/alerts.cc", "qt/onroad/driver_monitoring.cc", "qt/onroad/hud.cc"]
qt_env['CPPPATH'] += ["../../starpilot/ui/screenrecorder/openmax/include/"]
starpilot_src = ["../../starpilot/ui/starpilot_ui.cc", "../../starpilot/ui/qt/offroad/data_settings.cc",
"../../starpilot/ui/qt/offroad/device_settings.cc", "../../starpilot/ui/qt/offroad/starpilot_settings.cc",
"../../starpilot/ui/qt/offroad/expandable_multi_option_dialog.cc",
"../../starpilot/ui/qt/offroad/lateral_settings.cc", "../../starpilot/ui/qt/offroad/longitudinal_settings.cc",
"../../starpilot/ui/qt/offroad/maps_settings.cc", "../../starpilot/ui/qt/offroad/model_settings.cc",
"../../starpilot/ui/qt/offroad/navigation_settings.cc", "../../starpilot/ui/qt/offroad/sounds_settings.cc",
"../../starpilot/ui/qt/offroad/theme_settings.cc", "../../starpilot/ui/qt/offroad/utilities.cc",
"../../starpilot/ui/qt/offroad/vehicle_settings.cc", "../../starpilot/ui/qt/offroad/visual_settings.cc",
"../../starpilot/ui/qt/offroad/wheel_settings.cc", "../../starpilot/ui/qt/onroad/starpilot_annotated_camera.cc",
"../../starpilot/ui/qt/onroad/starpilot_buttons.cc", "../../starpilot/ui/qt/onroad/starpilot_onroad.cc",
"../../starpilot/ui/qt/widgets/developer_sidebar.cc", "../../starpilot/ui/qt/widgets/drive_stats.cc",
"../../starpilot/ui/qt/widgets/drive_summary.cc",
"../../starpilot/ui/qt/widgets/navigation_functions.cc",
"../../starpilot/ui/screenrecorder/omx_encoder.cc", "../../starpilot/ui/screenrecorder/screenrecorder.cc"]
qt_src += starpilot_src
# build translation files
with open(File("translations/languages.json").abspath) as f:
languages = json.loads(f.read())
translation_sources = [f"#selfdrive/ui/translations/{l}.ts" for l in languages.values()]
translation_targets = [src.replace(".ts", ".qm") for src in translation_sources]
lrelease_bin = os.environ.get("SP_QT_HOST_LRELEASE", "lrelease") if arch == 'larch64' else 'lrelease'
lrelease = qt_env.Command(translation_targets, translation_sources, f"{lrelease_bin} $SOURCES")
qt_env.NoClean(translation_sources)
qt_env.Precious(translation_sources)
# create qrc file for compiled translations to include with assets
translations_assets_src = "#selfdrive/assets/translations_assets.qrc"
with open(File(translations_assets_src).abspath, 'w') as f:
f.write('<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n')
f.write('\n'.join([f'<file alias="{l}">../ui/translations/{l}.qm</file>' for l in languages.values()]))
f.write('\n</qresource>\n</RCC>')
# build assets
assets = "#selfdrive/assets/assets.cc"
assets_src = "#selfdrive/assets/assets.qrc"
rcc_bin = qt_env.get("SP_QT_RCC", "rcc")
qt_env.Command(assets, [assets_src, translations_assets_src], f"{rcc_bin} $SOURCES -o $TARGET")
qt_env.Depends(assets, Glob('#selfdrive/assets/*', exclude=[assets, assets_src, translations_assets_src, "#selfdrive/assets/assets.o"]) + [lrelease])
asset_obj = qt_env.Object("assets", assets)
# build main UI
qt_env.Program("ui", qt_src + [asset_obj], LIBS=qt_libs)
if GetOption('extras'):
qt_src.remove("main.cc") # replaced by test_runner
qt_env.Program('tests/test_translations', [asset_obj, 'tests/test_runner.cc', 'tests/test_translations.cc'] + qt_src, LIBS=qt_libs)
# build installers
if arch != "Darwin":
raylib_env = env.Clone()
raylib_env['LIBPATH'] += [f'#third_party/raylib/{arch}/']
raylib_env['LINKFLAGS'].append('-Wl,-strip-debug')
raylib_libs = common + ["raylib"]
if arch == "larch64":
raylib_libs += ["GLESv2", "wayland-client", "wayland-egl", "EGL"]
else:
raylib_libs += ["GL"]
release = "release3"
installers = [
("openpilot", release),
("openpilot_test", f"{release}-staging"),
("openpilot_nightly", "nightly"),
("openpilot_internal", "nightly-dev"),
]
cont = raylib_env.Command("installer/continue_openpilot.o", "installer/continue_openpilot.sh",
"ld -r -b binary -o $TARGET $SOURCE")
inter = raylib_env.Command("installer/inter_ttf.o", "installer/inter-ascii.ttf",
"ld -r -b binary -o $TARGET $SOURCE")
for name, branch in installers:
d = {'BRANCH': f"'\"{branch}\"'"}
if "internal" in name:
d['INTERNAL'] = "1"
obj = raylib_env.Object(f"installer/installers/installer_{name}.o", ["installer/installer.cc"], CPPDEFINES=d)
f = raylib_env.Program(f"installer/installers/installer_{name}", [obj, cont, inter], LIBS=raylib_libs)
# keep installers small
assert f[0].get_size() < 1900*1e3, f[0].get_size()
obj = raylib_env.Object(f"installer/installers/installer_{name}.o", ["installer/installer.cc"], CPPDEFINES=defines)
installer = raylib_env.Program(f"installer/installers/installer_{name}", [obj, cont, inter], LIBS=raylib_libs)
assert installer[0].get_size() < 1900*1e3, installer[0].get_size()
@@ -32,7 +32,6 @@ THEME_KEY_CONFIG = {
COLOR_PRESETS = ["Stock", "#FFFFFF", "#178644", "#3B82F6", "#E63956", "#8B5CF6", "#F59E0B"]
CAMERA_VIEWS = ["Auto", "Driver", "Standard", "Wide"]
# Mirrors starpilot/ui/qt/offroad/developer_panel.cc:200-218.
# Keys are the int values stored in DeveloperSidebarMetric{1..7}; values are the
# human-readable labels shown in both the row value and the picker dialog.
DEVELOPER_SIDEBAR_METRIC_OPTIONS: dict[int, str] = {
@@ -355,7 +355,7 @@ class _SettingsPage(StarPilotPanel):
def _show_labeled_select(self, title, key, options, current_value):
"""Integer-based multi-option selector with label/value pairs (puts int).
Mirrors Qt's ButtonParamControl: resolve by index so no KeyError is possible.
Resolve by index so no KeyError is possible.
"""
option_labels = [tr(label) for _, label in options]
option_values = [value for value, _ in options]
-62
View File
@@ -1,62 +0,0 @@
#include <sys/resource.h>
#include <unistd.h>
#include <QApplication>
#include <QTranslator>
#include "common/swaglog.h"
#include "common/util.h"
#include "system/hardware/hw.h"
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/window.h"
// Qt 5.12.8's qErrnoWarning() emits QtCriticalMsg then calls abort() directly,
// bypassing the fatal-message path. Intercept critical+fatal Wayland messages
// before the unconditional abort() fires and clean-exit so the manager restarts
// us quickly instead of going through the slow abort/crash-handler path.
void waylandAwareMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
if (type == QtCriticalMsg || type == QtFatalMsg) {
QByteArray bytes = msg.toUtf8();
if (bytes.contains("ayland") || bytes.contains("wl_display")) {
swagLogMessageHandler(type, context, msg);
LOGE("UI WAYLAND EXIT: %s", bytes.constData());
_exit(0); // clean exit; manager restarts us
}
}
swagLogMessageHandler(type, context, msg);
// Non-Wayland fatal: let Qt abort normally; crash_handler will capture it.
}
int main(int argc, char *argv[]) {
setpriority(PRIO_PROCESS, 0, -20);
qInstallMessageHandler(waylandAwareMessageHandler);
initApp(argc, argv);
QTranslator translator;
QString translation_file = QString::fromStdString(Params().get("LanguageSetting"));
if (!translator.load(QString(":/%1").arg(translation_file)) && translation_file.length()) {
qCritical() << "Failed to load translation file:" << translation_file;
}
QApplication a(argc, argv);
a.installTranslator(&translator);
MainWindow w;
setMainWindow(&w);
a.installEventFilter(&w);
// Pin the UI to the little cores (0-3) AFTER startup. The realtime control
// loop (card/controlsd) runs SCHED_FIFO on core 4; this keeps the steady-state
// UI off it so a UI stall can't preempt the control loop. Deliberately done
// after MainWindow init so startup — and crucially restart recovery — can use
// all cores; pinning before init starved the restarting UI on the contended
// little cores and stretched recovery from ~30s to minutes. The per-second
// reaffine in UIState::update keeps it pinned thereafter.
if (!Hardware::PC()) {
util::set_core_affinity({0, 1, 2, 3});
}
return a.exec();
}
+1 -1
View File
@@ -105,7 +105,7 @@ class BigButton(Widget):
LABEL_HORIZONTAL_PADDING = 40
LABEL_VERTICAL_PADDING = 23 # visually matches 30 in figma
"""A lightweight stand-in for the Qt BigButton, drawn & updated each frame."""
"""A lightweight large action button, drawn and updated each frame."""
def __init__(self, text: str, value: str = "", icon: Union[rl.Texture, None] = None, scroll: bool = False):
super().__init__()
-338
View File
@@ -1,338 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'ui.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "ui.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'ui.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_UIState_t {
QByteArrayData data[11];
char stringdata0[96];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_UIState_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_UIState_t qt_meta_stringdata_UIState = {
{
QT_MOC_LITERAL(0, 0, 7), // "UIState"
QT_MOC_LITERAL(1, 8, 8), // "uiUpdate"
QT_MOC_LITERAL(2, 17, 0), // ""
QT_MOC_LITERAL(3, 18, 1), // "s"
QT_MOC_LITERAL(4, 20, 16), // "StarPilotUIState"
QT_MOC_LITERAL(5, 37, 2), // "fs"
QT_MOC_LITERAL(6, 40, 17), // "offroadTransition"
QT_MOC_LITERAL(7, 58, 7), // "offroad"
QT_MOC_LITERAL(8, 66, 14), // "engagedChanged"
QT_MOC_LITERAL(9, 81, 7), // "engaged"
QT_MOC_LITERAL(10, 89, 6) // "update"
},
"UIState\0uiUpdate\0\0s\0StarPilotUIState\0"
"fs\0offroadTransition\0offroad\0"
"engagedChanged\0engaged\0update"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_UIState[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
4, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
3, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 34, 2, 0x06 /* Public */,
6, 1, 39, 2, 0x06 /* Public */,
8, 1, 42, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
10, 0, 45, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void, 0x80000000 | 0, 0x80000000 | 4, 3, 5,
QMetaType::Void, QMetaType::Bool, 7,
QMetaType::Void, QMetaType::Bool, 9,
// slots: parameters
QMetaType::Void,
0 // eod
};
void UIState::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<UIState *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->uiUpdate((*reinterpret_cast< const UIState(*)>(_a[1])),(*reinterpret_cast< const StarPilotUIState(*)>(_a[2]))); break;
case 1: _t->offroadTransition((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 2: _t->engagedChanged((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 3: _t->update(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (UIState::*)(const UIState & , const StarPilotUIState & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&UIState::uiUpdate)) {
*result = 0;
return;
}
}
{
using _t = void (UIState::*)(bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&UIState::offroadTransition)) {
*result = 1;
return;
}
}
{
using _t = void (UIState::*)(bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&UIState::engagedChanged)) {
*result = 2;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject UIState::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_UIState.data,
qt_meta_data_UIState,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *UIState::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *UIState::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_UIState.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int UIState::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 4)
qt_static_metacall(this, _c, _id, _a);
_id -= 4;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 4)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 4;
}
return _id;
}
// SIGNAL 0
void UIState::uiUpdate(const UIState & _t1, const StarPilotUIState & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 1
void UIState::offroadTransition(bool _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
// SIGNAL 2
void UIState::engagedChanged(bool _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 2, _a);
}
struct qt_meta_stringdata_Device_t {
QByteArrayData data[13];
char stringdata0[134];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_Device_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_Device_t qt_meta_stringdata_Device = {
{
QT_MOC_LITERAL(0, 0, 6), // "Device"
QT_MOC_LITERAL(1, 7, 19), // "displayPowerChanged"
QT_MOC_LITERAL(2, 27, 0), // ""
QT_MOC_LITERAL(3, 28, 2), // "on"
QT_MOC_LITERAL(4, 31, 18), // "interactiveTimeout"
QT_MOC_LITERAL(5, 50, 23), // "resetInteractiveTimeout"
QT_MOC_LITERAL(6, 74, 7), // "timeout"
QT_MOC_LITERAL(7, 82, 14), // "timeout_onroad"
QT_MOC_LITERAL(8, 97, 6), // "update"
QT_MOC_LITERAL(9, 104, 7), // "UIState"
QT_MOC_LITERAL(10, 112, 1), // "s"
QT_MOC_LITERAL(11, 114, 16), // "StarPilotUIState"
QT_MOC_LITERAL(12, 131, 2) // "fs"
},
"Device\0displayPowerChanged\0\0on\0"
"interactiveTimeout\0resetInteractiveTimeout\0"
"timeout\0timeout_onroad\0update\0UIState\0"
"s\0StarPilotUIState\0fs"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_Device[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
6, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 1, 44, 2, 0x06 /* Public */,
4, 0, 47, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
5, 2, 48, 2, 0x0a /* Public */,
5, 1, 53, 2, 0x2a /* Public | MethodCloned */,
5, 0, 56, 2, 0x2a /* Public | MethodCloned */,
8, 2, 57, 2, 0x0a /* Public */,
// signals: parameters
QMetaType::Void, QMetaType::Bool, 3,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::Int, QMetaType::Int, 6, 7,
QMetaType::Void, QMetaType::Int, 6,
QMetaType::Void,
QMetaType::Void, 0x80000000 | 9, 0x80000000 | 11, 10, 12,
0 // eod
};
void Device::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<Device *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->displayPowerChanged((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 1: _t->interactiveTimeout(); break;
case 2: _t->resetInteractiveTimeout((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
case 3: _t->resetInteractiveTimeout((*reinterpret_cast< int(*)>(_a[1]))); break;
case 4: _t->resetInteractiveTimeout(); break;
case 5: _t->update((*reinterpret_cast< const UIState(*)>(_a[1])),(*reinterpret_cast< const StarPilotUIState(*)>(_a[2]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (Device::*)(bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Device::displayPowerChanged)) {
*result = 0;
return;
}
}
{
using _t = void (Device::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Device::interactiveTimeout)) {
*result = 1;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject Device::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_Device.data,
qt_meta_data_Device,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *Device::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *Device::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_Device.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int Device::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 6)
qt_static_metacall(this, _c, _id, _a);
_id -= 6;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 6)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 6;
}
return _id;
}
// SIGNAL 0
void Device::displayPowerChanged(bool _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 1
void Device::interactiveTimeout()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-1
View File
@@ -130,7 +130,6 @@ def render_adjacent_lanes(renderer) -> None:
def render_path_edges(renderer) -> None:
"""Draw colored edge strips along the driving path.
Qt reference: paintPathEdges in starpilot_annotated_camera.cc:732-769
Path edges are the area between track_edge_vertices (outer) and track_vertices (inner).
Color selection on Python UIs:
@@ -19,7 +19,7 @@ def _hsla_to_color(h: float, s: float, l: float, a: float) -> rl.Color:
class RainbowPath:
"""Rainbow path renderer ported from the FrogPilot/StarPilot Qt C++ UI implementation."""
"""Rainbow path renderer for the StarPilot onroad UI."""
def __init__(self) -> None:
self._hue_offset: float = 0.0
-142
View File
@@ -1,142 +0,0 @@
#include "selfdrive/ui/qt/api.h"
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <QApplication>
#include <QCryptographicHash>
#include <QDateTime>
#include <QDebug>
#include <QJsonDocument>
#include <QNetworkRequest>
#include <memory>
#include <string>
#include "common/util.h"
#include "system/hardware/hw.h"
#include "selfdrive/ui/qt/util.h"
namespace CommaApi {
RSA *get_rsa_private_key() {
static std::unique_ptr<RSA, decltype(&RSA_free)> rsa_private(nullptr, RSA_free);
if (!rsa_private) {
FILE *fp = fopen(Path::rsa_file().c_str(), "rb");
if (!fp) {
qDebug() << "No RSA private key found, please run manager.py or registration.py";
return nullptr;
}
rsa_private.reset(PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL));
fclose(fp);
}
return rsa_private.get();
}
QByteArray rsa_sign(const QByteArray &data) {
RSA *rsa_private = get_rsa_private_key();
if (!rsa_private) return {};
QByteArray sig(RSA_size(rsa_private), Qt::Uninitialized);
unsigned int sig_len;
int ret = RSA_sign(NID_sha256, (unsigned char*)data.data(), data.size(), (unsigned char*)sig.data(), &sig_len, rsa_private);
assert(ret == 1);
assert(sig.size() == sig_len);
return sig;
}
QString create_jwt(const QJsonObject &payloads, int expiry) {
QJsonObject header = {{"alg", "RS256"}};
auto t = QDateTime::currentSecsSinceEpoch();
QJsonObject payload = {{"identity", getDongleId().value_or("")}, {"nbf", t}, {"iat", t}, {"exp", t + expiry}};
for (auto it = payloads.begin(); it != payloads.end(); ++it) {
payload.insert(it.key(), it.value());
}
auto b64_opts = QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals;
QString jwt = QJsonDocument(header).toJson(QJsonDocument::Compact).toBase64(b64_opts) + '.' +
QJsonDocument(payload).toJson(QJsonDocument::Compact).toBase64(b64_opts);
auto hash = QCryptographicHash::hash(jwt.toUtf8(), QCryptographicHash::Sha256);
return jwt + "." + rsa_sign(hash).toBase64(b64_opts);
}
} // namespace CommaApi
HttpRequest::HttpRequest(QObject *parent, bool create_jwt, int timeout) : create_jwt(create_jwt), QObject(parent) {
networkTimer = new QTimer(this);
networkTimer->setSingleShot(true);
networkTimer->setInterval(timeout);
connect(networkTimer, &QTimer::timeout, this, &HttpRequest::requestTimeout);
}
bool HttpRequest::active() const {
return reply != nullptr;
}
bool HttpRequest::timeout() const {
return reply && reply->error() == QNetworkReply::OperationCanceledError;
}
void HttpRequest::sendRequest(const QString &requestURL, const HttpRequest::Method method) {
if (active()) {
qDebug() << "HttpRequest is active";
return;
}
QString token;
if (create_jwt) {
token = CommaApi::create_jwt();
} else {
QString token_json = QString::fromStdString(util::read_file(util::getenv("HOME") + "/.comma/auth.json"));
QJsonDocument json_d = QJsonDocument::fromJson(token_json.toUtf8());
token = json_d["access_token"].toString();
}
QNetworkRequest request;
request.setUrl(QUrl(requestURL));
request.setRawHeader("User-Agent", getUserAgent().toUtf8());
if (!token.isEmpty()) {
request.setRawHeader(QByteArray("Authorization"), ("JWT " + token).toUtf8());
}
if (method == HttpRequest::Method::GET) {
reply = nam()->get(request);
} else if (method == HttpRequest::Method::DELETE) {
reply = nam()->deleteResource(request);
}
networkTimer->start();
connect(reply, &QNetworkReply::finished, this, &HttpRequest::requestFinished);
}
void HttpRequest::requestTimeout() {
reply->abort();
}
void HttpRequest::requestFinished() {
networkTimer->stop();
if (reply->error() == QNetworkReply::NoError) {
emit requestDone(reply->readAll(), true, reply->error());
} else {
QString error;
if (reply->error() == QNetworkReply::OperationCanceledError) {
nam()->clearAccessCache();
nam()->clearConnectionCache();
error = "Request timed out";
} else {
error = reply->errorString();
}
emit requestDone(error, false, reply->error());
}
reply->deleteLater();
reply = nullptr;
}
QNetworkAccessManager *HttpRequest::nam() {
static QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(qApp);
return networkAccessManager;
}
-49
View File
@@ -1,49 +0,0 @@
#pragma once
#include <QJsonObject>
#include <QNetworkReply>
#include <QString>
#include <QTimer>
#include "common/util.h"
#include "starpilot/ui/qt/widgets/starpilot_controls.h"
namespace CommaApi {
const QString BASE_URL = util::getenv("API_HOST", useKonikServer() ? "https://api.konik.ai" : "https://api.commadotai.com").c_str();
QByteArray rsa_sign(const QByteArray &data);
QString create_jwt(const QJsonObject &payloads = {}, int expiry = 3600);
} // namespace CommaApi
/**
* Makes a request to the request endpoint.
*/
class HttpRequest : public QObject {
Q_OBJECT
public:
enum class Method {GET, DELETE};
explicit HttpRequest(QObject* parent, bool create_jwt = true, int timeout = 20000);
void sendRequest(const QString &requestURL, const Method method = Method::GET);
bool active() const;
bool timeout() const;
signals:
void requestDone(const QString &response, bool success, QNetworkReply::NetworkError error);
protected:
QNetworkReply *reply = nullptr;
private:
static QNetworkAccessManager *nam();
QTimer *networkTimer = nullptr;
bool create_jwt;
private slots:
void requestTimeout();
void requestFinished();
};
-161
View File
@@ -1,161 +0,0 @@
#include "selfdrive/ui/qt/body.h"
#include <cmath>
#include <algorithm>
#include <QPainter>
#include <QStackedLayout>
#include "common/params.h"
#include "common/timing.h"
RecordButton::RecordButton(QWidget *parent) : QPushButton(parent) {
setCheckable(true);
setChecked(false);
setFixedSize(148, 148);
QObject::connect(this, &QPushButton::toggled, [=]() {
setEnabled(false);
});
}
void RecordButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QPoint center(width() / 2, height() / 2);
QColor bg(isChecked() ? "#FFFFFF" : "#737373");
QColor accent(isChecked() ? "#FF0000" : "#FFFFFF");
if (!isEnabled()) {
bg = QColor("#404040");
accent = QColor("#FFFFFF");
}
if (isDown()) {
accent.setAlphaF(0.7);
}
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawEllipse(center, 74, 74);
p.setPen(QPen(accent, 6));
p.setBrush(Qt::NoBrush);
p.drawEllipse(center, 42, 42);
p.setPen(Qt::NoPen);
p.setBrush(accent);
p.drawEllipse(center, 22, 22);
}
BodyWindow::BodyWindow(QWidget *parent) : fuel_filter(1.0, 5., 1. / UI_FREQ), QWidget(parent) {
QStackedLayout *layout = new QStackedLayout(this);
layout->setStackingMode(QStackedLayout::StackAll);
QWidget *w = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout(w);
vlayout->setMargin(45);
layout->addWidget(w);
// face
face = new QLabel();
face->setAlignment(Qt::AlignCenter);
layout->addWidget(face);
awake = new QMovie("../assets/body/awake.gif", {}, this);
awake->setCacheMode(QMovie::CacheAll);
sleep = new QMovie("../assets/body/sleep.gif", {}, this);
sleep->setCacheMode(QMovie::CacheAll);
// record button
btn = new RecordButton(this);
vlayout->addWidget(btn, 0, Qt::AlignBottom | Qt::AlignRight);
QObject::connect(btn, &QPushButton::clicked, [=](bool checked) {
btn->setEnabled(false);
Params().putBool("DisableLogging", !checked);
last_button = nanos_since_boot();
});
w->raise();
QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState);
}
void BodyWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect(), QColor(0, 0, 0));
// battery outline + detail
p.translate(width() - 136, 16);
const QColor gray = QColor("#737373");
p.setBrush(Qt::NoBrush);
p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
p.drawRoundedRect(2, 2, 78, 36, 8, 8);
p.setPen(Qt::NoPen);
p.setBrush(gray);
p.drawRoundedRect(84, 12, 6, 16, 4, 4);
p.drawRect(84, 12, 3, 16);
// battery level
double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f);
const int m = 5; // manual margin since we can't do an inner border
p.setPen(Qt::NoPen);
p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A"));
p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4);
// charging status
if (charging) {
p.setPen(Qt::NoPen);
p.setBrush(Qt::white);
const QPolygonF charger({
QPointF(12.31, 0),
QPointF(12.31, 16.92),
QPointF(18.46, 16.92),
QPointF(6.15, 40),
QPointF(6.15, 23.08),
QPointF(0, 23.08),
});
p.drawPolygon(charger.translated(98, 0));
}
}
void BodyWindow::offroadTransition(bool offroad) {
btn->setChecked(true);
btn->setEnabled(true);
fuel_filter.reset(1.0);
}
void BodyWindow::updateState(const UIState &s) {
if (!isVisible()) {
return;
}
const SubMaster &sm = *(s.sm);
auto cs = sm["carState"].getCarState();
charging = cs.getCharging();
fuel_filter.update(cs.getFuelGauge());
// TODO: use carState.standstill when that's fixed
const bool standstill = std::abs(cs.getVEgo()) < 0.01;
QMovie *m = standstill ? sleep : awake;
if (m != face->movie()) {
face->setMovie(m);
face->movie()->start();
}
// update record button state
if (sm.updated("managerState") && (sm.rcv_time("managerState") - last_button)*1e-9 > 0.5) {
for (auto proc : sm["managerState"].getManagerState().getProcesses()) {
if (proc.getName() == "loggerd") {
btn->setEnabled(true);
btn->setChecked(proc.getRunning());
}
}
}
update();
}
-38
View File
@@ -1,38 +0,0 @@
#pragma once
#include <QMovie>
#include <QLabel>
#include <QPushButton>
#include "common/util.h"
#include "selfdrive/ui/ui.h"
class RecordButton : public QPushButton {
Q_OBJECT
public:
RecordButton(QWidget* parent = 0);
private:
void paintEvent(QPaintEvent*) override;
};
class BodyWindow : public QWidget {
Q_OBJECT
public:
BodyWindow(QWidget* parent = 0);
private:
bool charging = false;
uint64_t last_button = 0;
FirstOrderFilter fuel_filter;
QLabel *face;
QMovie *awake, *sleep;
RecordButton *btn;
void paintEvent(QPaintEvent*) override;
private slots:
void updateState(const UIState &s);
void offroadTransition(bool onroad);
};
-344
View File
@@ -1,344 +0,0 @@
#include "selfdrive/ui/qt/home.h"
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStackedWidget>
#include <QVBoxLayout>
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/prime.h"
#include "starpilot/ui/qt/widgets/drive_stats.h"
#include "starpilot/ui/qt/widgets/drive_summary.h"
// HomeWindow: the container for the offroad and onroad UIs
HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
QHBoxLayout *main_layout = new QHBoxLayout(this);
main_layout->setMargin(0);
main_layout->setSpacing(0);
sidebar = new Sidebar(this);
main_layout->addWidget(sidebar);
QObject::connect(sidebar, &Sidebar::openSettings, this, &HomeWindow::openSettings);
slayout = new QStackedLayout();
main_layout->addLayout(slayout);
home = new OffroadHome(this);
QObject::connect(home, &OffroadHome::openSettings, this, &HomeWindow::openSettings);
slayout->addWidget(home);
onroad = new OnroadWindow(this);
slayout->addWidget(onroad);
body = new BodyWindow(this);
slayout->addWidget(body);
driver_view = new DriverViewWindow(this);
connect(driver_view, &DriverViewWindow::done, [=] {
showDriverView(false);
});
slayout->addWidget(driver_view);
setAttribute(Qt::WA_NoSystemBackground);
QObject::connect(uiState(), &UIState::uiUpdate, this, &HomeWindow::updateState);
QObject::connect(uiState(), &UIState::offroadTransition, this, &HomeWindow::offroadTransition);
QObject::connect(uiState(), &UIState::offroadTransition, sidebar, &Sidebar::offroadTransition);
developer_sidebar = new DeveloperSidebar(this);
main_layout->addWidget(developer_sidebar);
developer_sidebar->setVisible(false);
}
void HomeWindow::showSidebar(bool show) {
sidebar->setVisible(show);
}
void HomeWindow::updateState(const UIState &s, const StarPilotUIState &fs) {
const SubMaster &sm = *(s.sm);
// switch to the generic robot UI
if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) {
body->setEnabled(true);
slayout->setCurrentWidget(body);
}
const StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
const QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
if (s.scene.started) {
if (starpilot_scene.driver_camera_timer >= UI_FREQ / 2) {
showDriverView(true, true);
} else {
if (driver_view->isVisible()) {
sidebar->setVisible(params.getBool("Sidebar") || starpilot_toggles.value("debug_mode").toBool());
slayout->setCurrentWidget(onroad);
}
developer_sidebar->setVisible(starpilot_toggles.value("developer_sidebar").toBool());
starpilotUIState()->starpilot_scene.sidebars_open = developer_sidebar->isVisible() && sidebar->isVisible();
}
}
}
void HomeWindow::offroadTransition(bool offroad) {
StarPilotUIState &fs = *starpilotUIState();
StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
body->setEnabled(false);
sidebar->setVisible(offroad || params.getBool("SidebarOpen") || starpilot_toggles.value("debug_mode").toBool());
if (offroad) {
slayout->setCurrentWidget(home);
developer_sidebar->setVisible(false);
} else {
slayout->setCurrentWidget(onroad);
}
}
void HomeWindow::showDriverView(bool show, bool started) {
if (show) {
if (!started) {
emit closeSettings();
}
slayout->setCurrentWidget(driver_view);
} else {
slayout->setCurrentWidget(home);
}
sidebar->setVisible(show == false);
developer_sidebar->setVisible(false);
}
void HomeWindow::mousePressEvent(QMouseEvent* e) {
// Handle sidebar collapsing
if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
sidebar->setVisible(!sidebar->isVisible());
params.putBool("SidebarOpen", sidebar->isVisible());
}
}
void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) {
HomeWindow::mousePressEvent(e);
const SubMaster &sm = *(uiState()->sm);
if (sm["carParams"].getCarParams().getNotCar()) {
if (onroad->isVisible()) {
slayout->setCurrentWidget(body);
} else if (body->isVisible()) {
slayout->setCurrentWidget(onroad);
}
showSidebar(false);
}
}
// OffroadHome: the offroad home page
OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
QVBoxLayout* main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(40, 40, 40, 40);
// top header
QHBoxLayout* header_layout = new QHBoxLayout();
header_layout->setContentsMargins(0, 0, 0, 0);
header_layout->setSpacing(16);
date = new ElidedLabel();
header_layout->addWidget(date, 0, Qt::AlignHCenter | Qt::AlignLeft);
update_notif = new QPushButton(tr("UPDATE"));
update_notif->setVisible(false);
update_notif->setStyleSheet("background-color: #364DEF;");
QObject::connect(update_notif, &QPushButton::clicked, [=]() { center_layout->setCurrentIndex(1); });
header_layout->addWidget(update_notif, 0, Qt::AlignHCenter | Qt::AlignLeft);
alert_notif = new QPushButton();
alert_notif->setVisible(false);
alert_notif->setStyleSheet("background-color: #E22C2C;");
QObject::connect(alert_notif, &QPushButton::clicked, [=] { center_layout->setCurrentIndex(2); });
header_layout->addWidget(alert_notif, 0, Qt::AlignHCenter | Qt::AlignLeft);
version = new ElidedLabel();
header_layout->addWidget(version, 0, Qt::AlignHCenter | Qt::AlignRight);
main_layout->addLayout(header_layout);
// main content
main_layout->addSpacing(25);
center_layout = new QStackedLayout();
QWidget *home_widget = new QWidget(this);
{
QHBoxLayout *home_layout = new QHBoxLayout(home_widget);
home_layout->setContentsMargins(0, 0, 0, 0);
home_layout->setSpacing(30);
// left: stock prime card in simple mode, StarPilot drive stats otherwise
left_widget = new QStackedWidget(this);
stock_left_widget = new QStackedWidget(this);
QVBoxLayout *left_prime_layout = new QVBoxLayout();
left_prime_layout->setContentsMargins(0, 0, 0, 0);
QWidget *prime_user = new PrimeUserWidget();
prime_user->setStyleSheet(R"(
border-radius: 10px;
background-color: #333333;
)");
left_prime_layout->addWidget(prime_user);
left_prime_layout->addStretch();
stock_left_widget->addWidget(new LayoutWidget(left_prime_layout));
stock_left_widget->addWidget(new PrimeAdWidget);
stock_left_widget->setStyleSheet("border-radius: 10px;");
QObject::connect(uiState()->prime_state, &PrimeState::changed, this, [this]() {
stock_left_widget->setCurrentIndex(uiState()->prime_state->isSubscribed() ? 0 : 1);
});
left_widget->addWidget(stock_left_widget);
QWidget *custom_left_widget = new QWidget(this);
custom_left_stack = new QStackedLayout(custom_left_widget);
custom_left_stack->setContentsMargins(0, 0, 0, 0);
custom_left_stack->addWidget(new DriveStats());
StarPilotDriveSummary *drive_summary = new StarPilotDriveSummary(this);
custom_left_stack->addWidget(drive_summary);
left_widget->addWidget(custom_left_widget);
left_widget->setCurrentIndex(params.getBool("SimpleMode") ? 0 : 1);
QObject::connect(drive_summary, &StarPilotDriveSummary::panelClosed, [this]() {
custom_left_stack->setCurrentIndex(0);
});
QObject::connect(uiState(), &UIState::offroadTransition, [this](bool offroad) {
static bool previouslyOnroad = false;
if (offroad && previouslyOnroad && !params.getBool("SimpleMode")) {
custom_left_stack->setCurrentIndex(1);
}
previouslyOnroad = !offroad;
});
home_layout->addWidget(left_widget, 1);
// right: ExperimentalModeButton, SetupWidget, Random Events Summary
right_widget = new QStackedWidget(this);
right_widget->setFixedWidth(750);
QWidget *default_right = new QWidget(this);
QVBoxLayout *right_column = new QVBoxLayout(default_right);
right_column->setContentsMargins(0, 0, 0, 0);
right_column->setSpacing(30);
ExperimentalModeButton *experimental_mode = new ExperimentalModeButton(this);
QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
right_column->addWidget(experimental_mode, 1);
SetupWidget *setup_widget = new SetupWidget;
QObject::connect(setup_widget, &SetupWidget::openSettings, this, &OffroadHome::openSettings);
right_column->addWidget(setup_widget, 1);
right_widget->addWidget(default_right);
StarPilotDriveSummary *random_events_summary = new StarPilotDriveSummary(this, true);
right_widget->addWidget(random_events_summary);
right_widget->setCurrentIndex(0);
QObject::connect(random_events_summary, &StarPilotDriveSummary::panelClosed, [=]() {
right_widget->setCurrentIndex(0);
});
QObject::connect(uiState(), &UIState::offroadTransition, [this](bool offroad) {
static bool previouslyOnroad = false;
if (offroad && previouslyOnroad && !params.getBool("SimpleMode") &&
starpilotUIState()->starpilot_scene.starpilot_toggles.value("random_events").toBool()) {
right_widget->setCurrentIndex(1);
}
previouslyOnroad = !offroad;
});
home_layout->addWidget(right_widget, 0);
}
center_layout->addWidget(home_widget);
// add update & alerts widgets
update_widget = new UpdateAlert();
QObject::connect(update_widget, &UpdateAlert::dismiss, [=]() { center_layout->setCurrentIndex(0); });
center_layout->addWidget(update_widget);
alerts_widget = new OffroadAlert();
QObject::connect(alerts_widget, &OffroadAlert::dismiss, [=]() { center_layout->setCurrentIndex(0); });
center_layout->addWidget(alerts_widget);
main_layout->addLayout(center_layout, 1);
// set up refresh timer
timer = new QTimer(this);
timer->callOnTimeout(this, &OffroadHome::refresh);
setStyleSheet(R"(
* {
color: white;
}
OffroadHome {
background-color: black;
}
OffroadHome > QPushButton {
padding: 15px 30px;
border-radius: 5px;
font-size: 40px;
font-weight: 500;
}
OffroadHome > QLabel {
font-size: 55px;
}
)");
}
void OffroadHome::showEvent(QShowEvent *event) {
refresh();
timer->start(10 * 1000);
}
void OffroadHome::hideEvent(QHideEvent *event) {
timer->stop();
}
void OffroadHome::refresh() {
bool updateAvailable = update_widget->refresh();
int alerts = alerts_widget->refresh();
// pop-up new notification
int idx = center_layout->currentIndex();
if (!updateAvailable && !alerts) {
idx = 0;
} else if (updateAvailable && (!update_notif->isVisible() || (!alerts && idx == 2))) {
idx = 1;
} else if (alerts && (!alert_notif->isVisible() || (!updateAvailable && idx == 1))) {
idx = 2;
}
center_layout->setCurrentIndex(idx);
update_notif->setVisible(updateAvailable);
alert_notif->setVisible(alerts);
if (alerts) {
alert_notif->setText(QString::number(alerts) + (alerts > 1 ? tr(" ALERTS") : tr(" ALERT")));
}
StarPilotUIState &fs = *starpilotUIState();
StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
const bool simple_mode = params.getBool("SimpleMode");
stock_left_widget->setCurrentIndex(uiState()->prime_state->isSubscribed() ? 0 : 1);
left_widget->setCurrentIndex(simple_mode ? 0 : 1);
if (simple_mode) {
custom_left_stack->setCurrentIndex(0);
right_widget->setCurrentIndex(0);
}
date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d"));
date->setVisible(util::system_time_valid() && !simple_mode);
if (simple_mode) {
version->setText(getBrand() + " " + formatStarPilotDisplayVersionDescription(QString::fromStdString(params.get("UpdaterCurrentDescription"))));
} else {
version->setText(getBrand() + " - " + getStarPilotDisplayVersion() + " - " + cleanModelName(starpilot_toggles.value("model_name").toString()));
}
}
-86
View File
@@ -1,86 +0,0 @@
#pragma once
#include <QFrame>
#include <QLabel>
#include <QPushButton>
#include <QStackedLayout>
#include <QStackedWidget>
#include <QTimer>
#include <QWidget>
#include "common/params.h"
#include "selfdrive/ui/qt/offroad/driverview.h"
#include "selfdrive/ui/qt/body.h"
#include "selfdrive/ui/qt/onroad/onroad_home.h"
#include "selfdrive/ui/qt/sidebar.h"
#include "selfdrive/ui/qt/widgets/controls.h"
#include "selfdrive/ui/qt/widgets/offroad_alerts.h"
#include "selfdrive/ui/ui.h"
#include "starpilot/ui/qt/widgets/developer_sidebar.h"
class OffroadHome : public QFrame {
Q_OBJECT
public:
explicit OffroadHome(QWidget* parent = 0);
signals:
void openSettings(int index = 0, const QString &param = "");
private:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
void refresh();
Params params;
QTimer* timer;
ElidedLabel* version;
QStackedLayout* center_layout;
UpdateAlert *update_widget;
OffroadAlert* alerts_widget;
QPushButton* alert_notif;
QPushButton* update_notif;
ElidedLabel* date;
QStackedWidget *left_widget;
QStackedWidget *stock_left_widget;
QStackedLayout *custom_left_stack;
QStackedWidget *right_widget;
};
class HomeWindow : public QWidget {
Q_OBJECT
public:
explicit HomeWindow(QWidget* parent = 0);
signals:
void openSettings(int index = 0, const QString &param = "");
void closeSettings();
public slots:
void offroadTransition(bool offroad);
void showDriverView(bool show, bool started=false);
void showSidebar(bool show);
protected:
void mousePressEvent(QMouseEvent* e) override;
void mouseDoubleClickEvent(QMouseEvent* e) override;
private:
Sidebar *sidebar;
OffroadHome *home;
OnroadWindow *onroad;
BodyWindow *body;
DriverViewWindow *driver_view;
QStackedLayout *slayout;
DeveloperSidebar *developer_sidebar;
Params params;
private slots:
void updateState(const UIState &s, const StarPilotUIState &fs);
};
-151
View File
@@ -1,151 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'api.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "api.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'api.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_HttpRequest_t {
QByteArrayData data[9];
char stringdata0[107];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_HttpRequest_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_HttpRequest_t qt_meta_stringdata_HttpRequest = {
{
QT_MOC_LITERAL(0, 0, 11), // "HttpRequest"
QT_MOC_LITERAL(1, 12, 11), // "requestDone"
QT_MOC_LITERAL(2, 24, 0), // ""
QT_MOC_LITERAL(3, 25, 8), // "response"
QT_MOC_LITERAL(4, 34, 7), // "success"
QT_MOC_LITERAL(5, 42, 27), // "QNetworkReply::NetworkError"
QT_MOC_LITERAL(6, 70, 5), // "error"
QT_MOC_LITERAL(7, 76, 14), // "requestTimeout"
QT_MOC_LITERAL(8, 91, 15) // "requestFinished"
},
"HttpRequest\0requestDone\0\0response\0"
"success\0QNetworkReply::NetworkError\0"
"error\0requestTimeout\0requestFinished"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_HttpRequest[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
3, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 3, 29, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
7, 0, 36, 2, 0x08 /* Private */,
8, 0, 37, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void, QMetaType::QString, QMetaType::Bool, 0x80000000 | 5, 3, 4, 6,
// slots: parameters
QMetaType::Void,
QMetaType::Void,
0 // eod
};
void HttpRequest::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<HttpRequest *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->requestDone((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< bool(*)>(_a[2])),(*reinterpret_cast< QNetworkReply::NetworkError(*)>(_a[3]))); break;
case 1: _t->requestTimeout(); break;
case 2: _t->requestFinished(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (HttpRequest::*)(const QString & , bool , QNetworkReply::NetworkError );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&HttpRequest::requestDone)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject HttpRequest::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_HttpRequest.data,
qt_meta_data_HttpRequest,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *HttpRequest::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *HttpRequest::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_HttpRequest.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int HttpRequest::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 3)
qt_static_metacall(this, _c, _id, _a);
_id -= 3;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 3)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 3;
}
return _id;
}
// SIGNAL 0
void HttpRequest::requestDone(const QString & _t1, bool _t2, QNetworkReply::NetworkError _t3)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)), const_cast<void*>(reinterpret_cast<const void*>(&_t3)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-195
View File
@@ -1,195 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'body.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "body.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'body.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_RecordButton_t {
QByteArrayData data[1];
char stringdata0[13];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_RecordButton_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_RecordButton_t qt_meta_stringdata_RecordButton = {
{
QT_MOC_LITERAL(0, 0, 12) // "RecordButton"
},
"RecordButton"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_RecordButton[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void RecordButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject RecordButton::staticMetaObject = { {
&QPushButton::staticMetaObject,
qt_meta_stringdata_RecordButton.data,
qt_meta_data_RecordButton,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *RecordButton::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *RecordButton::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_RecordButton.stringdata0))
return static_cast<void*>(this);
return QPushButton::qt_metacast(_clname);
}
int RecordButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QPushButton::qt_metacall(_c, _id, _a);
return _id;
}
struct qt_meta_stringdata_BodyWindow_t {
QByteArrayData data[7];
char stringdata0[59];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_BodyWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_BodyWindow_t qt_meta_stringdata_BodyWindow = {
{
QT_MOC_LITERAL(0, 0, 10), // "BodyWindow"
QT_MOC_LITERAL(1, 11, 11), // "updateState"
QT_MOC_LITERAL(2, 23, 0), // ""
QT_MOC_LITERAL(3, 24, 7), // "UIState"
QT_MOC_LITERAL(4, 32, 1), // "s"
QT_MOC_LITERAL(5, 34, 17), // "offroadTransition"
QT_MOC_LITERAL(6, 52, 6) // "onroad"
},
"BodyWindow\0updateState\0\0UIState\0s\0"
"offroadTransition\0onroad"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_BodyWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 1, 24, 2, 0x08 /* Private */,
5, 1, 27, 2, 0x08 /* Private */,
// slots: parameters
QMetaType::Void, 0x80000000 | 3, 4,
QMetaType::Void, QMetaType::Bool, 6,
0 // eod
};
void BodyWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<BodyWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->updateState((*reinterpret_cast< const UIState(*)>(_a[1]))); break;
case 1: _t->offroadTransition((*reinterpret_cast< bool(*)>(_a[1]))); break;
default: ;
}
}
}
QT_INIT_METAOBJECT const QMetaObject BodyWindow::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_BodyWindow.data,
qt_meta_data_BodyWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *BodyWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *BodyWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_BodyWindow.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int BodyWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-309
View File
@@ -1,309 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'home.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "home.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'home.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_OffroadHome_t {
QByteArrayData data[5];
char stringdata0[38];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_OffroadHome_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_OffroadHome_t qt_meta_stringdata_OffroadHome = {
{
QT_MOC_LITERAL(0, 0, 11), // "OffroadHome"
QT_MOC_LITERAL(1, 12, 12), // "openSettings"
QT_MOC_LITERAL(2, 25, 0), // ""
QT_MOC_LITERAL(3, 26, 5), // "index"
QT_MOC_LITERAL(4, 32, 5) // "param"
},
"OffroadHome\0openSettings\0\0index\0param"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_OffroadHome[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
3, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
3, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 29, 2, 0x06 /* Public */,
1, 1, 34, 2, 0x26 /* Public | MethodCloned */,
1, 0, 37, 2, 0x26 /* Public | MethodCloned */,
// signals: parameters
QMetaType::Void, QMetaType::Int, QMetaType::QString, 3, 4,
QMetaType::Void, QMetaType::Int, 3,
QMetaType::Void,
0 // eod
};
void OffroadHome::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<OffroadHome *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->openSettings((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
case 1: _t->openSettings((*reinterpret_cast< int(*)>(_a[1]))); break;
case 2: _t->openSettings(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (OffroadHome::*)(int , const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&OffroadHome::openSettings)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject OffroadHome::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_OffroadHome.data,
qt_meta_data_OffroadHome,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *OffroadHome::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *OffroadHome::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_OffroadHome.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int OffroadHome::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 3)
qt_static_metacall(this, _c, _id, _a);
_id -= 3;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 3)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 3;
}
return _id;
}
// SIGNAL 0
void OffroadHome::openSettings(int _t1, const QString & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
struct qt_meta_stringdata_HomeWindow_t {
QByteArrayData data[17];
char stringdata0[159];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_HomeWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_HomeWindow_t qt_meta_stringdata_HomeWindow = {
{
QT_MOC_LITERAL(0, 0, 10), // "HomeWindow"
QT_MOC_LITERAL(1, 11, 12), // "openSettings"
QT_MOC_LITERAL(2, 24, 0), // ""
QT_MOC_LITERAL(3, 25, 5), // "index"
QT_MOC_LITERAL(4, 31, 5), // "param"
QT_MOC_LITERAL(5, 37, 13), // "closeSettings"
QT_MOC_LITERAL(6, 51, 17), // "offroadTransition"
QT_MOC_LITERAL(7, 69, 7), // "offroad"
QT_MOC_LITERAL(8, 77, 14), // "showDriverView"
QT_MOC_LITERAL(9, 92, 4), // "show"
QT_MOC_LITERAL(10, 97, 7), // "started"
QT_MOC_LITERAL(11, 105, 11), // "showSidebar"
QT_MOC_LITERAL(12, 117, 11), // "updateState"
QT_MOC_LITERAL(13, 129, 7), // "UIState"
QT_MOC_LITERAL(14, 137, 1), // "s"
QT_MOC_LITERAL(15, 139, 16), // "StarPilotUIState"
QT_MOC_LITERAL(16, 156, 2) // "fs"
},
"HomeWindow\0openSettings\0\0index\0param\0"
"closeSettings\0offroadTransition\0offroad\0"
"showDriverView\0show\0started\0showSidebar\0"
"updateState\0UIState\0s\0StarPilotUIState\0"
"fs"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_HomeWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
9, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
4, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 59, 2, 0x06 /* Public */,
1, 1, 64, 2, 0x26 /* Public | MethodCloned */,
1, 0, 67, 2, 0x26 /* Public | MethodCloned */,
5, 0, 68, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
6, 1, 69, 2, 0x0a /* Public */,
8, 2, 72, 2, 0x0a /* Public */,
8, 1, 77, 2, 0x2a /* Public | MethodCloned */,
11, 1, 80, 2, 0x0a /* Public */,
12, 2, 83, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void, QMetaType::Int, QMetaType::QString, 3, 4,
QMetaType::Void, QMetaType::Int, 3,
QMetaType::Void,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::Bool, 7,
QMetaType::Void, QMetaType::Bool, QMetaType::Bool, 9, 10,
QMetaType::Void, QMetaType::Bool, 9,
QMetaType::Void, QMetaType::Bool, 9,
QMetaType::Void, 0x80000000 | 13, 0x80000000 | 15, 14, 16,
0 // eod
};
void HomeWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<HomeWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->openSettings((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
case 1: _t->openSettings((*reinterpret_cast< int(*)>(_a[1]))); break;
case 2: _t->openSettings(); break;
case 3: _t->closeSettings(); break;
case 4: _t->offroadTransition((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 5: _t->showDriverView((*reinterpret_cast< bool(*)>(_a[1])),(*reinterpret_cast< bool(*)>(_a[2]))); break;
case 6: _t->showDriverView((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 7: _t->showSidebar((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 8: _t->updateState((*reinterpret_cast< const UIState(*)>(_a[1])),(*reinterpret_cast< const StarPilotUIState(*)>(_a[2]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (HomeWindow::*)(int , const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&HomeWindow::openSettings)) {
*result = 0;
return;
}
}
{
using _t = void (HomeWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&HomeWindow::closeSettings)) {
*result = 3;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject HomeWindow::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_HomeWindow.data,
qt_meta_data_HomeWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *HomeWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *HomeWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_HomeWindow.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int HomeWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 9)
qt_static_metacall(this, _c, _id, _a);
_id -= 9;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 9)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 9;
}
return _id;
}
// SIGNAL 0
void HomeWindow::openSettings(int _t1, const QString & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 3
void HomeWindow::closeSettings()
{
QMetaObject::activate(this, &staticMetaObject, 3, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-136
View File
@@ -1,136 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'prime_state.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "prime_state.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'prime_state.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_PrimeState_t {
QByteArrayData data[5];
char stringdata0[48];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_PrimeState_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_PrimeState_t qt_meta_stringdata_PrimeState = {
{
QT_MOC_LITERAL(0, 0, 10), // "PrimeState"
QT_MOC_LITERAL(1, 11, 7), // "changed"
QT_MOC_LITERAL(2, 19, 0), // ""
QT_MOC_LITERAL(3, 20, 16), // "PrimeState::Type"
QT_MOC_LITERAL(4, 37, 10) // "prime_type"
},
"PrimeState\0changed\0\0PrimeState::Type\0"
"prime_type"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_PrimeState[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 1, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void, 0x80000000 | 3, 4,
0 // eod
};
void PrimeState::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<PrimeState *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->changed((*reinterpret_cast< PrimeState::Type(*)>(_a[1]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (PrimeState::*)(PrimeState::Type );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&PrimeState::changed)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject PrimeState::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_PrimeState.data,
qt_meta_data_PrimeState,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *PrimeState::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *PrimeState::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_PrimeState.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int PrimeState::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void PrimeState::changed(PrimeState::Type _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-323
View File
@@ -1,323 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'sidebar.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "sidebar.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'sidebar.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_Sidebar_t {
QByteArrayData data[23];
char stringdata0[236];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_Sidebar_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_Sidebar_t qt_meta_stringdata_Sidebar = {
{
QT_MOC_LITERAL(0, 0, 7), // "Sidebar"
QT_MOC_LITERAL(1, 8, 12), // "openSettings"
QT_MOC_LITERAL(2, 21, 0), // ""
QT_MOC_LITERAL(3, 22, 5), // "index"
QT_MOC_LITERAL(4, 28, 5), // "param"
QT_MOC_LITERAL(5, 34, 12), // "valueChanged"
QT_MOC_LITERAL(6, 47, 17), // "offroadTransition"
QT_MOC_LITERAL(7, 65, 7), // "offroad"
QT_MOC_LITERAL(8, 73, 11), // "updateState"
QT_MOC_LITERAL(9, 85, 7), // "UIState"
QT_MOC_LITERAL(10, 93, 1), // "s"
QT_MOC_LITERAL(11, 95, 16), // "StarPilotUIState"
QT_MOC_LITERAL(12, 112, 2), // "fs"
QT_MOC_LITERAL(13, 115, 13), // "connectStatus"
QT_MOC_LITERAL(14, 129, 10), // "ItemStatus"
QT_MOC_LITERAL(15, 140, 11), // "pandaStatus"
QT_MOC_LITERAL(16, 152, 10), // "tempStatus"
QT_MOC_LITERAL(17, 163, 7), // "netType"
QT_MOC_LITERAL(18, 171, 11), // "netStrength"
QT_MOC_LITERAL(19, 183, 14), // "recordingAudio"
QT_MOC_LITERAL(20, 198, 10), // "chipStatus"
QT_MOC_LITERAL(21, 209, 12), // "memoryStatus"
QT_MOC_LITERAL(22, 222, 13) // "storageStatus"
},
"Sidebar\0openSettings\0\0index\0param\0"
"valueChanged\0offroadTransition\0offroad\0"
"updateState\0UIState\0s\0StarPilotUIState\0"
"fs\0connectStatus\0ItemStatus\0pandaStatus\0"
"tempStatus\0netType\0netStrength\0"
"recordingAudio\0chipStatus\0memoryStatus\0"
"storageStatus"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_Sidebar[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
6, 14, // methods
9, 62, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
4, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 44, 2, 0x06 /* Public */,
1, 1, 49, 2, 0x26 /* Public | MethodCloned */,
1, 0, 52, 2, 0x26 /* Public | MethodCloned */,
5, 0, 53, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
6, 1, 54, 2, 0x0a /* Public */,
8, 2, 57, 2, 0x0a /* Public */,
// signals: parameters
QMetaType::Void, QMetaType::Int, QMetaType::QString, 3, 4,
QMetaType::Void, QMetaType::Int, 3,
QMetaType::Void,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::Bool, 7,
QMetaType::Void, 0x80000000 | 9, 0x80000000 | 11, 10, 12,
// properties: name, type, flags
13, 0x80000000 | 14, 0x0049500b,
15, 0x80000000 | 14, 0x0049500b,
16, 0x80000000 | 14, 0x0049500b,
17, QMetaType::QString, 0x00495003,
18, QMetaType::Int, 0x00495003,
19, QMetaType::Bool, 0x00495003,
20, 0x80000000 | 14, 0x0049500b,
21, 0x80000000 | 14, 0x0049500b,
22, 0x80000000 | 14, 0x0049500b,
// properties: notify_signal_id
3,
3,
3,
3,
3,
3,
3,
3,
3,
0 // eod
};
void Sidebar::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<Sidebar *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->openSettings((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
case 1: _t->openSettings((*reinterpret_cast< int(*)>(_a[1]))); break;
case 2: _t->openSettings(); break;
case 3: _t->valueChanged(); break;
case 4: _t->offroadTransition((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 5: _t->updateState((*reinterpret_cast< const UIState(*)>(_a[1])),(*reinterpret_cast< const StarPilotUIState(*)>(_a[2]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (Sidebar::*)(int , const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Sidebar::openSettings)) {
*result = 0;
return;
}
}
{
using _t = void (Sidebar::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&Sidebar::valueChanged)) {
*result = 3;
return;
}
}
} else if (_c == QMetaObject::RegisterPropertyMetaType) {
switch (_id) {
default: *reinterpret_cast<int*>(_a[0]) = -1; break;
case 8:
case 7:
case 6:
case 2:
case 1:
case 0:
*reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< ItemStatus >(); break;
}
}
#ifndef QT_NO_PROPERTIES
else if (_c == QMetaObject::ReadProperty) {
auto *_t = static_cast<Sidebar *>(_o);
Q_UNUSED(_t)
void *_v = _a[0];
switch (_id) {
case 0: *reinterpret_cast< ItemStatus*>(_v) = _t->connect_status; break;
case 1: *reinterpret_cast< ItemStatus*>(_v) = _t->panda_status; break;
case 2: *reinterpret_cast< ItemStatus*>(_v) = _t->temp_status; break;
case 3: *reinterpret_cast< QString*>(_v) = _t->net_type; break;
case 4: *reinterpret_cast< int*>(_v) = _t->net_strength; break;
case 5: *reinterpret_cast< bool*>(_v) = _t->recording_audio; break;
case 6: *reinterpret_cast< ItemStatus*>(_v) = _t->chip_status; break;
case 7: *reinterpret_cast< ItemStatus*>(_v) = _t->memory_status; break;
case 8: *reinterpret_cast< ItemStatus*>(_v) = _t->storage_status; break;
default: break;
}
} else if (_c == QMetaObject::WriteProperty) {
auto *_t = static_cast<Sidebar *>(_o);
Q_UNUSED(_t)
void *_v = _a[0];
switch (_id) {
case 0:
if (_t->connect_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->connect_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 1:
if (_t->panda_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->panda_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 2:
if (_t->temp_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->temp_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 3:
if (_t->net_type != *reinterpret_cast< QString*>(_v)) {
_t->net_type = *reinterpret_cast< QString*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 4:
if (_t->net_strength != *reinterpret_cast< int*>(_v)) {
_t->net_strength = *reinterpret_cast< int*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 5:
if (_t->recording_audio != *reinterpret_cast< bool*>(_v)) {
_t->recording_audio = *reinterpret_cast< bool*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 6:
if (_t->chip_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->chip_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 7:
if (_t->memory_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->memory_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
case 8:
if (_t->storage_status != *reinterpret_cast< ItemStatus*>(_v)) {
_t->storage_status = *reinterpret_cast< ItemStatus*>(_v);
Q_EMIT _t->valueChanged();
}
break;
default: break;
}
} else if (_c == QMetaObject::ResetProperty) {
}
#endif // QT_NO_PROPERTIES
}
QT_INIT_METAOBJECT const QMetaObject Sidebar::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_Sidebar.data,
qt_meta_data_Sidebar,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *Sidebar::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *Sidebar::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_Sidebar.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int Sidebar::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 6)
qt_static_metacall(this, _c, _id, _a);
_id -= 6;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 6)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 6;
}
#ifndef QT_NO_PROPERTIES
else if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty
|| _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType) {
qt_static_metacall(this, _c, _id, _a);
_id -= 9;
} else if (_c == QMetaObject::QueryPropertyDesignable) {
_id -= 9;
} else if (_c == QMetaObject::QueryPropertyScriptable) {
_id -= 9;
} else if (_c == QMetaObject::QueryPropertyStored) {
_id -= 9;
} else if (_c == QMetaObject::QueryPropertyEditable) {
_id -= 9;
} else if (_c == QMetaObject::QueryPropertyUser) {
_id -= 9;
}
#endif // QT_NO_PROPERTIES
return _id;
}
// SIGNAL 0
void Sidebar::openSettings(int _t1, const QString & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 3
void Sidebar::valueChanged()
{
QMetaObject::activate(this, &staticMetaObject, 3, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-136
View File
@@ -1,136 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'util.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "util.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'util.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_ParamWatcher_t {
QByteArrayData data[5];
char stringdata0[50];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_ParamWatcher_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_ParamWatcher_t qt_meta_stringdata_ParamWatcher = {
{
QT_MOC_LITERAL(0, 0, 12), // "ParamWatcher"
QT_MOC_LITERAL(1, 13, 12), // "paramChanged"
QT_MOC_LITERAL(2, 26, 0), // ""
QT_MOC_LITERAL(3, 27, 10), // "param_name"
QT_MOC_LITERAL(4, 38, 11) // "param_value"
},
"ParamWatcher\0paramChanged\0\0param_name\0"
"param_value"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_ParamWatcher[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void, QMetaType::QString, QMetaType::QString, 3, 4,
0 // eod
};
void ParamWatcher::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<ParamWatcher *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->paramChanged((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (ParamWatcher::*)(const QString & , const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&ParamWatcher::paramChanged)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject ParamWatcher::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_ParamWatcher.data,
qt_meta_data_ParamWatcher,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *ParamWatcher::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *ParamWatcher::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_ParamWatcher.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int ParamWatcher::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void ParamWatcher::paramChanged(const QString & _t1, const QString & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-94
View File
@@ -1,94 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'window.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "window.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'window.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_MainWindow_t {
QByteArrayData data[1];
char stringdata0[11];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_MainWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_MainWindow_t qt_meta_stringdata_MainWindow = {
{
QT_MOC_LITERAL(0, 0, 10) // "MainWindow"
},
"MainWindow"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_MainWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject MainWindow::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_MainWindow.data,
qt_meta_data_MainWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *MainWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *MainWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_MainWindow.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-519
View File
@@ -1,519 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'networking.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "networking.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'networking.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_WifiItem_t {
QByteArrayData data[6];
char stringdata0[51];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_WifiItem_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_WifiItem_t qt_meta_stringdata_WifiItem = {
{
QT_MOC_LITERAL(0, 0, 8), // "WifiItem"
QT_MOC_LITERAL(1, 9, 16), // "connectToNetwork"
QT_MOC_LITERAL(2, 26, 0), // ""
QT_MOC_LITERAL(3, 27, 7), // "Network"
QT_MOC_LITERAL(4, 35, 1), // "n"
QT_MOC_LITERAL(5, 37, 13) // "forgotNetwork"
},
"WifiItem\0connectToNetwork\0\0Network\0n\0"
"forgotNetwork"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_WifiItem[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 1, 24, 2, 0x06 /* Public */,
5, 1, 27, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void, 0x80000000 | 3, 4,
QMetaType::Void, 0x80000000 | 3, 4,
0 // eod
};
void WifiItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<WifiItem *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->connectToNetwork((*reinterpret_cast< const Network(*)>(_a[1]))); break;
case 1: _t->forgotNetwork((*reinterpret_cast< const Network(*)>(_a[1]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (WifiItem::*)(const Network );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&WifiItem::connectToNetwork)) {
*result = 0;
return;
}
}
{
using _t = void (WifiItem::*)(const Network );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&WifiItem::forgotNetwork)) {
*result = 1;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject WifiItem::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_WifiItem.data,
qt_meta_data_WifiItem,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *WifiItem::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *WifiItem::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_WifiItem.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int WifiItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
// SIGNAL 0
void WifiItem::connectToNetwork(const Network _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 1
void WifiItem::forgotNetwork(const Network _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
struct qt_meta_stringdata_WifiUI_t {
QByteArrayData data[6];
char stringdata0[43];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_WifiUI_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_WifiUI_t qt_meta_stringdata_WifiUI = {
{
QT_MOC_LITERAL(0, 0, 6), // "WifiUI"
QT_MOC_LITERAL(1, 7, 16), // "connectToNetwork"
QT_MOC_LITERAL(2, 24, 0), // ""
QT_MOC_LITERAL(3, 25, 7), // "Network"
QT_MOC_LITERAL(4, 33, 1), // "n"
QT_MOC_LITERAL(5, 35, 7) // "refresh"
},
"WifiUI\0connectToNetwork\0\0Network\0n\0"
"refresh"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_WifiUI[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 1, 24, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
5, 0, 27, 2, 0x0a /* Public */,
// signals: parameters
QMetaType::Void, 0x80000000 | 3, 4,
// slots: parameters
QMetaType::Void,
0 // eod
};
void WifiUI::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<WifiUI *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->connectToNetwork((*reinterpret_cast< const Network(*)>(_a[1]))); break;
case 1: _t->refresh(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (WifiUI::*)(const Network );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&WifiUI::connectToNetwork)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject WifiUI::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_WifiUI.data,
qt_meta_data_WifiUI,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *WifiUI::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *WifiUI::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_WifiUI.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int WifiUI::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
// SIGNAL 0
void WifiUI::connectToNetwork(const Network _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
struct qt_meta_stringdata_AdvancedNetworking_t {
QByteArrayData data[7];
char stringdata0[75];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_AdvancedNetworking_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_AdvancedNetworking_t qt_meta_stringdata_AdvancedNetworking = {
{
QT_MOC_LITERAL(0, 0, 18), // "AdvancedNetworking"
QT_MOC_LITERAL(1, 19, 9), // "backPress"
QT_MOC_LITERAL(2, 29, 0), // ""
QT_MOC_LITERAL(3, 30, 17), // "requestWifiScreen"
QT_MOC_LITERAL(4, 48, 15), // "toggleTethering"
QT_MOC_LITERAL(5, 64, 2), // "id"
QT_MOC_LITERAL(6, 67, 7) // "refresh"
},
"AdvancedNetworking\0backPress\0\0"
"requestWifiScreen\0toggleTethering\0id\0"
"refresh"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_AdvancedNetworking[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
4, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 34, 2, 0x06 /* Public */,
3, 0, 35, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
4, 1, 36, 2, 0x0a /* Public */,
6, 0, 39, 2, 0x0a /* Public */,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::Int, 5,
QMetaType::Void,
0 // eod
};
void AdvancedNetworking::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<AdvancedNetworking *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->backPress(); break;
case 1: _t->requestWifiScreen(); break;
case 2: _t->toggleTethering((*reinterpret_cast< int(*)>(_a[1]))); break;
case 3: _t->refresh(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (AdvancedNetworking::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&AdvancedNetworking::backPress)) {
*result = 0;
return;
}
}
{
using _t = void (AdvancedNetworking::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&AdvancedNetworking::requestWifiScreen)) {
*result = 1;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject AdvancedNetworking::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_AdvancedNetworking.data,
qt_meta_data_AdvancedNetworking,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *AdvancedNetworking::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *AdvancedNetworking::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_AdvancedNetworking.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int AdvancedNetworking::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 4)
qt_static_metacall(this, _c, _id, _a);
_id -= 4;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 4)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 4;
}
return _id;
}
// SIGNAL 0
void AdvancedNetworking::backPress()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
// SIGNAL 1
void AdvancedNetworking::requestWifiScreen()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
struct qt_meta_stringdata_Networking_t {
QByteArrayData data[8];
char stringdata0[66];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_Networking_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_Networking_t qt_meta_stringdata_Networking = {
{
QT_MOC_LITERAL(0, 0, 10), // "Networking"
QT_MOC_LITERAL(1, 11, 7), // "refresh"
QT_MOC_LITERAL(2, 19, 0), // ""
QT_MOC_LITERAL(3, 20, 16), // "connectToNetwork"
QT_MOC_LITERAL(4, 37, 7), // "Network"
QT_MOC_LITERAL(5, 45, 1), // "n"
QT_MOC_LITERAL(6, 47, 13), // "wrongPassword"
QT_MOC_LITERAL(7, 61, 4) // "ssid"
},
"Networking\0refresh\0\0connectToNetwork\0"
"Network\0n\0wrongPassword\0ssid"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_Networking[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
3, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 0, 29, 2, 0x0a /* Public */,
3, 1, 30, 2, 0x08 /* Private */,
6, 1, 33, 2, 0x08 /* Private */,
// slots: parameters
QMetaType::Void,
QMetaType::Void, 0x80000000 | 4, 5,
QMetaType::Void, QMetaType::QString, 7,
0 // eod
};
void Networking::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<Networking *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->refresh(); break;
case 1: _t->connectToNetwork((*reinterpret_cast< const Network(*)>(_a[1]))); break;
case 2: _t->wrongPassword((*reinterpret_cast< const QString(*)>(_a[1]))); break;
default: ;
}
}
}
QT_INIT_METAOBJECT const QMetaObject Networking::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_Networking.data,
qt_meta_data_Networking,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *Networking::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *Networking::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_Networking.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int Networking::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 3)
qt_static_metacall(this, _c, _id, _a);
_id -= 3;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 3)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 3;
}
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-201
View File
@@ -1,201 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'wifi_manager.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "wifi_manager.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'wifi_manager.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_WifiManager_t {
QByteArrayData data[22];
char stringdata0[276];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_WifiManager_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_WifiManager_t qt_meta_stringdata_WifiManager = {
{
QT_MOC_LITERAL(0, 0, 11), // "WifiManager"
QT_MOC_LITERAL(1, 12, 13), // "wrongPassword"
QT_MOC_LITERAL(2, 26, 0), // ""
QT_MOC_LITERAL(3, 27, 4), // "ssid"
QT_MOC_LITERAL(4, 32, 13), // "refreshSignal"
QT_MOC_LITERAL(5, 46, 11), // "stateChange"
QT_MOC_LITERAL(6, 58, 9), // "new_state"
QT_MOC_LITERAL(7, 68, 14), // "previous_state"
QT_MOC_LITERAL(8, 83, 13), // "change_reason"
QT_MOC_LITERAL(9, 97, 14), // "propertyChange"
QT_MOC_LITERAL(10, 112, 9), // "interface"
QT_MOC_LITERAL(11, 122, 5), // "props"
QT_MOC_LITERAL(12, 128, 17), // "invalidated_props"
QT_MOC_LITERAL(13, 146, 11), // "deviceAdded"
QT_MOC_LITERAL(14, 158, 15), // "QDBusObjectPath"
QT_MOC_LITERAL(15, 174, 4), // "path"
QT_MOC_LITERAL(16, 179, 17), // "connectionRemoved"
QT_MOC_LITERAL(17, 197, 13), // "newConnection"
QT_MOC_LITERAL(18, 211, 15), // "refreshFinished"
QT_MOC_LITERAL(19, 227, 24), // "QDBusPendingCallWatcher*"
QT_MOC_LITERAL(20, 252, 4), // "call"
QT_MOC_LITERAL(21, 257, 18) // "tetheringActivated"
},
"WifiManager\0wrongPassword\0\0ssid\0"
"refreshSignal\0stateChange\0new_state\0"
"previous_state\0change_reason\0"
"propertyChange\0interface\0props\0"
"invalidated_props\0deviceAdded\0"
"QDBusObjectPath\0path\0connectionRemoved\0"
"newConnection\0refreshFinished\0"
"QDBusPendingCallWatcher*\0call\0"
"tetheringActivated"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_WifiManager[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
9, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 1, 59, 2, 0x06 /* Public */,
4, 0, 62, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
5, 3, 63, 2, 0x08 /* Private */,
9, 3, 70, 2, 0x08 /* Private */,
13, 1, 77, 2, 0x08 /* Private */,
16, 1, 80, 2, 0x08 /* Private */,
17, 1, 83, 2, 0x08 /* Private */,
18, 1, 86, 2, 0x08 /* Private */,
21, 1, 89, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void, QMetaType::QString, 3,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::UInt, QMetaType::UInt, QMetaType::UInt, 6, 7, 8,
QMetaType::Void, QMetaType::QString, QMetaType::QVariantMap, QMetaType::QStringList, 10, 11, 12,
QMetaType::Void, 0x80000000 | 14, 15,
QMetaType::Void, 0x80000000 | 14, 15,
QMetaType::Void, 0x80000000 | 14, 15,
QMetaType::Void, 0x80000000 | 19, 20,
QMetaType::Void, 0x80000000 | 19, 20,
0 // eod
};
void WifiManager::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<WifiManager *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->wrongPassword((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 1: _t->refreshSignal(); break;
case 2: _t->stateChange((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2])),(*reinterpret_cast< uint(*)>(_a[3]))); break;
case 3: _t->propertyChange((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< const QVariantMap(*)>(_a[2])),(*reinterpret_cast< const QStringList(*)>(_a[3]))); break;
case 4: _t->deviceAdded((*reinterpret_cast< const QDBusObjectPath(*)>(_a[1]))); break;
case 5: _t->connectionRemoved((*reinterpret_cast< const QDBusObjectPath(*)>(_a[1]))); break;
case 6: _t->newConnection((*reinterpret_cast< const QDBusObjectPath(*)>(_a[1]))); break;
case 7: _t->refreshFinished((*reinterpret_cast< QDBusPendingCallWatcher*(*)>(_a[1]))); break;
case 8: _t->tetheringActivated((*reinterpret_cast< QDBusPendingCallWatcher*(*)>(_a[1]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (WifiManager::*)(const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&WifiManager::wrongPassword)) {
*result = 0;
return;
}
}
{
using _t = void (WifiManager::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&WifiManager::refreshSignal)) {
*result = 1;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject WifiManager::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_WifiManager.data,
qt_meta_data_WifiManager,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *WifiManager::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *WifiManager::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_WifiManager.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int WifiManager::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 9)
qt_static_metacall(this, _c, _id, _a);
_id -= 9;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 9)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 9;
}
return _id;
}
// SIGNAL 0
void WifiManager::wrongPassword(const QString & _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 1
void WifiManager::refreshSignal()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-420
View File
@@ -1,420 +0,0 @@
#include "selfdrive/ui/qt/network/networking.h"
#include <algorithm>
#include <QHBoxLayout>
#include <QScrollBar>
#include <QStyle>
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/controls.h"
#include "selfdrive/ui/qt/widgets/scrollview.h"
static const int ICON_WIDTH = 49;
// Networking functions
Networking::Networking(QWidget* parent, bool show_advanced) : QFrame(parent) {
main_layout = new QStackedLayout(this);
wifi = new WifiManager(this);
connect(wifi, &WifiManager::refreshSignal, this, &Networking::refresh);
connect(wifi, &WifiManager::wrongPassword, this, &Networking::wrongPassword);
wifiScreen = new QWidget(this);
QVBoxLayout* vlayout = new QVBoxLayout(wifiScreen);
vlayout->setContentsMargins(20, 20, 20, 20);
if (show_advanced) {
QPushButton* advancedSettings = new QPushButton(tr("Advanced"));
advancedSettings->setObjectName("advanced_btn");
advancedSettings->setStyleSheet("margin-right: 30px;");
advancedSettings->setFixedSize(400, 100);
connect(advancedSettings, &QPushButton::clicked, [=]() { main_layout->setCurrentWidget(an); });
vlayout->addSpacing(10);
vlayout->addWidget(advancedSettings, 0, Qt::AlignRight);
vlayout->addSpacing(10);
}
wifiWidget = new WifiUI(this, wifi);
wifiWidget->setObjectName("wifiWidget");
connect(wifiWidget, &WifiUI::connectToNetwork, this, &Networking::connectToNetwork);
ScrollView *wifiScroller = new ScrollView(wifiWidget, this);
wifiScroller->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
vlayout->addWidget(wifiScroller, 1);
main_layout->addWidget(wifiScreen);
an = new AdvancedNetworking(this, wifi);
connect(an, &AdvancedNetworking::backPress, [=]() { main_layout->setCurrentWidget(wifiScreen); });
connect(an, &AdvancedNetworking::requestWifiScreen, [=]() { main_layout->setCurrentWidget(wifiScreen); });
main_layout->addWidget(an);
QPalette pal = palette();
pal.setColor(QPalette::Window, QColor(0x29, 0x29, 0x29));
setAutoFillBackground(true);
setPalette(pal);
setStyleSheet(R"(
#wifiWidget > QPushButton, #back_btn, #advanced_btn {
font-size: 50px;
margin: 0px;
padding: 15px;
border-width: 0;
border-radius: 30px;
color: #dddddd;
background-color: #393939;
}
#back_btn:pressed, #advanced_btn:pressed {
background-color: #4a4a4a;
}
)");
main_layout->setCurrentWidget(wifiScreen);
}
void Networking::setPrimeType(PrimeState::Type type) {
an->setGsmVisible(type == PrimeState::PRIME_TYPE_NONE || type == PrimeState::PRIME_TYPE_LITE);
wifi->ipv4_forward = (type == PrimeState::PRIME_TYPE_NONE || type == PrimeState::PRIME_TYPE_LITE);
}
void Networking::refresh() {
wifiWidget->refresh();
an->refresh();
}
void Networking::connectToNetwork(const Network n) {
if (wifi->isKnownConnection(n.ssid)) {
wifi->activateWifiConnection(n.ssid);
} else if (n.security_type == SecurityType::OPEN) {
wifi->connect(n, false);
} else if (n.security_type == SecurityType::WPA) {
QString pass = InputDialog::getText(tr("Enter password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8);
if (!pass.isEmpty()) {
wifi->connect(n, false, pass);
}
}
}
void Networking::wrongPassword(const QString &ssid) {
if (wifi->seenNetworks.contains(ssid)) {
const Network &n = wifi->seenNetworks.value(ssid);
QString pass = InputDialog::getText(tr("Wrong password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8);
if (!pass.isEmpty()) {
wifi->connect(n, false, pass);
}
}
}
void Networking::showEvent(QShowEvent *event) {
wifi->start();
}
void Networking::hideEvent(QHideEvent *event) {
main_layout->setCurrentWidget(wifiScreen);
wifi->stop();
}
// AdvancedNetworking functions
AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi) {
QVBoxLayout* main_layout = new QVBoxLayout(this);
main_layout->setMargin(40);
main_layout->setSpacing(20);
// Back button
QPushButton* back = new QPushButton(tr("Back"));
back->setObjectName("back_btn");
back->setFixedSize(400, 100);
connect(back, &QPushButton::clicked, [=]() { emit backPress(); });
main_layout->addWidget(back, 0, Qt::AlignLeft);
ListWidget *list = new ListWidget(this);
// Enable tethering layout
std::vector<QString> tetheringSelection{tr("Off"), tr("Always"), tr("Only Onroad"), tr("Until Reboot")};
tetheringToggle = new ButtonParamControl("TetheringEnabled", tr("Enable Tethering"),
tr("Share your device's internet connection with other devices, either all the time or only while driving."),
"", tetheringSelection);
if (params.getInt("TetheringEnabled") == 3) {
params.remove("TetheringEnabled");
tetheringToggle->setCheckedButton(0);
}
list->addItem(tetheringToggle);
QObject::connect(tetheringToggle, &MultiButtonControl::buttonClicked, this, &AdvancedNetworking::toggleTethering);
// Change tethering password
ButtonControl *editPasswordButton = new ButtonControl(tr("Tethering Password"), tr("EDIT"));
connect(editPasswordButton, &ButtonControl::clicked, [=]() {
QString pass = InputDialog::getText(tr("Enter new tethering password"), this, "", true, 8, wifi->getTetheringPassword());
if (!pass.isEmpty()) {
wifi->changeTetheringPassword(pass);
}
});
list->addItem(editPasswordButton);
// IP address
ipLabel = new LabelControl(tr("IP Address"), wifi->ipv4_address);
list->addItem(ipLabel);
// Roaming toggle
const bool roamingEnabled = params.getBool("GsmRoaming");
roamingToggle = new ToggleControl(tr("Enable Roaming"), "", "", roamingEnabled);
QObject::connect(roamingToggle, &ToggleControl::toggleFlipped, [=](bool state) {
params.putBool("GsmRoaming", state);
wifi->updateGsmSettings(state, QString::fromStdString(params.get("GsmApn")), params.getBool("GsmMetered"));
});
list->addItem(roamingToggle);
// APN settings
editApnButton = new ButtonControl(tr("APN Setting"), tr("EDIT"));
connect(editApnButton, &ButtonControl::clicked, [=]() {
const QString cur_apn = QString::fromStdString(params.get("GsmApn"));
QString apn = InputDialog::getText(tr("Enter APN"), this, tr("leave blank for automatic configuration"), false, -1, cur_apn).trimmed();
if (apn.isEmpty()) {
params.remove("GsmApn");
} else {
params.put("GsmApn", apn.toStdString());
}
wifi->updateGsmSettings(params.getBool("GsmRoaming"), apn, params.getBool("GsmMetered"));
});
list->addItem(editApnButton);
// Cellular metered toggle (prime lite or none)
const bool metered = params.getBool("GsmMetered");
cellularMeteredToggle = new ToggleControl(tr("Cellular Metered"), tr("Prevent large data uploads when on a metered cellular connection"), "", metered);
QObject::connect(cellularMeteredToggle, &SshToggle::toggleFlipped, [=](bool state) {
params.putBool("GsmMetered", state);
wifi->updateGsmSettings(params.getBool("GsmRoaming"), QString::fromStdString(params.get("GsmApn")), state);
});
list->addItem(cellularMeteredToggle);
// Wi-Fi metered toggle
std::vector<QString> metered_button_texts{tr("default"), tr("metered"), tr("unmetered")};
wifiMeteredToggle = new MultiButtonControl(tr("Wi-Fi Network Metered"), tr("Prevent large data uploads when on a metered Wi-Fi connection"), "", metered_button_texts);
QObject::connect(wifiMeteredToggle, &MultiButtonControl::buttonClicked, [=](int id) {
wifiMeteredToggle->setEnabled(false);
MeteredType metered = MeteredType::UNKNOWN;
if (id == NM_METERED_YES) {
metered = MeteredType::YES;
} else if (id == NM_METERED_NO) {
metered = MeteredType::NO;
}
auto pending_call = wifi->setCurrentNetworkMetered(metered);
if (pending_call) {
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(*pending_call);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=]() {
refresh();
watcher->deleteLater();
});
}
});
list->addItem(wifiMeteredToggle);
// Hidden Network
hiddenNetworkButton = new ButtonControl(tr("Hidden Network"), tr("CONNECT"));
connect(hiddenNetworkButton, &ButtonControl::clicked, [=]() {
QString ssid = InputDialog::getText(tr("Enter SSID"), this, "", false, 1);
if (!ssid.isEmpty()) {
QString pass = InputDialog::getText(tr("Enter password"), this, tr("for \"%1\"").arg(ssid), true, -1);
Network hidden_network;
hidden_network.ssid = ssid.toUtf8();
if (!pass.isEmpty()) {
hidden_network.security_type = SecurityType::WPA;
wifi->connect(hidden_network, true, pass);
} else {
wifi->connect(hidden_network, true);
}
emit requestWifiScreen();
}
});
list->addItem(hiddenNetworkButton);
// Set initial config
wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn")), metered);
main_layout->addWidget(new ScrollView(list, this));
main_layout->addStretch(1);
}
void AdvancedNetworking::setGsmVisible(bool visible) {
roamingToggle->setVisible(visible);
editApnButton->setVisible(visible);
cellularMeteredToggle->setVisible(visible);
}
void AdvancedNetworking::refresh() {
ipLabel->setText(wifi->ipv4_address);
tetheringToggle->setEnabled(true);
if (wifi->isTetheringEnabled() || wifi->ipv4_address == "") {
wifiMeteredToggle->setEnabled(false);
wifiMeteredToggle->setCheckedButton(0);
} else if (wifi->ipv4_address != "") {
MeteredType metered = wifi->currentNetworkMetered();
wifiMeteredToggle->setEnabled(true);
wifiMeteredToggle->setCheckedButton(static_cast<int>(metered));
}
update();
}
void AdvancedNetworking::toggleTethering(int id) {
wifi->setTetheringEnabled(id == 1 || id == 2 && uiState()->scene.started || id == 3);
tetheringToggle->setEnabled(false);
if (id != 0) {
wifiMeteredToggle->setEnabled(false);
wifiMeteredToggle->setCheckedButton(0);
}
}
// WifiUI functions
WifiUI::WifiUI(QWidget *parent, WifiManager* wifi) : QWidget(parent), wifi(wifi) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
main_layout->setSpacing(0);
// load imgs
for (const auto &s : {"low", "medium", "high", "full"}) {
QPixmap pix(ASSET_PATH + "/icons/wifi_strength_" + s + ".svg");
strengths.push_back(pix.scaledToHeight(68, Qt::SmoothTransformation));
}
lock = QPixmap(ASSET_PATH + "icons/lock_closed.svg").scaledToWidth(ICON_WIDTH, Qt::SmoothTransformation);
checkmark = QPixmap(ASSET_PATH + "icons/checkmark.svg").scaledToWidth(ICON_WIDTH, Qt::SmoothTransformation);
circled_slash = QPixmap(ASSET_PATH + "icons/circled_slash.svg").scaledToWidth(ICON_WIDTH, Qt::SmoothTransformation);
scanningLabel = new QLabel(tr("Scanning for networks..."));
scanningLabel->setStyleSheet("font-size: 65px;");
main_layout->addWidget(scanningLabel, 0, Qt::AlignCenter);
wifi_list_widget = new ListWidget(this);
wifi_list_widget->setVisible(false);
main_layout->addWidget(wifi_list_widget);
setStyleSheet(R"(
QScrollBar::handle:vertical {
min-height: 0px;
border-radius: 4px;
background-color: #8A8A8A;
}
#forgetBtn {
font-size: 32px;
font-weight: 600;
color: #292929;
background-color: #BDBDBD;
border-width: 1px solid #828282;
border-radius: 5px;
padding: 40px;
padding-bottom: 16px;
padding-top: 16px;
}
#forgetBtn:pressed {
background-color: #828282;
}
#connecting {
font-size: 32px;
font-weight: 600;
color: white;
border-radius: 0;
padding: 27px;
padding-left: 43px;
padding-right: 43px;
background-color: black;
}
#ssidLabel {
text-align: left;
border: none;
padding-top: 50px;
padding-bottom: 50px;
}
#ssidLabel:disabled {
color: #696969;
}
)");
}
void WifiUI::refresh() {
bool is_empty = wifi->seenNetworks.isEmpty();
scanningLabel->setVisible(is_empty);
wifi_list_widget->setVisible(!is_empty);
if (is_empty) return;
setUpdatesEnabled(false);
const bool is_tethering_enabled = wifi->isTetheringEnabled();
QList<Network> sortedNetworks = wifi->seenNetworks.values();
std::sort(sortedNetworks.begin(), sortedNetworks.end(), compare_by_strength);
int n = 0;
for (Network &network : sortedNetworks) {
QPixmap status_icon;
if (network.connected == ConnectedType::CONNECTED) {
status_icon = checkmark;
} else if (network.security_type == SecurityType::UNSUPPORTED) {
status_icon = circled_slash;
} else if (network.security_type == SecurityType::WPA) {
status_icon = lock;
}
bool show_forget_btn = wifi->isKnownConnection(network.ssid) && !is_tethering_enabled;
QPixmap strength = strengths[strengthLevel(network.strength)];
auto item = getItem(n++);
item->setItem(network, status_icon, show_forget_btn, strength);
item->setVisible(true);
}
for (; n < wifi_items.size(); ++n) wifi_items[n]->setVisible(false);
setUpdatesEnabled(true);
}
WifiItem *WifiUI::getItem(int n) {
auto item = n < wifi_items.size() ? wifi_items[n] : wifi_items.emplace_back(new WifiItem(tr("CONNECTING..."), tr("FORGET")));
if (!item->parentWidget()) {
QObject::connect(item, &WifiItem::connectToNetwork, this, &WifiUI::connectToNetwork);
QObject::connect(item, &WifiItem::forgotNetwork, [this](const Network n) {
if (ConfirmationDialog::confirm(tr("Forget Wi-Fi Network \"%1\"?").arg(QString::fromUtf8(n.ssid)), tr("Forget"), this))
wifi->forgetConnection(n.ssid);
});
wifi_list_widget->addItem(item);
}
return item;
}
// WifiItem
WifiItem::WifiItem(const QString &connecting_text, const QString &forget_text, QWidget *parent) : QWidget(parent) {
QHBoxLayout *hlayout = new QHBoxLayout(this);
hlayout->setContentsMargins(44, 0, 73, 0);
hlayout->setSpacing(50);
hlayout->addWidget(ssidLabel = new ElidedLabel());
ssidLabel->setObjectName("ssidLabel");
ssidLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayout->addWidget(connecting = new QPushButton(connecting_text), 0, Qt::AlignRight);
connecting->setObjectName("connecting");
hlayout->addWidget(forgetBtn = new QPushButton(forget_text), 0, Qt::AlignRight);
forgetBtn->setObjectName("forgetBtn");
hlayout->addWidget(iconLabel = new QLabel(), 0, Qt::AlignRight);
hlayout->addWidget(strengthLabel = new QLabel(), 0, Qt::AlignRight);
iconLabel->setFixedWidth(ICON_WIDTH);
QObject::connect(forgetBtn, &QPushButton::clicked, [this]() { emit forgotNetwork(network); });
QObject::connect(ssidLabel, &ElidedLabel::clicked, [this]() {
if (network.connected == ConnectedType::DISCONNECTED) emit connectToNetwork(network);
});
}
void WifiItem::setItem(const Network &n, const QPixmap &status_icon, bool show_forget_btn, const QPixmap &strength_icon) {
network = n;
ssidLabel->setText(n.ssid);
ssidLabel->setEnabled(n.security_type != SecurityType::UNSUPPORTED);
ssidLabel->setFont(InterFont(55, network.connected == ConnectedType::DISCONNECTED ? QFont::Normal : QFont::Bold));
connecting->setVisible(n.connected == ConnectedType::CONNECTING);
forgetBtn->setVisible(show_forget_btn);
iconLabel->setPixmap(status_icon);
strengthLabel->setPixmap(strength_icon);
}
-106
View File
@@ -1,106 +0,0 @@
#pragma once
#include <vector>
#include "selfdrive/ui/qt/network/wifi_manager.h"
#include "selfdrive/ui/qt/prime_state.h"
#include "selfdrive/ui/qt/widgets/input.h"
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
#include "selfdrive/ui/qt/widgets/toggle.h"
#include "selfdrive/ui/ui.h"
class WifiItem : public QWidget {
Q_OBJECT
public:
explicit WifiItem(const QString &connecting_text, const QString &forget_text, QWidget* parent = nullptr);
void setItem(const Network& n, const QPixmap &icon, bool show_forget_btn, const QPixmap &strength);
signals:
// Cannot pass Network by reference. it may change after the signal is sent.
void connectToNetwork(const Network n);
void forgotNetwork(const Network n);
protected:
ElidedLabel* ssidLabel;
QPushButton* connecting;
QPushButton* forgetBtn;
QLabel* iconLabel;
QLabel* strengthLabel;
Network network;
};
class WifiUI : public QWidget {
Q_OBJECT
public:
explicit WifiUI(QWidget *parent = 0, WifiManager* wifi = 0);
private:
WifiItem *getItem(int n);
WifiManager *wifi = nullptr;
QLabel *scanningLabel = nullptr;
QPixmap lock;
QPixmap checkmark;
QPixmap circled_slash;
QVector<QPixmap> strengths;
ListWidget *wifi_list_widget = nullptr;
std::vector<WifiItem*> wifi_items;
signals:
void connectToNetwork(const Network n);
public slots:
void refresh();
};
class AdvancedNetworking : public QWidget {
Q_OBJECT
public:
explicit AdvancedNetworking(QWidget* parent = 0, WifiManager* wifi = 0);
void setGsmVisible(bool visible);
private:
LabelControl* ipLabel;
ButtonParamControl* tetheringToggle;
ToggleControl* roamingToggle;
ButtonControl* editApnButton;
ButtonControl* hiddenNetworkButton;
ToggleControl* cellularMeteredToggle;
MultiButtonControl* wifiMeteredToggle;
WifiManager* wifi = nullptr;
Params params;
signals:
void backPress();
void requestWifiScreen();
public slots:
void toggleTethering(int id);
void refresh();
};
class Networking : public QFrame {
Q_OBJECT
public:
explicit Networking(QWidget* parent = 0, bool show_advanced = true);
void setPrimeType(PrimeState::Type type);
WifiManager* wifi = nullptr;
private:
QStackedLayout* main_layout = nullptr;
QWidget* wifiScreen = nullptr;
AdvancedNetworking* an = nullptr;
WifiUI* wifiWidget;
void showEvent(QShowEvent* event) override;
void hideEvent(QHideEvent* event) override;
public slots:
void refresh();
private slots:
void connectToNetwork(const Network n);
void wrongPassword(const QString &ssid);
};
-48
View File
@@ -1,48 +0,0 @@
#pragma once
/**
* We are using a NetworkManager DBUS API : https://developer.gnome.org/NetworkManager/1.26/spec.html
* */
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApFlags
const int NM_802_11_AP_FLAGS_NONE = 0x00000000;
const int NM_802_11_AP_FLAGS_PRIVACY = 0x00000001;
const int NM_802_11_AP_FLAGS_WPS = 0x00000002;
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApSecurityFlags
const int NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001;
const int NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002;
const int NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010;
const int NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020;
const int NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100;
const int NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200;
const QString NM_DBUS_PATH = "/org/freedesktop/NetworkManager";
const QString NM_DBUS_PATH_SETTINGS = "/org/freedesktop/NetworkManager/Settings";
const QString NM_DBUS_INTERFACE = "org.freedesktop.NetworkManager";
const QString NM_DBUS_INTERFACE_PROPERTIES = "org.freedesktop.DBus.Properties";
const QString NM_DBUS_INTERFACE_SETTINGS = "org.freedesktop.NetworkManager.Settings";
const QString NM_DBUS_INTERFACE_SETTINGS_CONNECTION = "org.freedesktop.NetworkManager.Settings.Connection";
const QString NM_DBUS_INTERFACE_DEVICE = "org.freedesktop.NetworkManager.Device";
const QString NM_DBUS_INTERFACE_DEVICE_WIRELESS = "org.freedesktop.NetworkManager.Device.Wireless";
const QString NM_DBUS_INTERFACE_ACCESS_POINT = "org.freedesktop.NetworkManager.AccessPoint";
const QString NM_DBUS_INTERFACE_ACTIVE_CONNECTION = "org.freedesktop.NetworkManager.Connection.Active";
const QString NM_DBUS_INTERFACE_IP4_CONFIG = "org.freedesktop.NetworkManager.IP4Config";
const QString NM_DBUS_SERVICE = "org.freedesktop.NetworkManager";
const int NM_DEVICE_STATE_UNKNOWN = 0;
const int NM_DEVICE_STATE_ACTIVATED = 100;
const int NM_DEVICE_STATE_NEED_AUTH = 60;
const int NM_DEVICE_TYPE_WIFI = 2;
const int NM_DEVICE_TYPE_MODEM = 8;
const int NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8;
const int DBUS_TIMEOUT = 100;
// https://developer-old.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NMMetered
const int NM_METERED_UNKNOWN = 0;
const int NM_METERED_YES = 1;
const int NM_METERED_NO = 2;
const int NM_METERED_GUESS_YES = 3;
const int NM_METERED_GUESS_NO = 4;
-539
View File
@@ -1,539 +0,0 @@
#include "selfdrive/ui/qt/network/wifi_manager.h"
#include <utility>
#include "common/swaglog.h"
#include "selfdrive/ui/qt/util.h"
bool compare_by_strength(const Network &a, const Network &b) {
return std::tuple(a.connected, strengthLevel(a.strength), b.ssid) >
std::tuple(b.connected, strengthLevel(b.strength), a.ssid);
}
template <typename T = QDBusMessage, typename... Args>
T call(const QString &path, const QString &interface, const QString &method, Args &&...args) {
QDBusInterface nm(NM_DBUS_SERVICE, path, interface, QDBusConnection::systemBus());
nm.setTimeout(DBUS_TIMEOUT);
QDBusMessage response = nm.call(method, std::forward<Args>(args)...);
if (response.type() == QDBusMessage::ErrorMessage) {
qCritical() << "DBus call error:" << response.errorMessage();
return T();
}
if constexpr (std::is_same_v<T, QDBusMessage>) {
return response;
} else if (response.arguments().count() >= 1) {
QVariant vFirst = response.arguments().at(0).value<QDBusVariant>().variant();
if (vFirst.canConvert<T>()) {
return vFirst.value<T>();
}
QDebug critical = qCritical();
critical << "Variant unpacking failure :" << method << ',';
(critical << ... << args);
}
return T();
}
template <typename... Args>
QDBusPendingCall asyncCall(const QString &path, const QString &interface, const QString &method, Args &&...args) {
QDBusInterface nm = QDBusInterface(NM_DBUS_SERVICE, path, interface, QDBusConnection::systemBus());
return nm.asyncCall(method, args...);
}
bool emptyPath(const QString &path) {
return path == "" || path == "/";
}
WifiManager::WifiManager(QObject *parent) : QObject(parent) {
qDBusRegisterMetaType<Connection>();
qDBusRegisterMetaType<IpConfig>();
// Set tethering ssid as "weedle" + first 4 characters of a dongle id
tethering_ssid = "weedle";
if (auto dongle_id = getDongleId()) {
tethering_ssid += "-" + dongle_id->left(4);
}
adapter = getAdapter();
if (!adapter.isEmpty()) {
setup();
} else {
QDBusConnection::systemBus().connect(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceAdded", this, SLOT(deviceAdded(QDBusObjectPath)));
}
timer.callOnTimeout(this, &WifiManager::requestScan);
initConnections();
}
void WifiManager::setup() {
auto bus = QDBusConnection::systemBus();
bus.connect(NM_DBUS_SERVICE, adapter, NM_DBUS_INTERFACE_DEVICE, "StateChanged", this, SLOT(stateChange(unsigned int, unsigned int, unsigned int)));
bus.connect(NM_DBUS_SERVICE, adapter, NM_DBUS_INTERFACE_PROPERTIES, "PropertiesChanged", this, SLOT(propertyChange(QString, QVariantMap, QStringList)));
bus.connect(NM_DBUS_SERVICE, NM_DBUS_PATH_SETTINGS, NM_DBUS_INTERFACE_SETTINGS, "ConnectionRemoved", this, SLOT(connectionRemoved(QDBusObjectPath)));
bus.connect(NM_DBUS_SERVICE, NM_DBUS_PATH_SETTINGS, NM_DBUS_INTERFACE_SETTINGS, "NewConnection", this, SLOT(newConnection(QDBusObjectPath)));
raw_adapter_state = call<uint>(adapter, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_DEVICE, "State");
activeAp = call<QDBusObjectPath>(adapter, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_DEVICE_WIRELESS, "ActiveAccessPoint").path();
requestScan();
}
void WifiManager::start() {
timer.start(5000);
refreshNetworks();
}
void WifiManager::stop() {
timer.stop();
}
void WifiManager::refreshNetworks() {
if (adapter.isEmpty() || !timer.isActive()) return;
QDBusPendingCall pending_call = asyncCall(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "GetAllAccessPoints");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending_call);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &WifiManager::refreshFinished);
}
void WifiManager::refreshFinished(QDBusPendingCallWatcher *watcher) {
ipv4_address = getIp4Address();
seenNetworks.clear();
const QDBusReply<QList<QDBusObjectPath>> watcher_reply = *watcher;
if (!watcher_reply.isValid()) {
qCritical() << "Failed to refresh";
watcher->deleteLater();
return;
}
for (const QDBusObjectPath &path : watcher_reply.value()) {
QDBusReply<QVariantMap> reply = call(path.path(), NM_DBUS_INTERFACE_PROPERTIES, "GetAll", NM_DBUS_INTERFACE_ACCESS_POINT);
if (!reply.isValid()) {
qCritical() << "Failed to retrieve properties for path:" << path.path();
continue;
}
auto properties = reply.value();
const QByteArray ssid = properties["Ssid"].toByteArray();
if (ssid.isEmpty()) continue;
// May be multiple access points for each SSID.
// Use first for ssid and security type, then update connected status and strength using all
if (!seenNetworks.contains(ssid)) {
seenNetworks[ssid] = {ssid, 0U, ConnectedType::DISCONNECTED, getSecurityType(properties)};
}
if (path.path() == activeAp) {
seenNetworks[ssid].connected = (ssid == connecting_to_network) ? ConnectedType::CONNECTING : ConnectedType::CONNECTED;
}
uint32_t strength = properties["Strength"].toUInt();
if (seenNetworks[ssid].strength < strength) {
seenNetworks[ssid].strength = strength;
}
}
emit refreshSignal();
watcher->deleteLater();
}
QString WifiManager::getIp4Address() {
if (raw_adapter_state != NM_DEVICE_STATE_ACTIVATED) return "";
for (const auto &p : getActiveConnections()) {
QString type = call<QString>(p.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (type == "802-11-wireless") {
auto ip4config = call<QDBusObjectPath>(p.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Ip4Config");
const auto &arr = call<QDBusArgument>(ip4config.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_IP4_CONFIG, "AddressData");
QVariantMap path;
arr.beginArray();
while (!arr.atEnd()) {
arr >> path;
arr.endArray();
return path.value("address").value<QString>();
}
arr.endArray();
}
}
return "";
}
SecurityType WifiManager::getSecurityType(const QVariantMap &properties) {
int sflag = properties["Flags"].toUInt();
int wpaflag = properties["WpaFlags"].toUInt();
int rsnflag = properties["RsnFlags"].toUInt();
int wpa_props = wpaflag | rsnflag;
// obtained by looking at flags of networks in the office as reported by an Android phone
const int supports_wpa = NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 | NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_KEY_MGMT_PSK;
if ((sflag == NM_802_11_AP_FLAGS_NONE) || ((sflag & NM_802_11_AP_FLAGS_WPS) && !(wpa_props & supports_wpa))) {
return SecurityType::OPEN;
} else if ((sflag & NM_802_11_AP_FLAGS_PRIVACY) && (wpa_props & supports_wpa) && !(wpa_props & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
return SecurityType::WPA;
} else {
LOGW("Unsupported network! sflag: %d, wpaflag: %d, rsnflag: %d", sflag, wpaflag, rsnflag);
return SecurityType::UNSUPPORTED;
}
}
void WifiManager::connect(const Network &n, const bool is_hidden, const QString &password, const QString &username) {
setCurrentConnecting(n.ssid);
forgetConnection(n.ssid); // Clear all connections that may already exist to the network we are connecting
Connection connection;
connection["connection"]["type"] = "802-11-wireless";
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}');
connection["connection"]["id"] = "openpilot connection " + QString::fromStdString(n.ssid.toStdString());
connection["connection"]["autoconnect-retries"] = 0;
connection["802-11-wireless"]["ssid"] = n.ssid;
connection["802-11-wireless"]["hidden"] = is_hidden;
connection["802-11-wireless"]["mode"] = "infrastructure";
if (n.security_type == SecurityType::WPA) {
connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk";
connection["802-11-wireless-security"]["auth-alg"] = "open";
connection["802-11-wireless-security"]["psk"] = password;
}
connection["ipv4"]["method"] = "auto";
connection["ipv4"]["dns-priority"] = 600;
connection["ipv6"]["method"] = "ignore";
asyncCall(NM_DBUS_PATH_SETTINGS, NM_DBUS_INTERFACE_SETTINGS, "AddConnection", QVariant::fromValue(connection));
}
void WifiManager::deactivateConnectionBySsid(const QString &ssid) {
for (QDBusObjectPath active_connection : getActiveConnections()) {
auto pth = call<QDBusObjectPath>(active_connection.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "SpecificObject");
if (!emptyPath(pth.path())) {
QString Ssid = get_property(pth.path(), "Ssid");
if (Ssid == ssid) {
deactivateConnection(active_connection);
return;
}
}
}
}
void WifiManager::deactivateConnection(const QDBusObjectPath &path) {
asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeactivateConnection", QVariant::fromValue(path));
}
QVector<QDBusObjectPath> WifiManager::getActiveConnections() {
auto result = call<QDBusArgument>(NM_DBUS_PATH, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE, "ActiveConnections");
return qdbus_cast<QVector<QDBusObjectPath>>(result);
}
bool WifiManager::isKnownConnection(const QString &ssid) {
return !getConnectionPath(ssid).path().isEmpty();
}
void WifiManager::forgetConnection(const QString &ssid) {
const QDBusObjectPath &path = getConnectionPath(ssid);
if (!path.path().isEmpty()) {
call(path.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "Delete");
}
}
void WifiManager::setCurrentConnecting(const QString &ssid) {
connecting_to_network = ssid;
for (auto &network : seenNetworks) {
network.connected = (network.ssid == ssid) ? ConnectedType::CONNECTING : ConnectedType::DISCONNECTED;
}
emit refreshSignal();
}
uint WifiManager::getAdapterType(const QDBusObjectPath &path) {
return call<uint>(path.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_DEVICE, "DeviceType");
}
void WifiManager::requestScan() {
if (!adapter.isEmpty()) {
asyncCall(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "RequestScan", QVariantMap());
}
}
QByteArray WifiManager::get_property(const QString &network_path , const QString &property) {
return call<QByteArray>(network_path, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACCESS_POINT, property);
}
QString WifiManager::getAdapter(const uint adapter_type) {
QDBusReply<QList<QDBusObjectPath>> response = call(NM_DBUS_PATH, NM_DBUS_INTERFACE, "GetDevices");
for (const QDBusObjectPath &path : response.value()) {
if (getAdapterType(path) == adapter_type) {
return path.path();
}
}
return "";
}
void WifiManager::stateChange(unsigned int new_state, unsigned int previous_state, unsigned int change_reason) {
raw_adapter_state = new_state;
if (new_state == NM_DEVICE_STATE_NEED_AUTH && change_reason == NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT && !connecting_to_network.isEmpty()) {
forgetConnection(connecting_to_network);
emit wrongPassword(connecting_to_network);
} else if (new_state == NM_DEVICE_STATE_ACTIVATED) {
connecting_to_network = "";
refreshNetworks();
}
}
// https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.Device.Wireless.html
void WifiManager::propertyChange(const QString &interface, const QVariantMap &props, const QStringList &invalidated_props) {
if (interface == NM_DBUS_INTERFACE_DEVICE_WIRELESS && props.contains("LastScan")) {
refreshNetworks();
} else if (interface == NM_DBUS_INTERFACE_DEVICE_WIRELESS && props.contains("ActiveAccessPoint")) {
activeAp = props.value("ActiveAccessPoint").value<QDBusObjectPath>().path();
}
}
void WifiManager::deviceAdded(const QDBusObjectPath &path) {
if (getAdapterType(path) == NM_DEVICE_TYPE_WIFI && emptyPath(adapter)) {
adapter = path.path();
setup();
}
}
void WifiManager::connectionRemoved(const QDBusObjectPath &path) {
knownConnections.remove(path);
}
void WifiManager::newConnection(const QDBusObjectPath &path) {
Connection settings = getConnectionSettings(path);
if (settings.value("connection").value("type") == "802-11-wireless") {
knownConnections[path] = settings.value("802-11-wireless").value("ssid").toString();
if (knownConnections[path] != tethering_ssid) {
activateWifiConnection(knownConnections[path]);
}
}
}
QDBusObjectPath WifiManager::getConnectionPath(const QString &ssid) {
return knownConnections.key(ssid);
}
Connection WifiManager::getConnectionSettings(const QDBusObjectPath &path) {
return QDBusReply<Connection>(call(path.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "GetSettings")).value();
}
void WifiManager::initConnections() {
const QDBusReply<QList<QDBusObjectPath>> response = call(NM_DBUS_PATH_SETTINGS, NM_DBUS_INTERFACE_SETTINGS, "ListConnections");
for (const QDBusObjectPath &path : response.value()) {
const Connection settings = getConnectionSettings(path);
if (settings.value("connection").value("type") == "802-11-wireless") {
knownConnections[path] = settings.value("802-11-wireless").value("ssid").toString();
} else if (settings.value("connection").value("id") == "lte") {
lteConnectionPath = path;
}
}
if (!isKnownConnection(tethering_ssid)) {
addTetheringConnection();
}
}
std::optional<QDBusPendingCall> WifiManager::activateWifiConnection(const QString &ssid) {
const QDBusObjectPath &path = getConnectionPath(ssid);
if (!path.path().isEmpty()) {
setCurrentConnecting(ssid);
return asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(adapter)), QVariant::fromValue(QDBusObjectPath("/")));
}
return std::nullopt;
}
void WifiManager::activateModemConnection(const QDBusObjectPath &path) {
QString modem = getAdapter(NM_DEVICE_TYPE_MODEM);
if (!path.path().isEmpty() && !modem.isEmpty()) {
asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(modem)), QVariant::fromValue(QDBusObjectPath("/")));
}
}
// function matches tici/hardware.py
// FIXME: it can mistakenly show CELL when connected to WIFI
NetworkType WifiManager::currentNetworkType() {
auto primary_conn = call<QDBusObjectPath>(NM_DBUS_PATH, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE, "PrimaryConnection");
auto primary_type = call<QString>(primary_conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (primary_type == "802-3-ethernet") {
return NetworkType::ETHERNET;
} else if (primary_type == "802-11-wireless" && !isTetheringEnabled()) {
return NetworkType::WIFI;
} else {
for (const QDBusObjectPath &conn : getActiveConnections()) {
auto type = call<QString>(conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (type == "gsm") {
return NetworkType::CELL;
}
}
}
return NetworkType::NONE;
}
MeteredType WifiManager::currentNetworkMetered() {
MeteredType metered = MeteredType::UNKNOWN;
for (const auto &active_conn : getActiveConnections()) {
QString type = call<QString>(active_conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (type == "802-11-wireless") {
QDBusObjectPath conn = call<QDBusObjectPath>(active_conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Connection");
if (!conn.path().isEmpty()) {
Connection settings = getConnectionSettings(conn);
int metered_prop = settings.value("connection").value("metered").toInt();
if (metered_prop == NM_METERED_YES) {
metered = MeteredType::YES;
} else if (metered_prop == NM_METERED_NO) {
metered = MeteredType::NO;
}
}
break;
}
}
return metered;
}
std::optional<QDBusPendingCall> WifiManager::setCurrentNetworkMetered(MeteredType metered) {
for (const auto &active_conn : getActiveConnections()) {
QString type = call<QString>(active_conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (type == "802-11-wireless") {
if (!isTetheringEnabled()) {
QDBusObjectPath conn = call<QDBusObjectPath>(active_conn.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Connection");
if (!conn.path().isEmpty()) {
Connection settings = getConnectionSettings(conn);
settings["connection"]["metered"] = static_cast<int>(metered);
return asyncCall(conn.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "Update", QVariant::fromValue(settings));
}
}
}
}
return std::nullopt;
}
void WifiManager::updateGsmSettings(bool roaming, QString apn, bool metered) {
if (!lteConnectionPath.path().isEmpty()) {
bool changes = false;
bool auto_config = apn.isEmpty();
Connection settings = getConnectionSettings(lteConnectionPath);
if (settings.value("gsm").value("auto-config").toBool() != auto_config) {
qWarning() << "Changing gsm.auto-config to" << auto_config;
settings["gsm"]["auto-config"] = auto_config;
changes = true;
}
if (settings.value("gsm").value("apn").toString() != apn) {
qWarning() << "Changing gsm.apn to" << apn;
settings["gsm"]["apn"] = apn;
changes = true;
}
if (settings.value("gsm").value("home-only").toBool() == roaming) {
qWarning() << "Changing gsm.home-only to" << !roaming;
settings["gsm"]["home-only"] = !roaming;
changes = true;
}
int meteredInt = metered ? NM_METERED_UNKNOWN : NM_METERED_NO;
if (settings.value("connection").value("metered").toInt() != meteredInt) {
qWarning() << "Changing connection.metered to" << meteredInt;
settings["connection"]["metered"] = meteredInt;
changes = true;
}
if (changes) {
QDBusPendingCall pending_call = asyncCall(lteConnectionPath.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "UpdateUnsaved", QVariant::fromValue(settings)); // update is temporary
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending_call);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, watcher]() {
deactivateConnection(lteConnectionPath);
activateModemConnection(lteConnectionPath);
watcher->deleteLater();
});
}
}
}
// Functions for tethering
void WifiManager::addTetheringConnection() {
Connection connection;
connection["connection"]["id"] = "Hotspot";
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}');
connection["connection"]["type"] = "802-11-wireless";
connection["connection"]["interface-name"] = "wlan0";
connection["connection"]["autoconnect"] = false;
connection["802-11-wireless"]["band"] = "bg";
connection["802-11-wireless"]["mode"] = "ap";
connection["802-11-wireless"]["ssid"] = tethering_ssid.toUtf8();
connection["802-11-wireless-security"]["group"] = QStringList("ccmp");
connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk";
connection["802-11-wireless-security"]["pairwise"] = QStringList("ccmp");
connection["802-11-wireless-security"]["proto"] = QStringList("rsn");
connection["802-11-wireless-security"]["psk"] = defaultTetheringPassword;
connection["ipv4"]["method"] = "shared";
QVariantMap address;
address["address"] = "192.168.43.1";
address["prefix"] = 24u;
connection["ipv4"]["address-data"] = QVariant::fromValue(IpConfig() << address);
connection["ipv4"]["gateway"] = "192.168.43.1";
connection["ipv4"]["never-default"] = true;
connection["ipv6"]["method"] = "ignore";
asyncCall(NM_DBUS_PATH_SETTINGS, NM_DBUS_INTERFACE_SETTINGS, "AddConnection", QVariant::fromValue(connection));
}
void WifiManager::tetheringActivated(QDBusPendingCallWatcher *call) {
if (!ipv4_forward) {
QTimer::singleShot(5000, this, [=] {
qWarning() << "net.ipv4.ip_forward = 0";
std::system("sudo sysctl net.ipv4.ip_forward=0");
});
}
call->deleteLater();
tethering_on = true;
}
void WifiManager::setTetheringEnabled(bool enabled) {
if (enabled) {
auto pending_call = activateWifiConnection(tethering_ssid);
if (pending_call) {
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(*pending_call);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &WifiManager::tetheringActivated);
}
} else {
deactivateConnectionBySsid(tethering_ssid);
tethering_on = false;
}
}
bool WifiManager::isTetheringEnabled() {
if (!emptyPath(activeAp)) {
return get_property(activeAp, "Ssid") == tethering_ssid;
}
return false;
}
QString WifiManager::getTetheringPassword() {
const QDBusObjectPath &path = getConnectionPath(tethering_ssid);
if (!path.path().isEmpty()) {
QDBusReply<QMap<QString, QVariantMap>> response = call(path.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "GetSecrets", "802-11-wireless-security");
return response.value().value("802-11-wireless-security").value("psk").toString();
}
return "";
}
void WifiManager::changeTetheringPassword(const QString &newPassword) {
const QDBusObjectPath &path = getConnectionPath(tethering_ssid);
if (!path.path().isEmpty()) {
Connection settings = getConnectionSettings(path);
settings["802-11-wireless-security"]["psk"] = newPassword;
call(path.path(), NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "Update", QVariant::fromValue(settings));
if (isTetheringEnabled()) {
activateWifiConnection(tethering_ssid);
}
}
}
-112
View File
@@ -1,112 +0,0 @@
#pragma once
#include <optional>
#include <QtDBus>
#include <QTimer>
#include "selfdrive/ui/qt/network/networkmanager.h"
enum class SecurityType {
OPEN,
WPA,
UNSUPPORTED
};
enum class ConnectedType {
DISCONNECTED,
CONNECTING,
CONNECTED
};
enum class NetworkType {
NONE,
WIFI,
CELL,
ETHERNET
};
enum class MeteredType {
UNKNOWN,
YES,
NO
};
typedef QMap<QString, QVariantMap> Connection;
typedef QVector<QVariantMap> IpConfig;
struct Network {
QByteArray ssid;
unsigned int strength;
ConnectedType connected;
SecurityType security_type;
};
bool compare_by_strength(const Network &a, const Network &b);
inline int strengthLevel(unsigned int strength) { return std::clamp((int)round(strength / 33.), 0, 3); }
class WifiManager : public QObject {
Q_OBJECT
public:
QMap<QString, Network> seenNetworks;
QMap<QDBusObjectPath, QString> knownConnections;
QString ipv4_address;
bool tethering_on = false;
bool ipv4_forward = false;
explicit WifiManager(QObject* parent);
void start();
void stop();
void requestScan();
void forgetConnection(const QString &ssid);
bool isKnownConnection(const QString &ssid);
std::optional<QDBusPendingCall> activateWifiConnection(const QString &ssid);
NetworkType currentNetworkType();
MeteredType currentNetworkMetered();
std::optional<QDBusPendingCall> setCurrentNetworkMetered(MeteredType metered);
void updateGsmSettings(bool roaming, QString apn, bool metered);
void connect(const Network &ssid, const bool is_hidden = false, const QString &password = {}, const QString &username = {});
// Tethering functions
void setTetheringEnabled(bool enabled);
bool isTetheringEnabled();
void changeTetheringPassword(const QString &newPassword);
QString getTetheringPassword();
QString getIp4Address();
private:
QString adapter; // Path to network manager wifi-device
QTimer timer;
unsigned int raw_adapter_state = NM_DEVICE_STATE_UNKNOWN; // Connection status https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NMDeviceState
QString connecting_to_network;
QString tethering_ssid;
const QString defaultTetheringPassword = "swagswagcomma";
QString activeAp;
QDBusObjectPath lteConnectionPath;
QString getAdapter(const uint = NM_DEVICE_TYPE_WIFI);
uint getAdapterType(const QDBusObjectPath &path);
void deactivateConnectionBySsid(const QString &ssid);
void deactivateConnection(const QDBusObjectPath &path);
QVector<QDBusObjectPath> getActiveConnections();
QByteArray get_property(const QString &network_path, const QString &property);
SecurityType getSecurityType(const QVariantMap &properties);
QDBusObjectPath getConnectionPath(const QString &ssid);
Connection getConnectionSettings(const QDBusObjectPath &path);
void initConnections();
void setup();
void refreshNetworks();
void activateModemConnection(const QDBusObjectPath &path);
void addTetheringConnection();
void setCurrentConnecting(const QString &ssid);
signals:
void wrongPassword(const QString &ssid);
void refreshSignal();
private slots:
void stateChange(unsigned int new_state, unsigned int previous_state, unsigned int change_reason);
void propertyChange(const QString &interface, const QVariantMap &props, const QStringList &invalidated_props);
void deviceAdded(const QDBusObjectPath &path);
void connectionRemoved(const QDBusObjectPath &path);
void newConnection(const QDBusObjectPath &path);
void refreshFinished(QDBusPendingCallWatcher *call);
void tetheringActivated(QDBusPendingCallWatcher *call);
};
-401
View File
@@ -1,401 +0,0 @@
#include "selfdrive/ui/qt/offroad/developer_panel.h"
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
#include "selfdrive/ui/qt/widgets/controls.h"
DeveloperPanel::DeveloperPanel(SettingsWindow *parent) : QFrame(parent) {
mainLayout = new QStackedLayout(this);
mainWidget = new QWidget(this);
QVBoxLayout *mainListLayout = new QVBoxLayout(mainWidget);
mainListLayout->setContentsMargins(50, 25, 50, 25);
mainListLayout->setSpacing(20);
StarPilotListWidget *mainList = new StarPilotListWidget(mainWidget);
mainListLayout->addWidget(mainList);
adbToggle = new ParamControl("AdbEnabled", tr("Enable ADB"),
tr("ADB (Android Debug Bridge) allows connecting to your device over USB or over the network. See https://docs.comma.ai/how-to/connect-to-comma for more info."), "");
mainList->addItem(adbToggle);
auto *usePrebuiltToggle = new ParamControl("UsePrebuilt", tr("Use Prebuilt Binaries"),
tr("When enabled (default), the device skips source compilation on boot if a prebuilt artifact exists. Disable this if you plan to edit code and rebuild on-device."), "");
mainList->addItem(usePrebuiltToggle);
auto *showAllToggles = new ParamControl("ShowAllToggles", tr("Show All Toggles"),
tr("<b>Show every toggle</b> in Settings and StarPilot, even when it would normally be hidden by tuning level, car support, or related feature gating."), "");
QObject::connect(showAllToggles, &ParamControl::toggleFlipped, [this](bool) {
updateToggles(offroad);
emit showAllTogglesChanged();
});
mainList->addItem(showAllToggles);
// SSH keys
mainList->addItem(new SshToggle());
mainList->addItem(new SshControl());
joystickToggle = new ParamControl("JoystickDebugMode", tr("Joystick Debug Mode"), "", "");
QObject::connect(joystickToggle, &ParamControl::toggleFlipped, [=](bool state) {
params.putBool("LongitudinalManeuverMode", false);
longManeuverToggle->refresh();
});
mainList->addItem(joystickToggle);
longManeuverToggle = new ParamControl("LongitudinalManeuverMode", tr("Longitudinal Maneuver Mode"), "", "");
QObject::connect(longManeuverToggle, &ParamControl::toggleFlipped, [=](bool state) {
params.putBool("JoystickDebugMode", false);
joystickToggle->refresh();
});
mainList->addItem(longManeuverToggle);
experimentalLongitudinalToggle = new ParamControl(
"AlphaLongitudinalEnabled",
tr("openpilot Longitudinal Control (Alpha)"),
QString("<b>%1</b><br><br>%2")
.arg(tr("WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB)."))
.arg(tr("On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. "
"Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.")),
""
);
experimentalLongitudinalToggle->setConfirmation(true, false);
QObject::connect(experimentalLongitudinalToggle, &ParamControl::toggleFlipped, [=]() {
updateToggles(offroad);
});
mainList->addItem(experimentalLongitudinalToggle);
// Joystick and longitudinal maneuvers should be hidden on release branches
is_release = false;
// Toggles should be not available to change in onroad state
QObject::connect(uiState(), &UIState::offroadTransition, this, &DeveloperPanel::updateToggles);
QJsonObject shownDescriptions = QJsonDocument::fromJson(QString::fromStdString(params.get("ShownToggleDescriptions")).toUtf8()).object();
QString className = this->metaObject()->className();
if (!shownDescriptions.value(className).toBool(false)) {
forceOpenDescriptions = true;
}
std::vector<std::string> keys = params.allKeys();
for (const std::string &key : keys) {
starpilotToggleLevels[QString::fromStdString(key)] = params.getTuningLevel(key);
}
developerUIToggle = new StarPilotManageControl("DeveloperUI", tr("Developer UI"), tr("<b>Detailed information about openpilot's internal operations.</b>"), "");
QObject::connect(developerUIToggle, &StarPilotManageControl::manageButtonClicked, [this]() {
mainLayout->setCurrentWidget(developerUIPanel);
emit openSubPanel();
});
mainList->insertItem(0, developerUIToggle);
mainLayout->addWidget(mainWidget);
StarPilotListWidget *developerUIList = new StarPilotListWidget(this);
developerUIList->setContentsMargins(50, 25, 50, 25);
developerUIPanel = new ScrollView(developerUIList, this);
mainLayout->addWidget(developerUIPanel);
StarPilotListWidget *developerMetricList = new StarPilotListWidget(this);
developerMetricList->setContentsMargins(50, 25, 50, 25);
developerMetricPanel = new ScrollView(developerMetricList, this);
mainLayout->addWidget(developerMetricPanel);
StarPilotListWidget *developerSidebarList = new StarPilotListWidget(this);
developerSidebarList->setContentsMargins(50, 25, 50, 25);
developerSidebarPanel = new ScrollView(developerSidebarList, this);
mainLayout->addWidget(developerSidebarPanel);
StarPilotListWidget *developerWidgetList = new StarPilotListWidget(this);
developerWidgetList->setContentsMargins(50, 25, 50, 25);
developerWidgetPanel = new ScrollView(developerWidgetList, this);
mainLayout->addWidget(developerWidgetPanel);
std::vector<std::tuple<QString, QString, QString, QString>> developerToggles {
{"DeveloperMetrics", tr("Developer Metrics"), tr("<b>Performance data, sensor readings, and system metrics</b> for debugging and optimizing openpilot."), ""},
{"AdjacentPathMetrics", tr("Adjacent Lane Metrics"), tr("<b>Show the width of the adjacent lanes.</b>"), ""},
{"BorderMetrics", tr("Border Metrics"), tr("<b>Show statuses along the border of the driving screen.</b><br><br><b>Blind Spot</b>: The border turns red when a vehicle is in a blind spot<br><b>Steering Torque</b>: The border goes from green to red according to how much steering torque is being used<br><b>Turn Signal</b>: The border flashes yellow when a turn signal is on"), ""},
{"FPSCounter", tr("FPS Display"), tr("<b>Show the frames per second (FPS)</b> at the bottom of the driving screen."), ""},
{"LeadInfo", tr("Lead Info"), tr("<b>Show each tracked vehicle's distance and speed</b> below its marker."), ""},
{"NumericalTemp", tr("Numerical Temperature Gauge"), tr("<b>Show a numerical temperature in the sidebar</b> instead of the status labels."), ""},
{"SidebarMetrics", tr("Sidebar Metrics"), tr("<b>Display system information</b> (CPU, GPU, RAM usage, IP address, device storage) in the sidebar."), ""},
{"UseSI", tr("Use International System of Units"), tr("<b>Display measurements using the \"International System of Units\" (SI)</b> standard."), ""},
{"DeveloperSidebar", tr("Developer Sidebar"), tr("<b>Display debugging info and metrics</b> in a dedicated sidebar on the right side of the screen."), ""},
{"DeveloperSidebarMetric1", tr("Metric #1"), tr("<b>Select the metric shown in the first \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric2", tr("Metric #2"), tr("<b>Select the metric shown in the second \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric3", tr("Metric #3"), tr("<b>Select the metric shown in the third \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric4", tr("Metric #4"), tr("<b>Select the metric shown in the fourth \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric5", tr("Metric #5"), tr("<b>Select the metric shown in the fifth \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric6", tr("Metric #6"), tr("<b>Select the metric shown in the sixth \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperSidebarMetric7", tr("Metric #7"), tr("<b>Select the metric shown in the seventh \"Developer Sidebar\" widget.</b>"), ""},
{"DeveloperWidgets", tr("Developer Widgets"), tr("<b>Overlays for debugging visuals, internal states, and model predictions</b> on the driving screen."), ""},
{"AdjacentLeadsUI", tr("Adjacent Leads Tracking"), tr("<b>Display adjacent leads detected by the car's radar</b> to the left and right of the current driving path."), ""},
{"ShowStoppingPoint", tr("Model Stopping Point"), tr("<b>Show a stop-sign marker where the model intends to stop.</b>"), ""},
{"RadarTracksUI", tr("Radar Tracks"), tr("<b>Display all radar points</b> produced by the car's radar."), ""},
};
for (const auto &[param, title, desc, icon] : developerToggles) {
AbstractControl *developerToggle;
if (param == "DeveloperMetrics") {
StarPilotManageControl *developerMetricsToggle = new StarPilotManageControl(param, title, desc, icon);
QObject::connect(developerMetricsToggle, &StarPilotManageControl::manageButtonClicked, [this]() {
mainLayout->setCurrentWidget(developerMetricPanel);
emit openSubSubPanel();
});
developerToggle = developerMetricsToggle;
} else if (param == "BorderMetrics") {
std::vector<QString> borderToggles{"BlindSpotMetrics", "ShowSteering", "SignalMetrics"};
std::vector<QString> borderToggleNames{tr("Blind Spot"), tr("Steering Torque"), tr("Turn Signal")};
borderMetricsButton = new StarPilotButtonToggleControl(param, title, desc, icon, borderToggles, borderToggleNames);
developerToggle = borderMetricsButton;
} else if (param == "NumericalTemp") {
std::vector<QString> temperatureToggles{"Fahrenheit"};
std::vector<QString> temperatureToggleNames{tr("Fahrenheit")};
developerToggle = new StarPilotButtonToggleControl(param, title, desc, icon, temperatureToggles, temperatureToggleNames);
} else if (param == "SidebarMetrics") {
sidebarMetricsToggles = {"ShowCPU", "ShowGPU", "ShowIP", "ShowMemoryUsage", "ShowStorageLeft", "ShowStorageUsed"};
std::vector<QString> sidebarMetricsToggleNames{tr("CPU"), tr("GPU"), tr("IP"), tr("RAM"), tr("SSD Left"), tr("SSD Used")};
sidebarMetricsToggle = new StarPilotButtonsControl(title, desc, icon, sidebarMetricsToggleNames, true, false, 150);
for (int i = 0; i < sidebarMetricsToggles.size(); ++i) {
if (params.getBool(sidebarMetricsToggles[i].toStdString())) {
sidebarMetricsToggle->setCheckedButton(i);
}
}
QObject::connect(sidebarMetricsToggle, &StarPilotButtonsControl::buttonClicked, [this](int id) {
params.putBool(sidebarMetricsToggles[id].toStdString(), !params.getBool(sidebarMetricsToggles[id].toStdString()));
if (id == 0) {
params.putBool("ShowGPU", false);
} else if (id == 1) {
params.putBool("ShowCPU", false);
} else if (id == 3) {
params.putBool("ShowStorageLeft", false);
params.putBool("ShowStorageUsed", false);
} else if (id == 4) {
params.putBool("ShowMemoryUsage", false);
params.putBool("ShowStorageUsed", false);
} else if (id == 5) {
params.putBool("ShowMemoryUsage", false);
params.putBool("ShowStorageLeft", false);
}
sidebarMetricsToggle->clearCheckedButtons();
for (int i = 0; i < sidebarMetricsToggles.size(); ++i) {
if (params.getBool(sidebarMetricsToggles[i].toStdString())) {
sidebarMetricsToggle->setCheckedButton(i);
}
}
});
developerToggle = sidebarMetricsToggle;
} else if (param == "DeveloperSidebar") {
StarPilotManageControl *developerSidebarToggle = new StarPilotManageControl(param, title, desc, icon);
QObject::connect(developerSidebarToggle, &StarPilotManageControl::manageButtonClicked, [this]() {
mainLayout->setCurrentWidget(developerSidebarPanel);
emit openSubSubPanel();
});
developerToggle = developerSidebarToggle;
} else if (developerSidebarKeys.contains(param)) {
QMap<int, QString> developerSidebarMetricOptions {
{0, tr("None")},
{1, tr("Acceleration: Current")},
{2, tr("Acceleration: Max")},
{3, tr("Auto Tune: Actuator Delay")},
{4, tr("Auto Tune: Friction")},
{5, tr("Auto Tune: Lateral Acceleration")},
{6, tr("Auto Tune: Steer Ratio")},
{7, tr("Auto Tune: Stiffness Factor")},
{8, tr("Engagement %: Lateral")},
{9, tr("Engagement %: Longitudinal")},
{10, tr("Lateral Control: Steering Angle")},
{11, tr("Lateral Control: Torque % Used")},
{12, tr("Longitudinal Control: Actuator Acceleration Output")},
{13, tr("Longitudinal MPC: Danger Factor")},
{14, tr("Longitudinal MPC Jerk: Acceleration")},
{15, tr("Longitudinal MPC Jerk: Danger Zone")},
{16, tr("Longitudinal MPC Jerk: Speed Control")},
{17, tr("Model Name")},
};
ButtonControl *metricToggle = new ButtonControl(title, tr("SELECT"), desc);
QObject::connect(metricToggle, &ButtonControl::clicked, [metricToggle, key = param, developerSidebarMetricOptions, this]() mutable {
QString current = developerSidebarMetricOptions.value(params.getInt(key.toStdString()), tr("None"));
QString selection = MultiOptionDialog::getSelection(tr("Select a metric to display"), developerSidebarMetricOptions.values(), current, this);
if (!selection.isEmpty()) {
int selectedMetric = developerSidebarMetricOptions.key(selection);
params.putInt(key.toStdString(), selectedMetric);
metricToggle->setValue(selection);
}
});
metricToggle->setValue(developerSidebarMetricOptions.value(params.getInt(param.toStdString()), tr("None")));
developerToggle = metricToggle;
} else if (param == "DeveloperWidgets") {
StarPilotManageControl *developerWidgetsToggle = new StarPilotManageControl(param, title, desc, icon);
QObject::connect(developerWidgetsToggle, &StarPilotManageControl::manageButtonClicked, [this]() {
mainLayout->setCurrentWidget(developerWidgetPanel);
emit openSubSubPanel();
});
developerToggle = developerWidgetsToggle;
} else if (param == "ShowStoppingPoint") {
std::vector<QString> stoppingPointToggles{"ShowStoppingPointMetrics"};
std::vector<QString> stoppingPointToggleNames{tr("Show Distance")};
developerToggle = new StarPilotButtonToggleControl(param, title, desc, icon, stoppingPointToggles, stoppingPointToggleNames);
} else {
developerToggle = new ParamControl(param, title, desc, icon);
}
toggles[param] = developerToggle;
if (developerMetricKeys.contains(param)) {
developerMetricList->addItem(developerToggle);
} else if (developerSidebarKeys.contains(param)) {
developerSidebarList->addItem(developerToggle);
} else if (developerWidgetKeys.contains(param)) {
developerWidgetList->addItem(developerToggle);
} else {
developerUIList->addItem(developerToggle);
parentKeys.insert(param);
}
}
QObject::connect(parent, &SettingsWindow::closeSubPanel, [this]() {mainLayout->setCurrentWidget(mainWidget);});
QObject::connect(parent, &SettingsWindow::closeSubSubPanel, [this]() {mainLayout->setCurrentWidget(developerUIPanel);});
}
void DeveloperPanel::updateToggles(bool _offroad) {
const bool showAllToggles = params.getBool("ShowAllToggles");
for (auto btn : findChildren<ParamControl *>()) {
btn->setVisible(showAllToggles || !is_release);
/*
* experimentalLongitudinalToggle should be toggelable when:
* - visible, and
* - during onroad & offroad states
*/
if (btn != experimentalLongitudinalToggle) {
btn->setEnabled(_offroad);
}
for (auto &[key, toggle] : toggles) {
if (toggle == btn) {
btn->setEnabled(true);
break;
}
}
if (developerUIToggle == btn) {
btn->setEnabled(true);
}
}
// longManeuverToggle and experimentalLongitudinalToggle should not be toggleable if the car does not have longitudinal control
auto cp_bytes = params.get("CarParamsPersistent");
if (!cp_bytes.empty()) {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size()));
cereal::CarParams::Reader CP = cmsg.getRoot<cereal::CarParams>();
if ((!CP.getAlphaLongitudinalAvailable() || is_release) && !showAllToggles) {
params.remove("AlphaLongitudinalEnabled");
experimentalLongitudinalToggle->setEnabled(false);
} else {
experimentalLongitudinalToggle->setEnabled(true);
}
/*
* experimentalLongitudinalToggle should be visible when:
* - is not a release branch, and
* - the car supports experimental longitudinal control (alpha)
*/
experimentalLongitudinalToggle->setVisible(showAllToggles || (CP.getAlphaLongitudinalAvailable() && !is_release));
longManeuverToggle->setEnabled((showAllToggles || hasLongitudinalControl(CP)) && _offroad);
hasOpenpilotLongitudinal = hasLongitudinalControl(CP);
hasRadar = !CP.getRadarUnavailable();
borderMetricsButton->setVisibleButton(0, showAllToggles || CP.getEnableBsm());
} else {
longManeuverToggle->setEnabled(showAllToggles && _offroad);
experimentalLongitudinalToggle->setEnabled(showAllToggles);
experimentalLongitudinalToggle->setVisible(showAllToggles);
}
experimentalLongitudinalToggle->refresh();
offroad = _offroad;
tuningLevel = params.getInt("TuningLevel");
for (auto &[key, toggle] : toggles) {
if (parentKeys.contains(key)) {
toggle->setVisible(showAllToggles);
}
}
for (auto &[key, toggle] : toggles) {
if (parentKeys.contains(key)) {
continue;
}
bool setVisible = showAllToggles || tuningLevel >= starpilotToggleLevels[key].toDouble();
if (!showAllToggles) {
if (key == "AdjacentLeadsUI") {
setVisible &= hasRadar && !(params.getBool("AdvancedCustomUI") && params.getBool("HideLeadMarker"));
}
else if (key == "RadarTracksUI") {
setVisible &= hasRadar;
}
else if (key == "ShowStoppingPoint") {
setVisible &= hasOpenpilotLongitudinal;
}
}
toggle->setVisible(setVisible);
if (setVisible) {
if (developerMetricKeys.contains(key)) {
toggles["DeveloperMetrics"]->setVisible(true);
} else if (developerSidebarKeys.contains(key)) {
toggles["DeveloperSidebar"]->setVisible(true);
} else if (developerUIKeys.contains(key)) {
toggles["DeveloperUI"]->setVisible(true);
} else if (developerWidgetKeys.contains(key)) {
toggles["DeveloperWidgets"]->setVisible(true);
}
}
}
borderMetricsButton->setVisibleButton(0, showAllToggles || hasBSM);
developerUIToggle->setVisible(showAllToggles || tuningLevel >= starpilotToggleLevels["DeveloperUI"].toDouble());
openDescriptions(forceOpenDescriptions, toggles);
update();
}
void DeveloperPanel::showEvent(QShowEvent *event) {
updateToggles(offroad);
for (int i = 0; i < sidebarMetricsToggles.size(); ++i) {
if (params.getBool(sidebarMetricsToggles[i].toStdString())) {
sidebarMetricsToggle->setCheckedButton(i);
}
}
QJsonObject shownDescriptions = QJsonDocument::fromJson(QString::fromStdString(params.get("ShownToggleDescriptions")).toUtf8()).object();
QString className = this->metaObject()->className();
if (!shownDescriptions.value(className).toBool(false)) {
shownDescriptions.insert(className, true);
params.put("ShownToggleDescriptions", QJsonDocument(shownDescriptions).toJson(QJsonDocument::Compact).toStdString());
}
}
-64
View File
@@ -1,64 +0,0 @@
#pragma once
#include "selfdrive/ui/qt/offroad/settings.h"
#include "starpilot/ui/qt/offroad/starpilot_settings.h"
class DeveloperPanel : public QFrame {
Q_OBJECT
public:
explicit DeveloperPanel(SettingsWindow *parent);
void showEvent(QShowEvent *event) override;
signals:
void openSubPanel();
void openSubSubPanel();
void showAllTogglesChanged();
private:
Params params;
ParamControl* adbToggle;
ParamControl* joystickToggle;
ParamControl* longManeuverToggle;
ParamControl* experimentalLongitudinalToggle;
bool is_release;
bool offroad = false;
bool forceOpenDescriptions = false;
bool hasBSM = true;
bool hasOpenpilotLongitudinal = true;
bool hasRadar = true;
int tuningLevel;
std::map<QString, AbstractControl*> toggles;
std::vector<QString> sidebarMetricsToggles;
StarPilotButtonsControl *sidebarMetricsToggle;
StarPilotButtonToggleControl *borderMetricsButton;
StarPilotManageControl *developerUIToggle;
QJsonObject starpilotToggleLevels;
QSet<QString> developerMetricKeys = {"AdjacentPathMetrics", "BorderMetrics", "FPSCounter", "LeadInfo", "NumericalTemp", "SidebarMetrics", "UseSI"};
QSet<QString> developerSidebarKeys = {"DeveloperSidebarMetric1", "DeveloperSidebarMetric2", "DeveloperSidebarMetric3", "DeveloperSidebarMetric4", "DeveloperSidebarMetric5", "DeveloperSidebarMetric6", "DeveloperSidebarMetric7"};
QSet<QString> developerUIKeys = {"DeveloperMetrics", "DeveloperSidebar", "DeveloperWidgets"};
QSet<QString> developerWidgetKeys = {"AdjacentLeadsUI", "RadarTracksUI", "ShowStoppingPoint"};
QSet<QString> parentKeys;
QStackedLayout *mainLayout;
QWidget *mainWidget;
ScrollView *developerMetricPanel;
ScrollView *developerSidebarPanel;
ScrollView *developerUIPanel;
ScrollView *developerWidgetPanel;
private slots:
void updateToggles(bool _offroad);
};
-82
View File
@@ -1,82 +0,0 @@
#include "selfdrive/ui/qt/offroad/driverview.h"
#include <algorithm>
#include <QPainter>
#include "selfdrive/ui/qt/util.h"
DriverViewWindow::DriverViewWindow(QWidget* parent) : CameraWidget("camerad", VISION_STREAM_DRIVER, parent) {
QObject::connect(this, &CameraWidget::clicked, this, &DriverViewWindow::done);
QObject::connect(device(), &Device::interactiveTimeout, this, [this]() {
if (isVisible()) {
emit done();
}
});
}
void DriverViewWindow::showEvent(QShowEvent* event) {
params.putBool("IsDriverViewEnabled", true);
device()->resetInteractiveTimeout(60);
CameraWidget::showEvent(event);
}
void DriverViewWindow::hideEvent(QHideEvent* event) {
params.putBool("IsDriverViewEnabled", false);
stopVipcThread();
CameraWidget::hideEvent(event);
}
void DriverViewWindow::paintGL() {
CameraWidget::paintGL();
std::lock_guard lk(frame_lock);
QPainter p(this);
// startup msg
if (frames.empty()) {
p.setPen(Qt::white);
p.setRenderHint(QPainter::TextAntialiasing);
p.setFont(InterFont(100, QFont::Bold));
p.drawText(geometry(), Qt::AlignCenter, tr("camera starting"));
return;
}
const auto &sm = *(uiState()->sm);
cereal::DriverStateV2::Reader driver_state = sm["driverStateV2"].getDriverStateV2();
bool is_rhd = driver_state.getWheelOnRightProb() > 0.5;
auto driver_data = is_rhd ? driver_state.getRightDriverData() : driver_state.getLeftDriverData();
bool face_detected = driver_data.getFaceProb() > 0.7;
if (face_detected) {
auto fxy_list = driver_data.getFacePosition();
auto std_list = driver_data.getFaceOrientationStd();
float face_x = fxy_list[0];
float face_y = fxy_list[1];
float face_std = std::max(std_list[0], std_list[1]);
float alpha = 0.7;
if (face_std > 0.15) {
alpha = std::max(0.7 - (face_std-0.15)*3.5, 0.0);
}
const int box_size = 220;
// use approx instead of distort_points
int fbox_x = 1080.0 - 1714.0 * face_x;
int fbox_y = -135.0 + (504.0 + std::abs(face_x)*112.0) + (1205.0 - std::abs(face_x)*724.0) * face_y;
p.setPen(QPen(QColor(255, 255, 255, alpha * 255), 10));
p.drawRoundedRect(fbox_x - box_size / 2, fbox_y - box_size / 2, box_size, box_size, 35.0, 35.0);
}
driver_monitor.updateState(*uiState());
driver_monitor.draw(p, rect());
}
mat4 DriverViewWindow::calcFrameMatrix() {
const float driver_view_ratio = 2.0;
const float yscale = stream_height * driver_view_ratio / stream_width;
const float xscale = yscale * glHeight() / glWidth() * stream_width / stream_height;
return mat4{{
xscale, 0.0, 0.0, 0.0,
0.0, yscale, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
}
-23
View File
@@ -1,23 +0,0 @@
#pragma once
#include "selfdrive/ui/qt/widgets/cameraview.h"
#include "selfdrive/ui/qt/onroad/driver_monitoring.h"
class DriverViewWindow : public CameraWidget {
Q_OBJECT
public:
explicit DriverViewWindow(QWidget *parent);
signals:
void done();
protected:
mat4 calcFrameMatrix() override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
void paintGL() override;
Params params;
DriverMonitorRenderer driver_monitor;
};
@@ -1,95 +0,0 @@
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
#include <QDebug>
#include <QHBoxLayout>
#include <QPainter>
#include <QPainterPath>
#include <QStyle>
#include "selfdrive/ui/ui.h"
ExperimentalModeButton::ExperimentalModeButton(QWidget *parent) : QPushButton(parent) {
chill_pixmap = QPixmap("../assets/icons/couch.svg").scaledToWidth(img_width, Qt::SmoothTransformation);
experimental_pixmap = QPixmap("../assets/icons/experimental_grey.svg").scaledToWidth(img_width, Qt::SmoothTransformation);
// go to toggles and expand whichever mode control is actually active
connect(this, &QPushButton::clicked, [=]() {
const QString toggle = params.getBool("ConditionalExperimental") ? "ConditionalExperimental" :
params.getBool("ConditionalChill") ? "ConditionalChill" :
"ExperimentalMode";
emit openSettings(2, toggle);
});
setFixedHeight(125);
QHBoxLayout *main_layout = new QHBoxLayout;
main_layout->setContentsMargins(horizontal_padding, 0, horizontal_padding, 0);
mode_label = new QLabel;
mode_icon = new QLabel;
mode_icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
main_layout->addWidget(mode_label, 1, Qt::AlignLeft);
main_layout->addWidget(mode_icon, 0, Qt::AlignRight);
setLayout(main_layout);
setStyleSheet(R"(
QPushButton {
border: none;
}
QLabel {
font-size: 45px;
font-weight: 300;
text-align: left;
font-family: JetBrainsMono;
color: #000000;
}
)");
}
void ExperimentalModeButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addRoundedRect(rect(), 10, 10);
// gradient
bool pressed = isDown();
QLinearGradient gradient(rect().left(), 0, rect().right(), 0);
if (experimental_mode) {
gradient.setColorAt(0, QColor(255, 155, 63, pressed ? 0xcc : 0xff));
gradient.setColorAt(1, QColor(219, 56, 34, pressed ? 0xcc : 0xff));
} else {
gradient.setColorAt(0, QColor(20, 255, 171, pressed ? 0xcc : 0xff));
gradient.setColorAt(1, QColor(35, 149, 255, pressed ? 0xcc : 0xff));
}
p.fillPath(path, gradient);
// vertical line
p.setPen(QPen(QColor(0, 0, 0, 0x4d), 3, Qt::SolidLine));
int line_x = rect().right() - img_width - (2 * horizontal_padding);
p.drawLine(line_x, rect().bottom(), line_x, rect().top());
}
void ExperimentalModeButton::showEvent(QShowEvent *event) {
if (params.getBool("ConditionalExperimental")) {
int status = params_memory.getInt("CEStatus");
if ((status != 1 && status != 2) && params.getBool("PersistExperimentalState")) {
status = params.getInt("PersistedCEStatus");
}
experimental_mode = !params.getBool("SafeMode") && status == 2;
} else if (params.getBool("ConditionalChill")) {
int status = params_memory.getInt("CCStatus");
if ((status != 1 && status != 2) && params.getBool("PersistChillState")) {
status = params.getInt("PersistedCCStatus");
}
experimental_mode = !params.getBool("SafeMode") && (status == 0 || status == 1);
} else {
experimental_mode = params.getBool("ExperimentalMode") && !params.getBool("SafeMode");
}
mode_icon->setPixmap(experimental_mode ? experimental_pixmap : chill_pixmap);
mode_label->setText(experimental_mode ? tr("EXPERIMENTAL MODE ON") : tr("CHILL MODE ON"));
}
@@ -1,32 +0,0 @@
#pragma once
#include <QLabel>
#include <QPushButton>
#include "common/params.h"
class ExperimentalModeButton : public QPushButton {
Q_OBJECT
public:
explicit ExperimentalModeButton(QWidget* parent = 0);
signals:
void openSettings(int index = 0, const QString &toggle = "");
private:
void showEvent(QShowEvent *event) override;
Params params;
Params params_memory{"", true};
bool experimental_mode;
int img_width = 100;
int horizontal_padding = 30;
QPixmap experimental_pixmap;
QPixmap chill_pixmap;
QLabel *mode_label;
QLabel *mode_icon;
protected:
void paintEvent(QPaintEvent *event) override;
};
@@ -1,177 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'developer_panel.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "developer_panel.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'developer_panel.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_DeveloperPanel_t {
QByteArrayData data[7];
char stringdata0[90];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_DeveloperPanel_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_DeveloperPanel_t qt_meta_stringdata_DeveloperPanel = {
{
QT_MOC_LITERAL(0, 0, 14), // "DeveloperPanel"
QT_MOC_LITERAL(1, 15, 12), // "openSubPanel"
QT_MOC_LITERAL(2, 28, 0), // ""
QT_MOC_LITERAL(3, 29, 15), // "openSubSubPanel"
QT_MOC_LITERAL(4, 45, 21), // "showAllTogglesChanged"
QT_MOC_LITERAL(5, 67, 13), // "updateToggles"
QT_MOC_LITERAL(6, 81, 8) // "_offroad"
},
"DeveloperPanel\0openSubPanel\0\0"
"openSubSubPanel\0showAllTogglesChanged\0"
"updateToggles\0_offroad"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_DeveloperPanel[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
4, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
3, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 34, 2, 0x06 /* Public */,
3, 0, 35, 2, 0x06 /* Public */,
4, 0, 36, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
5, 1, 37, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
QMetaType::Void,
// slots: parameters
QMetaType::Void, QMetaType::Bool, 6,
0 // eod
};
void DeveloperPanel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<DeveloperPanel *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->openSubPanel(); break;
case 1: _t->openSubSubPanel(); break;
case 2: _t->showAllTogglesChanged(); break;
case 3: _t->updateToggles((*reinterpret_cast< bool(*)>(_a[1]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (DeveloperPanel::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DeveloperPanel::openSubPanel)) {
*result = 0;
return;
}
}
{
using _t = void (DeveloperPanel::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DeveloperPanel::openSubSubPanel)) {
*result = 1;
return;
}
}
{
using _t = void (DeveloperPanel::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DeveloperPanel::showAllTogglesChanged)) {
*result = 2;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject DeveloperPanel::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_DeveloperPanel.data,
qt_meta_data_DeveloperPanel,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *DeveloperPanel::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *DeveloperPanel::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_DeveloperPanel.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int DeveloperPanel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 4)
qt_static_metacall(this, _c, _id, _a);
_id -= 4;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 4)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 4;
}
return _id;
}
// SIGNAL 0
void DeveloperPanel::openSubPanel()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
// SIGNAL 1
void DeveloperPanel::openSubSubPanel()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
// SIGNAL 2
void DeveloperPanel::showAllTogglesChanged()
{
QMetaObject::activate(this, &staticMetaObject, 2, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-133
View File
@@ -1,133 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'driverview.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "driverview.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'driverview.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_DriverViewWindow_t {
QByteArrayData data[3];
char stringdata0[23];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_DriverViewWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_DriverViewWindow_t qt_meta_stringdata_DriverViewWindow = {
{
QT_MOC_LITERAL(0, 0, 16), // "DriverViewWindow"
QT_MOC_LITERAL(1, 17, 4), // "done"
QT_MOC_LITERAL(2, 22, 0) // ""
},
"DriverViewWindow\0done\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_DriverViewWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
0 // eod
};
void DriverViewWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<DriverViewWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->done(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (DriverViewWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DriverViewWindow::done)) {
*result = 0;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject DriverViewWindow::staticMetaObject = { {
&CameraWidget::staticMetaObject,
qt_meta_stringdata_DriverViewWindow.data,
qt_meta_data_DriverViewWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *DriverViewWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *DriverViewWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_DriverViewWindow.stringdata0))
return static_cast<void*>(this);
return CameraWidget::qt_metacast(_clname);
}
int DriverViewWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = CameraWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void DriverViewWindow::done()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
@@ -1,142 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'experimental_mode.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "experimental_mode.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'experimental_mode.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_ExperimentalModeButton_t {
QByteArrayData data[5];
char stringdata0[50];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_ExperimentalModeButton_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_ExperimentalModeButton_t qt_meta_stringdata_ExperimentalModeButton = {
{
QT_MOC_LITERAL(0, 0, 22), // "ExperimentalModeButton"
QT_MOC_LITERAL(1, 23, 12), // "openSettings"
QT_MOC_LITERAL(2, 36, 0), // ""
QT_MOC_LITERAL(3, 37, 5), // "index"
QT_MOC_LITERAL(4, 43, 6) // "toggle"
},
"ExperimentalModeButton\0openSettings\0"
"\0index\0toggle"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_ExperimentalModeButton[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
3, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
3, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 29, 2, 0x06 /* Public */,
1, 1, 34, 2, 0x26 /* Public | MethodCloned */,
1, 0, 37, 2, 0x26 /* Public | MethodCloned */,
// signals: parameters
QMetaType::Void, QMetaType::Int, QMetaType::QString, 3, 4,
QMetaType::Void, QMetaType::Int, 3,
QMetaType::Void,
0 // eod
};
void ExperimentalModeButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<ExperimentalModeButton *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->openSettings((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< const QString(*)>(_a[2]))); break;
case 1: _t->openSettings((*reinterpret_cast< int(*)>(_a[1]))); break;
case 2: _t->openSettings(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (ExperimentalModeButton::*)(int , const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&ExperimentalModeButton::openSettings)) {
*result = 0;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject ExperimentalModeButton::staticMetaObject = { {
&QPushButton::staticMetaObject,
qt_meta_stringdata_ExperimentalModeButton.data,
qt_meta_data_ExperimentalModeButton,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *ExperimentalModeButton::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *ExperimentalModeButton::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_ExperimentalModeButton.stringdata0))
return static_cast<void*>(this);
return QPushButton::qt_metacast(_clname);
}
int ExperimentalModeButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QPushButton::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 3)
qt_static_metacall(this, _c, _id, _a);
_id -= 3;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 3)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 3;
}
return _id;
}
// SIGNAL 0
void ExperimentalModeButton::openSettings(int _t1, const QString & _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-477
View File
@@ -1,477 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'onboarding.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "onboarding.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'onboarding.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_TrainingGuide_t {
QByteArrayData data[3];
char stringdata0[33];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_TrainingGuide_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_TrainingGuide_t qt_meta_stringdata_TrainingGuide = {
{
QT_MOC_LITERAL(0, 0, 13), // "TrainingGuide"
QT_MOC_LITERAL(1, 14, 17), // "completedTraining"
QT_MOC_LITERAL(2, 32, 0) // ""
},
"TrainingGuide\0completedTraining\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_TrainingGuide[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
0 // eod
};
void TrainingGuide::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<TrainingGuide *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->completedTraining(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (TrainingGuide::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&TrainingGuide::completedTraining)) {
*result = 0;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject TrainingGuide::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_TrainingGuide.data,
qt_meta_data_TrainingGuide,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *TrainingGuide::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *TrainingGuide::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_TrainingGuide.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int TrainingGuide::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void TrainingGuide::completedTraining()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
struct qt_meta_stringdata_TermsPage_t {
QByteArrayData data[4];
char stringdata0[39];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_TermsPage_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_TermsPage_t qt_meta_stringdata_TermsPage = {
{
QT_MOC_LITERAL(0, 0, 9), // "TermsPage"
QT_MOC_LITERAL(1, 10, 13), // "acceptedTerms"
QT_MOC_LITERAL(2, 24, 0), // ""
QT_MOC_LITERAL(3, 25, 13) // "declinedTerms"
},
"TermsPage\0acceptedTerms\0\0declinedTerms"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_TermsPage[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 24, 2, 0x06 /* Public */,
3, 0, 25, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
0 // eod
};
void TermsPage::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<TermsPage *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->acceptedTerms(); break;
case 1: _t->declinedTerms(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (TermsPage::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&TermsPage::acceptedTerms)) {
*result = 0;
return;
}
}
{
using _t = void (TermsPage::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&TermsPage::declinedTerms)) {
*result = 1;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject TermsPage::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_TermsPage.data,
qt_meta_data_TermsPage,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *TermsPage::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *TermsPage::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_TermsPage.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int TermsPage::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
// SIGNAL 0
void TermsPage::acceptedTerms()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
// SIGNAL 1
void TermsPage::declinedTerms()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
struct qt_meta_stringdata_DeclinePage_t {
QByteArrayData data[3];
char stringdata0[21];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_DeclinePage_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_DeclinePage_t qt_meta_stringdata_DeclinePage = {
{
QT_MOC_LITERAL(0, 0, 11), // "DeclinePage"
QT_MOC_LITERAL(1, 12, 7), // "getBack"
QT_MOC_LITERAL(2, 20, 0) // ""
},
"DeclinePage\0getBack\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_DeclinePage[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
0 // eod
};
void DeclinePage::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<DeclinePage *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->getBack(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (DeclinePage::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DeclinePage::getBack)) {
*result = 0;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject DeclinePage::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_DeclinePage.data,
qt_meta_data_DeclinePage,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *DeclinePage::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *DeclinePage::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_DeclinePage.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int DeclinePage::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void DeclinePage::getBack()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
struct qt_meta_stringdata_OnboardingWindow_t {
QByteArrayData data[3];
char stringdata0[33];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_OnboardingWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_OnboardingWindow_t qt_meta_stringdata_OnboardingWindow = {
{
QT_MOC_LITERAL(0, 0, 16), // "OnboardingWindow"
QT_MOC_LITERAL(1, 17, 14), // "onboardingDone"
QT_MOC_LITERAL(2, 32, 0) // ""
},
"OnboardingWindow\0onboardingDone\0"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_OnboardingWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 19, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
0 // eod
};
void OnboardingWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<OnboardingWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->onboardingDone(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (OnboardingWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&OnboardingWindow::onboardingDone)) {
*result = 0;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject OnboardingWindow::staticMetaObject = { {
&QStackedWidget::staticMetaObject,
qt_meta_stringdata_OnboardingWindow.data,
qt_meta_data_OnboardingWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *OnboardingWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *OnboardingWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_OnboardingWindow.stringdata0))
return static_cast<void*>(this);
return QStackedWidget::qt_metacast(_clname);
}
int OnboardingWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QStackedWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 1)
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 1)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 1;
}
return _id;
}
// SIGNAL 0
void OnboardingWindow::onboardingDone()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-756
View File
@@ -1,756 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'settings.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "settings.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'settings.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_SettingsWindow_t {
QByteArrayData data[16];
char stringdata0[220];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_SettingsWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_SettingsWindow_t qt_meta_stringdata_SettingsWindow = {
{
QT_MOC_LITERAL(0, 0, 14), // "SettingsWindow"
QT_MOC_LITERAL(1, 15, 13), // "closeSettings"
QT_MOC_LITERAL(2, 29, 0), // ""
QT_MOC_LITERAL(3, 30, 19), // "reviewTrainingGuide"
QT_MOC_LITERAL(4, 50, 14), // "showDriverView"
QT_MOC_LITERAL(5, 65, 23), // "expandToggleDescription"
QT_MOC_LITERAL(6, 89, 5), // "param"
QT_MOC_LITERAL(7, 95, 14), // "scrollToToggle"
QT_MOC_LITERAL(8, 110, 10), // "closePanel"
QT_MOC_LITERAL(9, 121, 13), // "closeSubPanel"
QT_MOC_LITERAL(10, 135, 16), // "closeSubSubPanel"
QT_MOC_LITERAL(11, 152, 19), // "closeSubSubSubPanel"
QT_MOC_LITERAL(12, 172, 12), // "updateMetric"
QT_MOC_LITERAL(13, 185, 8), // "isMetric"
QT_MOC_LITERAL(14, 194, 7), // "bootRun"
QT_MOC_LITERAL(15, 202, 17) // "updateTuningLevel"
},
"SettingsWindow\0closeSettings\0\0"
"reviewTrainingGuide\0showDriverView\0"
"expandToggleDescription\0param\0"
"scrollToToggle\0closePanel\0closeSubPanel\0"
"closeSubSubPanel\0closeSubSubSubPanel\0"
"updateMetric\0isMetric\0bootRun\0"
"updateTuningLevel"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_SettingsWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
12, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
12, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 74, 2, 0x06 /* Public */,
3, 0, 75, 2, 0x06 /* Public */,
4, 0, 76, 2, 0x06 /* Public */,
5, 1, 77, 2, 0x06 /* Public */,
7, 1, 80, 2, 0x06 /* Public */,
8, 0, 83, 2, 0x06 /* Public */,
9, 0, 84, 2, 0x06 /* Public */,
10, 0, 85, 2, 0x06 /* Public */,
11, 0, 86, 2, 0x06 /* Public */,
12, 2, 87, 2, 0x06 /* Public */,
12, 1, 92, 2, 0x26 /* Public | MethodCloned */,
15, 0, 95, 2, 0x06 /* Public */,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
QMetaType::Void,
QMetaType::Void, QMetaType::QString, 6,
QMetaType::Void, QMetaType::QString, 6,
QMetaType::Void,
QMetaType::Void,
QMetaType::Void,
QMetaType::Void,
QMetaType::Void, QMetaType::Bool, QMetaType::Bool, 13, 14,
QMetaType::Void, QMetaType::Bool, 13,
QMetaType::Void,
0 // eod
};
void SettingsWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<SettingsWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->closeSettings(); break;
case 1: _t->reviewTrainingGuide(); break;
case 2: _t->showDriverView(); break;
case 3: _t->expandToggleDescription((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 4: _t->scrollToToggle((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 5: _t->closePanel(); break;
case 6: _t->closeSubPanel(); break;
case 7: _t->closeSubSubPanel(); break;
case 8: _t->closeSubSubSubPanel(); break;
case 9: _t->updateMetric((*reinterpret_cast< bool(*)>(_a[1])),(*reinterpret_cast< bool(*)>(_a[2]))); break;
case 10: _t->updateMetric((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 11: _t->updateTuningLevel(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::closeSettings)) {
*result = 0;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::reviewTrainingGuide)) {
*result = 1;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::showDriverView)) {
*result = 2;
return;
}
}
{
using _t = void (SettingsWindow::*)(const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::expandToggleDescription)) {
*result = 3;
return;
}
}
{
using _t = void (SettingsWindow::*)(const QString & );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::scrollToToggle)) {
*result = 4;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::closePanel)) {
*result = 5;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::closeSubPanel)) {
*result = 6;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::closeSubSubPanel)) {
*result = 7;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::closeSubSubSubPanel)) {
*result = 8;
return;
}
}
{
using _t = void (SettingsWindow::*)(bool , bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::updateMetric)) {
*result = 9;
return;
}
}
{
using _t = void (SettingsWindow::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&SettingsWindow::updateTuningLevel)) {
*result = 11;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject SettingsWindow::staticMetaObject = { {
&QFrame::staticMetaObject,
qt_meta_stringdata_SettingsWindow.data,
qt_meta_data_SettingsWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *SettingsWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *SettingsWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_SettingsWindow.stringdata0))
return static_cast<void*>(this);
return QFrame::qt_metacast(_clname);
}
int SettingsWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QFrame::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 12)
qt_static_metacall(this, _c, _id, _a);
_id -= 12;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 12)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 12;
}
return _id;
}
// SIGNAL 0
void SettingsWindow::closeSettings()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
// SIGNAL 1
void SettingsWindow::reviewTrainingGuide()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
// SIGNAL 2
void SettingsWindow::showDriverView()
{
QMetaObject::activate(this, &staticMetaObject, 2, nullptr);
}
// SIGNAL 3
void SettingsWindow::expandToggleDescription(const QString & _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 3, _a);
}
// SIGNAL 4
void SettingsWindow::scrollToToggle(const QString & _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 4, _a);
}
// SIGNAL 5
void SettingsWindow::closePanel()
{
QMetaObject::activate(this, &staticMetaObject, 5, nullptr);
}
// SIGNAL 6
void SettingsWindow::closeSubPanel()
{
QMetaObject::activate(this, &staticMetaObject, 6, nullptr);
}
// SIGNAL 7
void SettingsWindow::closeSubSubPanel()
{
QMetaObject::activate(this, &staticMetaObject, 7, nullptr);
}
// SIGNAL 8
void SettingsWindow::closeSubSubSubPanel()
{
QMetaObject::activate(this, &staticMetaObject, 8, nullptr);
}
// SIGNAL 9
void SettingsWindow::updateMetric(bool _t1, bool _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 9, _a);
}
// SIGNAL 11
void SettingsWindow::updateTuningLevel()
{
QMetaObject::activate(this, &staticMetaObject, 11, nullptr);
}
struct qt_meta_stringdata_GalaxyQRPopup_t {
QByteArrayData data[1];
char stringdata0[14];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_GalaxyQRPopup_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_GalaxyQRPopup_t qt_meta_stringdata_GalaxyQRPopup = {
{
QT_MOC_LITERAL(0, 0, 13) // "GalaxyQRPopup"
},
"GalaxyQRPopup"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_GalaxyQRPopup[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void GalaxyQRPopup::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject GalaxyQRPopup::staticMetaObject = { {
&DialogBase::staticMetaObject,
qt_meta_stringdata_GalaxyQRPopup.data,
qt_meta_data_GalaxyQRPopup,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *GalaxyQRPopup::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *GalaxyQRPopup::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_GalaxyQRPopup.stringdata0))
return static_cast<void*>(this);
return DialogBase::qt_metacast(_clname);
}
int GalaxyQRPopup::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = DialogBase::qt_metacall(_c, _id, _a);
return _id;
}
struct qt_meta_stringdata_DevicePanel_t {
QByteArrayData data[7];
char stringdata0[87];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_DevicePanel_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_DevicePanel_t qt_meta_stringdata_DevicePanel = {
{
QT_MOC_LITERAL(0, 0, 11), // "DevicePanel"
QT_MOC_LITERAL(1, 12, 19), // "reviewTrainingGuide"
QT_MOC_LITERAL(2, 32, 0), // ""
QT_MOC_LITERAL(3, 33, 14), // "showDriverView"
QT_MOC_LITERAL(4, 48, 8), // "poweroff"
QT_MOC_LITERAL(5, 57, 6), // "reboot"
QT_MOC_LITERAL(6, 64, 22) // "updateCalibDescription"
},
"DevicePanel\0reviewTrainingGuide\0\0"
"showDriverView\0poweroff\0reboot\0"
"updateCalibDescription"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_DevicePanel[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
5, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// signals: name, argc, parameters, tag, flags
1, 0, 39, 2, 0x06 /* Public */,
3, 0, 40, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
4, 0, 41, 2, 0x08 /* Private */,
5, 0, 42, 2, 0x08 /* Private */,
6, 0, 43, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void,
QMetaType::Void,
// slots: parameters
QMetaType::Void,
QMetaType::Void,
QMetaType::Void,
0 // eod
};
void DevicePanel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<DevicePanel *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->reviewTrainingGuide(); break;
case 1: _t->showDriverView(); break;
case 2: _t->poweroff(); break;
case 3: _t->reboot(); break;
case 4: _t->updateCalibDescription(); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (DevicePanel::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DevicePanel::reviewTrainingGuide)) {
*result = 0;
return;
}
}
{
using _t = void (DevicePanel::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&DevicePanel::showDriverView)) {
*result = 1;
return;
}
}
}
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject DevicePanel::staticMetaObject = { {
&ListWidget::staticMetaObject,
qt_meta_stringdata_DevicePanel.data,
qt_meta_data_DevicePanel,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *DevicePanel::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *DevicePanel::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_DevicePanel.stringdata0))
return static_cast<void*>(this);
return ListWidget::qt_metacast(_clname);
}
int DevicePanel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = ListWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 5)
qt_static_metacall(this, _c, _id, _a);
_id -= 5;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 5)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 5;
}
return _id;
}
// SIGNAL 0
void DevicePanel::reviewTrainingGuide()
{
QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}
// SIGNAL 1
void DevicePanel::showDriverView()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
struct qt_meta_stringdata_TogglesPanel_t {
QByteArrayData data[13];
char stringdata0[135];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_TogglesPanel_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_TogglesPanel_t qt_meta_stringdata_TogglesPanel = {
{
QT_MOC_LITERAL(0, 0, 12), // "TogglesPanel"
QT_MOC_LITERAL(1, 13, 12), // "updateMetric"
QT_MOC_LITERAL(2, 26, 0), // ""
QT_MOC_LITERAL(3, 27, 6), // "metric"
QT_MOC_LITERAL(4, 34, 7), // "bootRun"
QT_MOC_LITERAL(5, 42, 17), // "simpleModeChanged"
QT_MOC_LITERAL(6, 60, 7), // "enabled"
QT_MOC_LITERAL(7, 68, 23), // "expandToggleDescription"
QT_MOC_LITERAL(8, 92, 5), // "param"
QT_MOC_LITERAL(9, 98, 14), // "scrollToToggle"
QT_MOC_LITERAL(10, 113, 11), // "updateState"
QT_MOC_LITERAL(11, 125, 7), // "UIState"
QT_MOC_LITERAL(12, 133, 1) // "s"
},
"TogglesPanel\0updateMetric\0\0metric\0"
"bootRun\0simpleModeChanged\0enabled\0"
"expandToggleDescription\0param\0"
"scrollToToggle\0updateState\0UIState\0s"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_TogglesPanel[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
6, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
3, // signalCount
// signals: name, argc, parameters, tag, flags
1, 2, 44, 2, 0x06 /* Public */,
1, 1, 49, 2, 0x26 /* Public | MethodCloned */,
5, 1, 52, 2, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
7, 1, 55, 2, 0x0a /* Public */,
9, 1, 58, 2, 0x0a /* Public */,
10, 1, 61, 2, 0x08 /* Private */,
// signals: parameters
QMetaType::Void, QMetaType::Bool, QMetaType::Bool, 3, 4,
QMetaType::Void, QMetaType::Bool, 3,
QMetaType::Void, QMetaType::Bool, 6,
// slots: parameters
QMetaType::Void, QMetaType::QString, 8,
QMetaType::Void, QMetaType::QString, 8,
QMetaType::Void, 0x80000000 | 11, 12,
0 // eod
};
void TogglesPanel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<TogglesPanel *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->updateMetric((*reinterpret_cast< bool(*)>(_a[1])),(*reinterpret_cast< bool(*)>(_a[2]))); break;
case 1: _t->updateMetric((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 2: _t->simpleModeChanged((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 3: _t->expandToggleDescription((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 4: _t->scrollToToggle((*reinterpret_cast< const QString(*)>(_a[1]))); break;
case 5: _t->updateState((*reinterpret_cast< const UIState(*)>(_a[1]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (TogglesPanel::*)(bool , bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&TogglesPanel::updateMetric)) {
*result = 0;
return;
}
}
{
using _t = void (TogglesPanel::*)(bool );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&TogglesPanel::simpleModeChanged)) {
*result = 2;
return;
}
}
}
}
QT_INIT_METAOBJECT const QMetaObject TogglesPanel::staticMetaObject = { {
&ListWidget::staticMetaObject,
qt_meta_stringdata_TogglesPanel.data,
qt_meta_data_TogglesPanel,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *TogglesPanel::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *TogglesPanel::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_TogglesPanel.stringdata0))
return static_cast<void*>(this);
return ListWidget::qt_metacast(_clname);
}
int TogglesPanel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = ListWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 6)
qt_static_metacall(this, _c, _id, _a);
_id -= 6;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 6)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 6;
}
return _id;
}
// SIGNAL 0
void TogglesPanel::updateMetric(bool _t1, bool _t2)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 2
void TogglesPanel::simpleModeChanged(bool _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 2, _a);
}
struct qt_meta_stringdata_SoftwarePanel_t {
QByteArrayData data[1];
char stringdata0[14];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_SoftwarePanel_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_SoftwarePanel_t qt_meta_stringdata_SoftwarePanel = {
{
QT_MOC_LITERAL(0, 0, 13) // "SoftwarePanel"
},
"SoftwarePanel"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_SoftwarePanel[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void SoftwarePanel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject SoftwarePanel::staticMetaObject = { {
&ListWidget::staticMetaObject,
qt_meta_stringdata_SoftwarePanel.data,
qt_meta_data_SoftwarePanel,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *SoftwarePanel::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *SoftwarePanel::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_SoftwarePanel.stringdata0))
return static_cast<void*>(this);
return ListWidget::qt_metacast(_clname);
}
int SoftwarePanel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = ListWidget::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-211
View File
@@ -1,211 +0,0 @@
#include "selfdrive/ui/qt/offroad/onboarding.h"
#include <string>
#include <QLabel>
#include <QPainter>
#include <QTransform>
#include <QVBoxLayout>
#include "common/util.h"
#include "common/params.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/input.h"
TrainingGuide::TrainingGuide(QWidget *parent) : QFrame(parent) {
setAttribute(Qt::WA_OpaquePaintEvent);
}
void TrainingGuide::mouseReleaseEvent(QMouseEvent *e) {
if (click_timer.elapsed() < 250) {
return;
}
click_timer.restart();
auto contains = [this](QRect r, const QPoint &pt) {
if (image.size() != image_raw_size) {
QTransform transform;
transform.translate((width()- image.width()) / 2.0, (height()- image.height()) / 2.0);
transform.scale(image.width() / (float)image_raw_size.width(), image.height() / (float)image_raw_size.height());
r= transform.mapRect(r);
}
return r.contains(pt);
};
if (contains(boundingRect[currentIndex], e->pos())) {
if (currentIndex == 9) {
const QRect yes = QRect(707, 804, 531, 164);
Params().putBool("RecordFront", contains(yes, e->pos()));
}
currentIndex += 1;
} else if (currentIndex == (boundingRect.size() - 2) && contains(boundingRect.last(), e->pos())) {
currentIndex = 0;
}
if (currentIndex >= (boundingRect.size() - 1)) {
emit completedTraining();
} else {
update();
}
}
void TrainingGuide::showEvent(QShowEvent *event) {
currentIndex = 0;
click_timer.start();
}
QImage TrainingGuide::loadImage(int id) {
QImage img(img_path + QString("step%1.png").arg(id));
image_raw_size = img.size();
if (image_raw_size != rect().size()) {
img = img.scaled(width(), height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
return img;
}
void TrainingGuide::paintEvent(QPaintEvent *event) {
QPainter painter(this);
QRect bg(0, 0, painter.device()->width(), painter.device()->height());
painter.fillRect(bg, QColor("#000000"));
image = loadImage(currentIndex);
QRect rect(image.rect());
rect.moveCenter(bg.center());
painter.drawImage(rect.topLeft(), image);
// progress bar
if (currentIndex > 0 && currentIndex < (boundingRect.size() - 2)) {
const int h = 20;
const int w = (currentIndex / (float)(boundingRect.size() - 2)) * width();
painter.fillRect(QRect(0, height() - h, w, h), QColor("#465BEA"));
}
}
void TermsPage::showEvent(QShowEvent *event) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(45, 35, 45, 45);
main_layout->setSpacing(0);
QVBoxLayout *vlayout = new QVBoxLayout();
vlayout->setContentsMargins(165, 165, 165, 0);
main_layout->addLayout(vlayout);
QLabel *title = new QLabel(tr("Welcome to openpilot"));
title->setStyleSheet("font-size: 90px; font-weight: 500;");
vlayout->addWidget(title, 0, Qt::AlignTop | Qt::AlignLeft);
vlayout->addSpacing(90);
QLabel *desc = new QLabel(tr("You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing."));
desc->setWordWrap(true);
desc->setStyleSheet("font-size: 80px; font-weight: 300;");
vlayout->addWidget(desc, 0);
vlayout->addStretch();
QHBoxLayout* buttons = new QHBoxLayout;
buttons->setMargin(0);
buttons->setSpacing(45);
main_layout->addLayout(buttons);
QPushButton *decline_btn = new QPushButton(tr("Decline"));
buttons->addWidget(decline_btn);
QObject::connect(decline_btn, &QPushButton::clicked, this, &TermsPage::declinedTerms);
accept_btn = new QPushButton(tr("Agree"));
accept_btn->setStyleSheet(R"(
QPushButton {
background-color: #465BEA;
}
QPushButton:pressed {
background-color: #3049F4;
}
)");
buttons->addWidget(accept_btn);
QObject::connect(accept_btn, &QPushButton::clicked, this, &TermsPage::acceptedTerms);
}
void DeclinePage::showEvent(QShowEvent *event) {
if (layout()) {
return;
}
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setMargin(45);
main_layout->setSpacing(40);
QLabel *text = new QLabel(this);
text->setText(tr("You must accept the Terms and Conditions in order to use openpilot."));
text->setStyleSheet(R"(font-size: 80px; font-weight: 300; margin: 200px;)");
text->setWordWrap(true);
main_layout->addWidget(text, 0, Qt::AlignCenter);
QHBoxLayout* buttons = new QHBoxLayout;
buttons->setSpacing(45);
main_layout->addLayout(buttons);
QPushButton *back_btn = new QPushButton(tr("Back"));
buttons->addWidget(back_btn);
QObject::connect(back_btn, &QPushButton::clicked, this, &DeclinePage::getBack);
QPushButton *uninstall_btn = new QPushButton(tr("Decline, uninstall %1").arg(getBrand()));
uninstall_btn->setStyleSheet("background-color: #B73D3D");
buttons->addWidget(uninstall_btn);
QObject::connect(uninstall_btn, &QPushButton::clicked, [=]() {
Params().putBool("DoUninstall", true);
});
}
void OnboardingWindow::updateActiveScreen() {
if (!accepted_terms) {
setCurrentIndex(0);
} else if (!training_done) {
setCurrentIndex(1);
} else {
emit onboardingDone();
}
}
OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) {
std::string current_terms_version = params.get("TermsVersion");
std::string current_training_version = params.get("TrainingVersion");
accepted_terms = params.get("HasAcceptedTerms") == current_terms_version;
training_done = params.get("CompletedTrainingVersion") == current_training_version;
TermsPage* terms = new TermsPage(this);
addWidget(terms);
connect(terms, &TermsPage::acceptedTerms, [=]() {
params.put("HasAcceptedTerms", current_terms_version);
accepted_terms = true;
updateActiveScreen();
});
connect(terms, &TermsPage::declinedTerms, [=]() { setCurrentIndex(2); });
TrainingGuide* tr = new TrainingGuide(this);
addWidget(tr);
connect(tr, &TrainingGuide::completedTraining, [=]() {
training_done = true;
params.put("CompletedTrainingVersion", current_training_version);
updateActiveScreen();
});
DeclinePage* declinePage = new DeclinePage(this);
addWidget(declinePage);
connect(declinePage, &DeclinePage::getBack, [=]() { updateActiveScreen(); });
setStyleSheet(R"(
* {
color: white;
background-color: black;
}
QPushButton {
height: 160px;
font-size: 55px;
font-weight: 400;
border-radius: 10px;
background-color: #4F4F4F;
}
)");
updateActiveScreen();
}
-107
View File
@@ -1,107 +0,0 @@
#pragma once
#include <QElapsedTimer>
#include <QImage>
#include <QMouseEvent>
#include <QPushButton>
#include <QStackedWidget>
#include <QWidget>
#include "common/params.h"
#include "selfdrive/ui/qt/qt_window.h"
class TrainingGuide : public QFrame {
Q_OBJECT
public:
explicit TrainingGuide(QWidget *parent = 0);
private:
void showEvent(QShowEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void mouseReleaseEvent(QMouseEvent* e) override;
QImage loadImage(int id);
QImage image;
QSize image_raw_size;
int currentIndex = 0;
// Bounding boxes for each training guide step
const QRect continueBtn = {1840, 0, 320, 1080};
QVector<QRect> boundingRect {
QRect(112, 804, 618, 164),
continueBtn,
continueBtn,
QRect(1641, 558, 210, 313),
QRect(1662, 528, 184, 108),
continueBtn,
QRect(1814, 621, 211, 170),
QRect(1350, 0, 497, 755),
QRect(1540, 386, 468, 238),
QRect(112, 804, 1126, 164),
QRect(1598, 199, 316, 333),
continueBtn,
QRect(1364, 90, 796, 990),
continueBtn,
QRect(1593, 114, 318, 853),
QRect(1379, 511, 391, 243),
continueBtn,
continueBtn,
QRect(630, 804, 626, 164),
QRect(108, 804, 426, 164),
};
const QString img_path = "../assets/training/";
QElapsedTimer click_timer;
signals:
void completedTraining();
};
class TermsPage : public QFrame {
Q_OBJECT
public:
explicit TermsPage(QWidget *parent = 0) : QFrame(parent) {}
private:
void showEvent(QShowEvent *event) override;
QPushButton *accept_btn;
signals:
void acceptedTerms();
void declinedTerms();
};
class DeclinePage : public QFrame {
Q_OBJECT
public:
explicit DeclinePage(QWidget *parent = 0) : QFrame(parent) {}
private:
void showEvent(QShowEvent *event) override;
signals:
void getBack();
};
class OnboardingWindow : public QStackedWidget {
Q_OBJECT
public:
explicit OnboardingWindow(QWidget *parent = 0);
inline void showTrainingGuide() { setCurrentIndex(1); }
inline bool completed() const { return accepted_terms && training_done; }
private:
void updateActiveScreen();
Params params;
bool accepted_terms = false, training_done = false;
signals:
void onboardingDone();
};
-897
View File
@@ -1,897 +0,0 @@
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <tuple>
#include <vector>
#include <QCryptographicHash>
#include <QDebug>
#include <QRandomGenerator>
#include <QrCode.hpp>
#include "common/watchdog.h"
#include "common/util.h"
#include "system/hardware/hw.h"
#include "selfdrive/ui/qt/network/networking.h"
#include "selfdrive/ui/qt/offroad/settings.h"
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/widgets/input.h"
#include "selfdrive/ui/qt/widgets/prime.h"
#include "selfdrive/ui/qt/widgets/scrollview.h"
#include "selfdrive/ui/qt/offroad/developer_panel.h"
#include "starpilot/ui/qt/offroad/starpilot_settings.h"
TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
syncRhdToggle();
// param, title, desc, icon, restart needed
std::vector<std::tuple<QString, QString, QString, QString, bool>> toggle_defs{
{
"OpenpilotEnabledToggle",
tr("Enable openpilot"),
tr("Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature."),
"../assets/icons/chffr_wheel.png",
true,
},
{
"ExperimentalMode",
tr("Experimental Mode"),
"",
"../assets/icons/experimental_white.svg",
false,
},
{
"SafeMode",
tr("Safe Mode"),
tr("Temporarily force driving-affecting StarPilot settings back to safe defaults, stock tuning, and the branch default model until disabled."),
"../assets/icons/warning.png",
true,
},
{
"SimpleMode",
tr("Simple Mode"),
tr("Use a more stock-like Qt interface by hiding most branch-specific UI, theme, sound, and alert styling. This only changes presentation and does not change driving behavior."),
"../assets/icons/settings.png",
false,
},
{
"DisengageOnAccelerator",
tr("Disengage on Accelerator Pedal"),
tr("When enabled, pressing the accelerator pedal will disengage openpilot."),
"../assets/icons/disengage_on_accelerator.svg",
false,
},
{
"IsLdwEnabled",
tr("Enable Lane Departure Warnings"),
tr("Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h)."),
"../assets/icons/warning.png",
false,
},
{
"AlwaysOnDM",
tr("Always-On Driver Monitoring"),
tr("Enable driver monitoring even when openpilot is not engaged."),
"../assets/icons/monitoring.png",
false,
},
{
"IsRHD",
tr("Right Hand Driving"),
tr("Use right-hand-drive driver monitoring. This follows the auto-detected side until changed manually."),
"../assets/icons/monitoring.png",
false,
},
{
"RecordFront",
tr("Record and Upload Driver Camera"),
tr("Upload data from the driver facing camera and help improve the driver monitoring algorithm."),
"../assets/icons/monitoring.png",
true,
},
{
"RecordAudio",
tr("Record and Upload Microphone Audio"),
tr("Record and store microphone audio while driving. The audio will be included in the dashcam video in comma connect."),
"../assets/icons/microphone.png",
true,
},
{
"IsMetric",
tr("Use Metric System"),
tr("Display speed in km/h instead of mph."),
"../assets/icons/metric.png",
false,
},
};
std::vector<QString> longi_button_texts{tr("Aggressive"), tr("Standard"), tr("Relaxed")};
long_personality_setting = new ButtonParamControl("LongitudinalPersonality", tr("Driving Personality"),
tr("Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. "
"In relaxed mode openpilot will stay further away from lead cars. On supported cars, you can cycle through these personalities with "
"your steering wheel distance button."),
"../assets/icons/speed_limit.png",
longi_button_texts);
// set up uiState update for personality setting
QObject::connect(uiState(), &UIState::uiUpdate, this, &TogglesPanel::updateState);
for (auto &[param, title, desc, icon, needs_restart] : toggle_defs) {
auto toggle = new ParamControl(param, title, desc, icon, this);
bool locked = params.getBool((param + "Lock").toStdString());
toggle->setEnabled(!locked);
if (needs_restart && !locked) {
toggle->setDescription(toggle->getDescription() + tr(" Changing this setting will restart openpilot if the car is powered on."));
QObject::connect(uiState(), &UIState::engagedChanged, [toggle](bool engaged) {
toggle->setEnabled(!engaged);
});
QObject::connect(toggle, &ParamControl::toggleFlipped, [=](bool state) {
params.putBool("OnroadCycleRequested", true);
});
}
if (param == "SimpleMode") {
QObject::connect(toggle, &ParamControl::toggleFlipped, this, [this](bool state) {
updateToggles();
emit simpleModeChanged(state);
});
}
if (param == "IsRHD") {
QObject::connect(toggle, &ParamControl::toggleFlipped, this, [this](bool state) {
params.putBool("IsRHD", state);
params.putBool("IsRHDOverride", true);
});
}
addItem(toggle);
toggles[param.toStdString()] = toggle;
// insert longitudinal personality after NDOG toggle
if (param == "DisengageOnAccelerator") {
addItem(long_personality_setting);
}
}
// Toggles with confirmation dialogs
toggles["ExperimentalMode"]->setActiveIcon("../assets/icons/experimental.svg");
toggles["ExperimentalMode"]->setConfirmation(true, true);
connect(toggles["IsMetric"], &ToggleControl::toggleFlipped, [=](bool isMetric) {
updateMetric(isMetric);
});
}
void TogglesPanel::syncRhdToggle() {
if (!params.getBool("IsRHDOverride")) {
params.putBool("IsRHD", params.getBool("IsRhdDetected"));
}
}
void TogglesPanel::updateState(const UIState &s) {
const SubMaster &sm = *(s.sm);
if (sm.updated("selfdriveState")) {
auto personality = sm["selfdriveState"].getSelfdriveState().getPersonality();
if (personality != s.scene.personality && s.scene.started && isVisible()) {
long_personality_setting->setCheckedButton(static_cast<int>(personality));
}
uiState()->scene.personality = personality;
}
}
void TogglesPanel::expandToggleDescription(const QString &param) {
toggles[param.toStdString()]->showDescription();
}
void TogglesPanel::scrollToToggle(const QString &param) {
if (auto it = toggles.find(param.toStdString()); it != toggles.end()) {
auto scroll_area = qobject_cast<QScrollArea*>(parent()->parent());
if (scroll_area) {
scroll_area->ensureWidgetVisible(it->second);
}
}
}
void TogglesPanel::showEvent(QShowEvent *event) {
updateToggles();
}
void TogglesPanel::updateToggles() {
syncRhdToggle();
const bool showAllToggles = params.getBool("ShowAllToggles");
const bool safe_mode = params.getBool("SafeMode");
const bool simple_mode = params.getBool("SimpleMode");
if (safe_mode) {
if (params.getBool("ExperimentalMode")) {
params.putBool("ExperimentalMode", false);
}
if (params.getInt("LongitudinalPersonality") != static_cast<int>(cereal::LongitudinalPersonality::RELAXED)) {
params.putInt("LongitudinalPersonality", static_cast<int>(cereal::LongitudinalPersonality::RELAXED));
}
}
auto experimental_mode_toggle = toggles["ExperimentalMode"];
const QString e2e_description = QString("%1<br>"
"<h4>%2</h4><br>"
"%3<br>"
"<h4>%4</h4><br>"
"%5<br>")
.arg(tr("openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below:"))
.arg(tr("End-to-End Longitudinal Control"))
.arg(tr("Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. "
"Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; "
"mistakes should be expected."))
.arg(tr("New Driving Visualization"))
.arg(tr("The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner."));
const bool is_release = false;
auto cp_bytes = params.get("CarParamsPersistent");
if (!cp_bytes.empty()) {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size()));
cereal::CarParams::Reader CP = cmsg.getRoot<cereal::CarParams>();
if (hasLongitudinalControl(CP) || showAllToggles) {
// normal description and toggle
experimental_mode_toggle->setEnabled(!safe_mode);
experimental_mode_toggle->setDescription(e2e_description);
long_personality_setting->setEnabled(!safe_mode);
if (safe_mode) {
long_personality_setting->setCheckedButton(static_cast<int>(cereal::LongitudinalPersonality::RELAXED));
}
} else {
// no long for now
experimental_mode_toggle->setEnabled(false);
long_personality_setting->setEnabled(false);
params.remove("ExperimentalMode");
const QString unavailable = tr("Experimental mode is currently unavailable on this car since the car's stock ACC is used for longitudinal control.");
QString long_desc = unavailable + " " + \
tr("openpilot longitudinal control may come in a future update.");
if (CP.getAlphaLongitudinalAvailable()) {
if (is_release) {
long_desc = unavailable + " " + tr("An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches.");
} else {
long_desc = tr("Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.");
}
}
experimental_mode_toggle->setDescription("<b>" + long_desc + "</b><br><br>" + e2e_description);
}
experimental_mode_toggle->refresh();
} else {
experimental_mode_toggle->setDescription(e2e_description);
}
if (safe_mode) {
experimental_mode_toggle->setEnabled(false);
long_personality_setting->setEnabled(false);
long_personality_setting->setCheckedButton(static_cast<int>(cereal::LongitudinalPersonality::RELAXED));
}
StarPilotUIState &fs = *starpilotUIState();
StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
auto disengage_on_accelerator_toggle = toggles["DisengageOnAccelerator"];
disengage_on_accelerator_toggle->setVisible(showAllToggles || !starpilot_toggles.value("always_on_lateral").toBool());
auto driver_camera_toggle = toggles["RecordFront"];
driver_camera_toggle->setVisible(showAllToggles || !starpilot_toggles.value("no_logging").toBool());
experimental_mode_toggle->setVisible(showAllToggles || !starpilot_toggles.value("conditional_experimental_mode").toBool());
auto record_audio_toggle = toggles["RecordAudio"];
record_audio_toggle->setVisible(showAllToggles || !starpilot_toggles.value("no_logging").toBool());
toggles["IsRHD"]->refresh();
auto safe_mode_toggle = toggles["SafeMode"];
if (safe_mode_toggle != nullptr) {
safe_mode_toggle->setVisible(!simple_mode);
}
}
GalaxyQRPopup::GalaxyQRPopup(const QString &url, QWidget *parent) : DialogBase(parent) {
setStyleSheet("GalaxyQRPopup { background-color: #1a1a30; }");
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setAlignment(Qt::AlignCenter);
layout->setSpacing(30);
layout->setContentsMargins(60, 40, 60, 40);
auto qr = qrcodegen::QrCode::encodeText(url.toUtf8().constData(), qrcodegen::QrCode::Ecc::LOW);
const int qr_size = qr.getSize();
const int quiet_zone_modules = 4;
const int qr_display_size = 520;
const int image_size = qr_size + 2 * quiet_zone_modules;
QImage image(image_size, image_size, QImage::Format_RGB32);
image.fill(qRgb(255, 255, 255));
for (int y = 0; y < qr_size; ++y) {
for (int x = 0; x < qr_size; ++x) {
image.setPixel(x + quiet_zone_modules, y + quiet_zone_modules,
qr.getModule(x, y) ? qRgb(0, 0, 0) : qRgb(255, 255, 255));
}
}
QLabel *title = new QLabel(tr("Scan to open Galaxy"), this);
title->setStyleSheet("font-size: 52px; font-weight: bold; color: white;");
title->setAlignment(Qt::AlignCenter);
layout->addWidget(title);
QLabel *qr_label = new QLabel(this);
qr_label->setPixmap(QPixmap::fromImage(
image.scaled(qr_display_size, qr_display_size, Qt::KeepAspectRatio), Qt::MonoOnly));
qr_label->setAlignment(Qt::AlignCenter);
layout->addWidget(qr_label);
QLabel *url_label = new QLabel(url, this);
url_label->setStyleSheet("font-size: 36px; color: #8b6cc5;");
url_label->setAlignment(Qt::AlignCenter);
layout->addWidget(url_label);
QLabel *hint = new QLabel(tr("Tap anywhere to dismiss"), this);
hint->setStyleSheet("font-size: 28px; color: #7e7e98;");
hint->setAlignment(Qt::AlignCenter);
layout->addWidget(hint);
}
DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
setSpacing(50);
addItem(new LabelControl(tr("Dongle ID"), getDongleId().value_or(tr("N/A"))));
addItem(new LabelControl(tr("Serial"), params.get("HardwareSerial").c_str()));
pair_device = new ButtonControl(tr("Pair Device"), tr("PAIR"),
useKonikServer() ? tr("Pair your device with Konik connect (stable.konik.ai).") : tr("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer."));
connect(pair_device, &ButtonControl::clicked, [=]() {
PairingPopup popup(this);
popup.exec();
});
addItem(pair_device);
const std::string galaxy_dir = Hardware::PC() ? (Path::comma_home() + "/starpilot/data/galaxy") : "/data/galaxy";
const std::string galaxy_auth_path = galaxy_dir + "/glxyauth";
const std::string galaxy_session_path = galaxy_dir + "/glxysession";
const std::string galaxy_slug_path = galaxy_dir + "/glxyslug";
auto showGalaxyQR = [=]() {
std::string slug = util::read_file(galaxy_slug_path);
if (slug.empty()) {
ConfirmationDialog::alert(tr("Galaxy is not paired yet."), this);
return;
}
GalaxyQRPopup popup("https://galaxy.firestar.link/" + QString::fromStdString(slug), this);
popup.exec();
};
pair_galaxy = new ButtonControl(tr("Galaxy"), tr("PAIR"), tr("Pair your device with Galaxy for remote access to The Galaxy."));
connect(pair_galaxy, &ButtonControl::clicked, [=]() {
const std::string current_password = util::read_file(galaxy_auth_path);
if (current_password.empty()) {
QString new_password = InputDialog::getText(
tr("Set Galaxy Password"), this,
tr("Set a password to secure your Galaxy access. (Min 6 characters)"),
false, 6);
if (new_password.isEmpty()) {
return;
}
std::string hash = QCryptographicHash::hash(new_password.toUtf8(), QCryptographicHash::Sha256).toHex().toStdString();
util::create_directories(galaxy_dir, 0775);
util::write_file(galaxy_auth_path.c_str(), hash.data(), hash.size(), O_WRONLY | O_CREAT | O_TRUNC);
QByteArray session_bytes(32, 0);
QRandomGenerator::securelySeeded().fillRange(reinterpret_cast<quint32 *>(session_bytes.data()), 8);
std::string session_token = session_bytes.toHex().toStdString();
util::write_file(galaxy_session_path.c_str(), session_token.data(), session_token.size(), O_WRONLY | O_CREAT | O_TRUNC);
static constexpr char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
std::string slug(16, '\0');
auto *rng = QRandomGenerator::global();
for (int i = 0; i < 16; ++i) {
slug[i] = charset[rng->bounded(62)];
}
util::write_file(galaxy_slug_path.c_str(), slug.data(), slug.size(), O_WRONLY | O_CREAT | O_TRUNC);
pair_galaxy->setText(tr("UNPAIR"));
galaxy_qr_btn->setVisible(true);
showGalaxyQR();
return;
}
if (ConfirmationDialog::confirm(tr("Are you sure you want to unpair from Galaxy?"), tr("Unpair"), this)) {
std::remove(galaxy_auth_path.c_str());
std::remove(galaxy_session_path.c_str());
std::remove(galaxy_slug_path.c_str());
pair_galaxy->setText(tr("PAIR"));
galaxy_qr_btn->setVisible(false);
}
});
galaxy_qr_btn = new QPushButton(tr("QR"));
galaxy_qr_btn->setFixedSize(250, 100);
galaxy_qr_btn->setStyleSheet(R"(
QPushButton { background-color: #393939; color: #E4E4E4; border-radius: 50px; font-size: 35px; font-weight: 500; }
QPushButton:pressed { background-color: #4a4a4a; }
)");
galaxy_qr_btn->setVisible(false);
connect(galaxy_qr_btn, &QPushButton::clicked, showGalaxyQR);
if (QHBoxLayout *hlayout = pair_galaxy->findChild<QHBoxLayout *>()) {
hlayout->insertWidget(3, galaxy_qr_btn);
}
const bool galaxy_paired = !util::read_file(galaxy_auth_path).empty();
pair_galaxy->setText(galaxy_paired ? tr("UNPAIR") : tr("PAIR"));
galaxy_qr_btn->setVisible(galaxy_paired);
addItem(pair_galaxy);
// offroad-only buttons
auto dcamBtn = new ButtonControl(tr("Driver Camera"), tr("PREVIEW"),
tr("Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off)"));
connect(dcamBtn, &ButtonControl::clicked, [=]() { emit showDriverView(); });
addItem(dcamBtn);
resetDmCalibBtn = new ButtonControl(
tr("Reset Driver Monitoring"),
tr("RESET"),
tr("Clears the saved driver monitoring wheel-side calibration and any manual right-hand-driving override if the device thinks you're seated on the wrong side. "
"Resetting will restart openpilot if the car is powered on.")
);
connect(resetDmCalibBtn, &ButtonControl::clicked, [&]() {
if (!uiState()->engaged()) {
if (ConfirmationDialog::confirm(tr("Are you sure you want to reset driver monitoring calibration?"), tr("Reset"), this)) {
if (!uiState()->engaged()) {
params.remove("IsRhdDetected");
params.remove("IsRHD");
params.remove("IsRHDOverride");
params.putBool("OnroadCycleRequested", true);
}
}
} else {
ConfirmationDialog::alert(tr("Disengage to Reset Driver Monitoring"), this);
}
});
addItem(resetDmCalibBtn);
resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), "");
connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription);
connect(resetCalibBtn, &ButtonControl::clicked, [&]() {
if (!uiState()->engaged()) {
if (ConfirmationDialog::confirm(tr("Are you sure you want to reset calibration?"), tr("Reset"), this)) {
// Check engaged again in case it changed while the dialog was open
if (!uiState()->engaged()) {
params.remove("CalibrationParams");
params.remove("LiveTorqueParameters");
params.remove("LiveParameters");
params.remove("LiveParametersV2");
params.remove("LiveDelay");
params.putBool("OnroadCycleRequested", true);
updateCalibDescription();
}
}
} else {
ConfirmationDialog::alert(tr("Disengage to Reset Calibration"), this);
}
});
addItem(resetCalibBtn);
auto retrainingBtn = new ButtonControl(tr("Review Training Guide"), tr("REVIEW"), tr("Review the rules, features, and limitations of openpilot"));
connect(retrainingBtn, &ButtonControl::clicked, [=]() {
if (ConfirmationDialog::confirm(tr("Are you sure you want to review the training guide?"), tr("Review"), this)) {
emit reviewTrainingGuide();
}
});
addItem(retrainingBtn);
if (Hardware::TICI()) {
auto regulatoryBtn = new ButtonControl(tr("Regulatory"), tr("VIEW"), "");
connect(regulatoryBtn, &ButtonControl::clicked, [=]() {
const std::string txt = util::read_file("../assets/offroad/fcc.html");
ConfirmationDialog::rich(QString::fromStdString(txt), this);
});
addItem(regulatoryBtn);
}
auto translateBtn = new ButtonControl(tr("Change Language"), tr("CHANGE"), "");
connect(translateBtn, &ButtonControl::clicked, [=]() {
QMap<QString, QString> langs = getSupportedLanguages();
QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), langs.key(uiState()->language), this);
if (!selection.isEmpty()) {
// put language setting, exit Qt UI, and trigger fast restart
params.put("LanguageSetting", langs[selection].toStdString());
qApp->exit(18);
watchdog_kick(0);
}
});
addItem(translateBtn);
QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) {
pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED);
});
QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
for (auto btn : findChildren<ButtonControl *>()) {
if (btn != pair_device && btn != resetCalibBtn && btn != resetDmCalibBtn) {
btn->setEnabled(offroad);
}
}
});
// power buttons
QHBoxLayout *power_layout = new QHBoxLayout();
power_layout->setSpacing(30);
QPushButton *reboot_btn = new QPushButton(tr("Reboot"));
reboot_btn->setObjectName("reboot_btn");
power_layout->addWidget(reboot_btn);
QObject::connect(reboot_btn, &QPushButton::clicked, this, &DevicePanel::reboot);
QPushButton *poweroff_btn = new QPushButton(tr("Power Off"));
poweroff_btn->setObjectName("poweroff_btn");
power_layout->addWidget(poweroff_btn);
QObject::connect(poweroff_btn, &QPushButton::clicked, this, &DevicePanel::poweroff);
if (!Hardware::PC()) {
connect(uiState(), &UIState::offroadTransition, poweroff_btn, &QPushButton::setVisible);
}
setStyleSheet(R"(
#reboot_btn { height: 120px; border-radius: 15px; background-color: #393939; }
#reboot_btn:pressed { background-color: #4a4a4a; }
#poweroff_btn { height: 120px; border-radius: 15px; background-color: #E22C2C; }
#poweroff_btn:pressed { background-color: #FF2424; }
)");
addItem(power_layout);
}
void DevicePanel::updateCalibDescription() {
QString desc = tr("openpilot requires the device to be mounted within 4° left or right and within 5° up or 9° down.");
std::string calib_bytes = params.get("CalibrationParams");
if (!calib_bytes.empty()) {
try {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(calib_bytes.data(), calib_bytes.size()));
auto calib = cmsg.getRoot<cereal::Event>().getLiveCalibration();
if (calib.getCalStatus() != cereal::LiveCalibrationData::Status::UNCALIBRATED) {
double pitch = calib.getRpyCalib()[1] * (180 / M_PI);
double yaw = calib.getRpyCalib()[2] * (180 / M_PI);
desc += tr(" Your device is pointed %1° %2 and %3° %4.")
.arg(QString::number(std::abs(pitch), 'g', 1), pitch > 0 ? tr("down") : tr("up"),
QString::number(std::abs(yaw), 'g', 1), yaw > 0 ? tr("left") : tr("right"));
}
} catch (kj::Exception) {
qInfo() << "invalid CalibrationParams";
}
}
int lag_perc = 0;
std::string lag_bytes = params.get("LiveDelay");
if (!lag_bytes.empty()) {
try {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(lag_bytes.data(), lag_bytes.size()));
lag_perc = cmsg.getRoot<cereal::Event>().getLiveDelay().getCalPerc();
} catch (kj::Exception) {
qInfo() << "invalid LiveDelay";
}
}
if (lag_perc < 100) {
desc += tr("\n\nSteering lag calibration is %1% complete.").arg(lag_perc);
} else {
desc += tr("\n\nSteering lag calibration is complete.");
}
std::string torque_bytes = params.get("LiveTorqueParameters");
if (!torque_bytes.empty()) {
try {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(torque_bytes.data(), torque_bytes.size()));
auto torque = cmsg.getRoot<cereal::Event>().getLiveTorqueParameters();
// don't add for non-torque cars
if (torque.getUseParams()) {
int torque_perc = torque.getCalPerc();
if (torque_perc < 100) {
desc += tr(" Steering torque response calibration is %1% complete.").arg(torque_perc);
} else {
desc += tr(" Steering torque response calibration is complete.");
}
}
} catch (kj::Exception) {
qInfo() << "invalid LiveTorqueParameters";
}
}
desc += "\n\n";
desc += tr("openpilot is continuously calibrating, resetting is rarely required. "
"Resetting calibration will restart openpilot if the car is powered on.");
resetCalibBtn->setDescription(desc);
}
void DevicePanel::reboot() {
if (!uiState()->engaged()) {
if (ConfirmationDialog::confirm(tr("Are you sure you want to reboot?"), tr("Reboot"), this)) {
// Check engaged again in case it changed while the dialog was open
if (!uiState()->engaged()) {
params.putBool("DoReboot", true);
}
}
} else {
ConfirmationDialog::alert(tr("Disengage to Reboot"), this);
}
}
void DevicePanel::poweroff() {
if (!uiState()->engaged()) {
if (ConfirmationDialog::confirm(tr("Are you sure you want to power off?"), tr("Power Off"), this)) {
// Check engaged again in case it changed while the dialog was open
if (!uiState()->engaged()) {
params.putBool("DoShutdown", true);
}
}
} else {
ConfirmationDialog::alert(tr("Disengage to Power Off"), this);
}
}
void SettingsWindow::showEvent(QShowEvent *event) {
setCurrentPanel(0);
}
void SettingsWindow::hideEvent(QHideEvent *event) {
closePanel();
closeSubPanel();
panelOpen = false;
subPanelOpen = false;
subSubPanelOpen = false;
subSubSubPanelOpen = false;
updateStarPilotToggles();
}
void SettingsWindow::setCurrentPanel(int index, const QString &param) {
if (!param.isEmpty()) {
// Check if param ends with "Panel" to determine if it's a panel name
if (param.endsWith("Panel")) {
QString panelName = param;
panelName.chop(5); // Remove "Panel" suffix
// Find the panel by name
for (int i = 0; i < nav_btns->buttons().size(); i++) {
if (nav_btns->buttons()[i]->text() == tr(panelName.toStdString().c_str())) {
index = i;
break;
}
}
} else {
emit expandToggleDescription(param);
emit scrollToToggle(param);
}
}
panel_widget->setCurrentIndex(index);
nav_btns->buttons()[index]->setChecked(true);
}
SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
// setup two main layouts
sidebar_widget = new QWidget;
QVBoxLayout *sidebar_layout = new QVBoxLayout(sidebar_widget);
panel_widget = new QStackedWidget();
// close button
QPushButton *close_btn = new QPushButton(tr("← Back"));
close_btn->setStyleSheet(R"(
QPushButton {
font-size: 50px;
border-radius: 25px;
background-color: #292929;
font-weight: 500;
}
QPushButton:pressed {
background-color: #ADADAD;
}
)");
close_btn->setFixedSize(300, 125);
sidebar_layout->addSpacing(10);
sidebar_layout->addWidget(close_btn, 0, Qt::AlignRight);
QObject::connect(close_btn, &QPushButton::clicked, [this]() {
if (subSubSubPanelOpen) {
closeSubSubSubPanel();
subSubSubPanelOpen = false;
} else if (subSubPanelOpen) {
closeSubSubPanel();
subSubPanelOpen = false;
} else if (subPanelOpen) {
closeSubPanel();
subPanelOpen = false;
} else if (panelOpen) {
closePanel();
panelOpen = false;
} else {
closeSettings();
}
});
// setup panels
DevicePanel *device = new DevicePanel(this);
QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide);
QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView);
TogglesPanel *toggles = new TogglesPanel(this);
QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
QObject::connect(this, &SettingsWindow::scrollToToggle, toggles, &TogglesPanel::scrollToToggle);
auto networking = new Networking(this);
QObject::connect(uiState()->prime_state, &PrimeState::changed, networking, &Networking::setPrimeType);
QObject::connect(toggles, &TogglesPanel::updateMetric, this, &SettingsWindow::updateMetric);
StarPilotSettingsWindow *starpilotSettingsWindow = new StarPilotSettingsWindow(this);
QObject::connect(starpilotSettingsWindow, &StarPilotSettingsWindow::openPanel, [this]() {panelOpen=true;});
QObject::connect(starpilotSettingsWindow, &StarPilotSettingsWindow::openSubPanel, [this]() {subPanelOpen=true;});
QObject::connect(starpilotSettingsWindow, &StarPilotSettingsWindow::openSubSubPanel, [this]() {subSubPanelOpen=true;});
QObject::connect(starpilotSettingsWindow, &StarPilotSettingsWindow::openSubSubSubPanel, [this]() {subSubSubPanelOpen=true;});
QObject::connect(starpilotSettingsWindow, &StarPilotSettingsWindow::tuningLevelChanged, this, &SettingsWindow::updateDeveloperToggle);
DeveloperPanel *developerPanel = new DeveloperPanel(this);
QObject::connect(developerPanel, &DeveloperPanel::openSubPanel, [this]() {subPanelOpen=true;});
QObject::connect(developerPanel, &DeveloperPanel::openSubSubPanel, [this]() {subSubPanelOpen=true;});
QObject::connect(developerPanel, &DeveloperPanel::showAllTogglesChanged, [this]() {
updateDeveloperToggle(params.getInt("TuningLevel"));
});
QObject::connect(toggles, &TogglesPanel::simpleModeChanged, [this](bool enabled) {
updateDeveloperToggle(params.getInt("TuningLevel"));
if (enabled && panel_widget->currentIndex() < nav_btns->buttons().size() &&
nav_btns->buttons()[panel_widget->currentIndex()]->text() == tr("StarPilot")) {
setCurrentPanel(2);
}
});
QList<QPair<QString, QWidget *>> panels = {
{tr("Device"), device},
{tr("Network"), networking},
{tr("Toggles"), toggles},
{tr("Software"), new SoftwarePanel(this)},
{tr("Developer"), developerPanel},
{tr("StarPilot"), starpilotSettingsWindow},
};
nav_btns = new QButtonGroup(this);
for (auto &[name, panel] : panels) {
QPushButton *btn = new QPushButton(name);
btn->setCheckable(true);
btn->setChecked(nav_btns->buttons().size() == 0);
btn->setStyleSheet(R"(
QPushButton {
color: grey;
border: none;
background: none;
font-size: 65px;
font-weight: 500;
}
QPushButton:checked {
color: white;
}
QPushButton:pressed {
color: #ADADAD;
}
)");
btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
nav_btns->addButton(btn);
sidebar_layout->addWidget(btn, 0, Qt::AlignRight);
const int lr_margin = name != tr("Network") ? 50 : 0; // Network panel handles its own margins
panel->setContentsMargins(lr_margin, 25, lr_margin, 25);
ScrollView *panel_frame = new ScrollView(panel, this);
panel_widget->addWidget(panel_frame);
QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() {
if (w->widget() == starpilotSettingsWindow) {
bool tuningLevelConfirmed = params.getBool("TuningLevelConfirmed");
if (!tuningLevelConfirmed) {
int starpilotHours = QJsonDocument::fromJson(QString::fromStdString(params.get("StarPilotStats")).toUtf8()).object().value("StarPilotSeconds").toInt() / (60 * 60);
int openpilotHours = params.getInt("KonikMinutes") / 60 + params.getInt("openpilotMinutes") / 60;
if (starpilotHours < 1 && openpilotHours < 100) {
if (openpilotHours < 10) {
if (ConfirmationDialog::alert(tr("Welcome to StarPilot! Since you're new to openpilot, the \"Minimal\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 0);
}
} else {
if (ConfirmationDialog::alert(tr("Welcome to StarPilot! Since you're new to StarPilot, the \"Minimal\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 0);
}
}
} else if (starpilotHours < 50 && openpilotHours < 100) {
if (ConfirmationDialog::alert(tr("Since you're fairly new to StarPilot, the \"Minimal\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 0);
}
} else if (starpilotHours < 100) {
if (openpilotHours >= 100) {
if (ConfirmationDialog::alert(tr("Since you're experienced with openpilot, the \"Standard\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 1);
}
} else {
if (ConfirmationDialog::alert(tr("Since you're experienced with StarPilot, the \"Standard\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 1);
}
}
} else if (starpilotHours >= 100) {
if (ConfirmationDialog::alert(tr("Since you're very experienced with StarPilot, the \"Advanced\" toggle preset has been applied, but you can change this at any time via the \"Tuning Level\" button!"), this, true)) {
params.putBool("TuningLevelConfirmed", true);
params.putInt("TuningLevel", 2);
}
}
updateTuningLevel();
}
}
if (subSubSubPanelOpen) {
closeSubSubSubPanel();
subSubSubPanelOpen = false;
}
if (subSubPanelOpen) {
closeSubSubPanel();
subSubPanelOpen = false;
}
if (subPanelOpen) {
closeSubPanel();
subPanelOpen = false;
}
if (panelOpen) {
closePanel();
panelOpen = false;
}
btn->setChecked(true);
panel_widget->setCurrentWidget(w);
});
}
sidebar_layout->setContentsMargins(50, 50, 100, 50);
// main settings layout, sidebar + main panel
QHBoxLayout *main_layout = new QHBoxLayout(this);
sidebar_widget->setFixedWidth(500);
main_layout->addWidget(sidebar_widget);
main_layout->addWidget(panel_widget);
setStyleSheet(R"(
* {
color: white;
font-size: 50px;
}
SettingsWindow {
background-color: black;
}
QStackedWidget, ScrollView {
background-color: #292929;
border-radius: 30px;
}
)");
updateDeveloperToggle(params.getInt("TuningLevel"));
}
void SettingsWindow::updateDeveloperToggle(int tuningLevel) {
for (QAbstractButton *btn : nav_btns->buttons()) {
if (btn->text() == tr("Developer")) {
btn->setVisible(tuningLevel >= 3 || params.getBool("ShowAllToggles"));
} else if (btn->text() == tr("StarPilot")) {
btn->setVisible(!params.getBool("SimpleMode"));
}
}
}
-143
View File
@@ -1,143 +0,0 @@
#pragma once
#include <map>
#include <string>
#include <QButtonGroup>
#include <QFrame>
#include <QLabel>
#include <QMouseEvent>
#include <QPushButton>
#include <QStackedWidget>
#include <QWidget>
#include "selfdrive/ui/ui.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/controls.h"
// ********** settings window + top-level panels **********
class SettingsWindow : public QFrame {
Q_OBJECT
public:
explicit SettingsWindow(QWidget *parent = 0);
void setCurrentPanel(int index, const QString &param = "");
protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
signals:
void closeSettings();
void reviewTrainingGuide();
void showDriverView();
void expandToggleDescription(const QString &param);
void scrollToToggle(const QString &param);
void closePanel();
void closeSubPanel();
void closeSubSubPanel();
void closeSubSubSubPanel();
void updateMetric(bool isMetric, bool bootRun=false);
void updateTuningLevel();
private:
QPushButton *sidebar_alert_widget;
QWidget *sidebar_widget;
QButtonGroup *nav_btns;
QStackedWidget *panel_widget;
void updateDeveloperToggle(int tuningLevel);
bool panelOpen;
bool subPanelOpen;
bool subSubPanelOpen;
bool subSubSubPanelOpen;
Params params;
};
class GalaxyQRPopup : public DialogBase {
Q_OBJECT
public:
explicit GalaxyQRPopup(const QString &url, QWidget *parent = nullptr);
protected:
void mousePressEvent(QMouseEvent *event) override {
reject();
DialogBase::mousePressEvent(event);
}
};
class DevicePanel : public ListWidget {
Q_OBJECT
public:
explicit DevicePanel(SettingsWindow *parent);
signals:
void reviewTrainingGuide();
void showDriverView();
private slots:
void poweroff();
void reboot();
void updateCalibDescription();
private:
Params params;
ButtonControl *pair_device;
ButtonControl *pair_galaxy;
QPushButton *galaxy_qr_btn;
ButtonControl *resetCalibBtn;
ButtonControl *resetDmCalibBtn;
};
class TogglesPanel : public ListWidget {
Q_OBJECT
public:
explicit TogglesPanel(SettingsWindow *parent);
void showEvent(QShowEvent *event) override;
signals:
void updateMetric(bool metric, bool bootRun=false);
void simpleModeChanged(bool enabled);
public slots:
void expandToggleDescription(const QString &param);
void scrollToToggle(const QString &param);
private slots:
void updateState(const UIState &s);
private:
Params params;
std::map<std::string, ParamControl*> toggles;
ButtonParamControl *long_personality_setting;
void syncRhdToggle();
void updateToggles();
};
class SoftwarePanel : public ListWidget {
Q_OBJECT
public:
explicit SoftwarePanel(QWidget* parent = nullptr);
private:
void showEvent(QShowEvent *event) override;
void updateLabels();
void checkForUpdates();
bool is_onroad = false;
QLabel *onroadLbl;
LabelControl *versionLbl;
ButtonControl *installBtn;
ButtonControl *downloadBtn;
ButtonControl *targetBranchBtn;
Params params;
ParamWatcher *fs_watch;
};
@@ -1,202 +0,0 @@
#include "selfdrive/ui/qt/offroad/settings.h"
#include <cassert>
#include <cmath>
#include <string>
#include <QDebug>
#include <QLabel>
#include "common/params.h"
#include "common/util.h"
#include "selfdrive/ui/ui.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/controls.h"
#include "selfdrive/ui/qt/widgets/input.h"
#include "system/hardware/hw.h"
void SoftwarePanel::checkForUpdates() {
std::system("pkill -SIGUSR1 -f system.updated.updated");
}
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off or in park."));
onroadLbl->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; padding-top: 30px; padding-bottom: 30px;");
addItem(onroadLbl);
// current version
versionLbl = new LabelControl(tr("Current Version"), "");
addItem(versionLbl);
// automatic updates toggle
ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr("Automatically Update StarPilot"),
tr("Automatically update StarPilot when the vehicle is parked with an active internet connection."), "");
automaticUpdatesToggle->setVisible(true);
addItem(automaticUpdatesToggle);
// download update btn
downloadBtn = new ButtonControl(tr("Download"), tr("CHECK"));
connect(downloadBtn, &ButtonControl::clicked, [=]() {
downloadBtn->setEnabled(false);
if (downloadBtn->text() == tr("CHECK")) {
checkForUpdates();
} else {
std::system("pkill -SIGHUP -f system.updated.updated");
}
starpilotUIState()->params_memory.putBool("ManualUpdateInitiated", true);
});
addItem(downloadBtn);
// install update btn
installBtn = new ButtonControl(tr("Install Update"), tr("INSTALL"));
connect(installBtn, &ButtonControl::clicked, [=]() {
installBtn->setEnabled(false);
params.putBool("DoReboot", true);
});
addItem(installBtn);
// branch selecting
targetBranchBtn = new ButtonControl(tr("Target Branch"), tr("SELECT"));
connect(targetBranchBtn, &ButtonControl::clicked, [=]() {
auto current = params.get("GitBranch");
QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(",");
if (!isFrogsGoMoo()) {
branches.removeAll("StarPilot-Vetting");
branches.removeAll("MAKE-PRS-HERE");
}
for (QString b : {current.c_str(), "devel-staging", "devel", "nightly", "nightly-dev", "master"}) {
auto i = branches.indexOf(b);
if (i >= 0) {
branches.removeAt(i);
branches.insert(0, b);
}
}
QString cur = QString::fromStdString(params.get("UpdaterTargetBranch"));
QString selection = MultiOptionDialog::getSelection(tr("Select a branch"), branches, cur, this);
if (!selection.isEmpty()) {
params.put("UpdaterTargetBranch", selection.toStdString());
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch")));
checkForUpdates();
if (selection != cur) {
if (StarPilotConfirmationDialog::yesorno(tr("This branch must be downloaded before switching. Would you like to download it now?"), this)) {
std::system("pkill -SIGHUP -f system.updated.updated");
starpilotUIState()->params_memory.putBool("ManualUpdateInitiated", true);
}
}
}
});
addItem(targetBranchBtn);
// uninstall button
auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL"));
connect(uninstallBtn, &ButtonControl::clicked, [&]() {
if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), tr("Uninstall"), this)) {
if (StarPilotConfirmationDialog::yesorno(tr("Do you want to perform a full factory reset? All saved assets and settings will be permanently deleted!"), this)) {
if (StarPilotConfirmationDialog::yesorno(tr("This is a complete factory reset and cannot be undone. Are you absolutely sure you want to continue?"), this)) {
Params().clearAll(ParamKeyFlag::ALL);
}
}
params.putBool("DoUninstall", true);
}
});
addItem(uninstallBtn);
// error log button
auto errorLogBtn = new ButtonControl(tr("Error Log"), tr("VIEW"), tr("View the error log for openpilot crashes."));
connect(errorLogBtn, &ButtonControl::clicked, [=]() {
std::string txt = util::read_file("/data/error_logs/error.txt");
ConfirmationDialog::rich(QString::fromStdString(txt), this);
});
addItem(errorLogBtn);
fs_watch = new ParamWatcher(this);
QObject::connect(fs_watch, &ParamWatcher::paramChanged, [=](const QString &param_name, const QString &param_value) {
updateLabels();
});
connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
is_onroad = !offroad;
updateLabels();
});
updateLabels();
}
void SoftwarePanel::showEvent(QShowEvent *event) {
// nice for testing on PC
installBtn->setEnabled(true);
updateLabels();
StarPilotUIState &fs = *starpilotUIState();
StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
if (starpilot_scene.online && params.get("UpdaterState") == "idle") {
checkForUpdates();
}
}
void SoftwarePanel::updateLabels() {
StarPilotUIState &fs = *starpilotUIState();
StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
bool parked = starpilot_scene.parked || isFrogsGoMoo();
// add these back in case the files got removed
fs_watch->addParam("LastUpdateTime");
fs_watch->addParam("UpdateFailedCount");
fs_watch->addParam("UpdaterState");
fs_watch->addParam("UpdateAvailable");
if (!isVisible()) {
starpilot_scene.downloading_update = false;
return;
}
// updater only runs offroad or when parked
onroadLbl->setVisible(is_onroad && !parked);
downloadBtn->setVisible(!is_onroad || parked);
// download update
QString updater_state = QString::fromStdString(params.get("UpdaterState"));
bool failed = std::atoi(params.get("UpdateFailedCount").c_str()) > 0;
if (updater_state != "idle") {
downloadBtn->setEnabled(false);
downloadBtn->setValue(updater_state);
starpilot_scene.downloading_update = true;
} else {
if (failed) {
downloadBtn->setText(tr("CHECK"));
downloadBtn->setValue(tr("failed to check for update"));
} else if (params.getBool("UpdaterFetchAvailable")) {
downloadBtn->setText(tr("DOWNLOAD"));
downloadBtn->setValue(tr("update available"));
} else {
QString lastUpdate = tr("never");
auto tm = params.get("LastUpdateTime");
if (!tm.empty()) {
lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate));
}
downloadBtn->setText(tr("CHECK"));
downloadBtn->setValue(tr("up to date, last checked %1").arg(lastUpdate));
}
downloadBtn->setEnabled(true);
starpilot_scene.downloading_update = false;
}
targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch")));
// current + new versions
versionLbl->setText(formatStarPilotDisplayVersionDescription(QString::fromStdString(params.get("UpdaterCurrentDescription"))));
versionLbl->setDescription(QString::fromStdString(params.get("UpdaterCurrentReleaseNotes")));
installBtn->setVisible((!is_onroad || parked) && params.getBool("UpdateAvailable"));
installBtn->setValue(formatStarPilotDisplayVersionDescription(QString::fromStdString(params.get("UpdaterNewDescription"))));
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes")));
update();
}
-163
View File
@@ -1,163 +0,0 @@
#include "selfdrive/ui/qt/onroad/alerts.h"
#include <QPainter>
#include <map>
#include "selfdrive/ui/qt/util.h"
void OnroadAlerts::updateState(const UIState &s, const StarPilotUIState &fs) {
Alert a = getAlert(*(s.sm), *(fs.sm), s.scene.started_frame);
if (!alert.equal(a)) {
// Hide only incoming NORMAL alerts. Keep userPrompt/critical visible.
if (a.status == cereal::SelfdriveState::AlertStatus::NORMAL && starpilot_toggles.value("hide_alerts").toBool()) {
clear();
} else {
alert = a;
update();
}
}
sidebarsOpen = fs.starpilot_scene.sidebars_open;
}
void OnroadAlerts::clear() {
alert = {};
update();
alertHeight = 0;
}
OnroadAlerts::Alert OnroadAlerts::getAlert(const SubMaster &sm, const SubMaster &fpsm, uint64_t started_frame) {
const cereal::SelfdriveState::Reader &ss = sm["selfdriveState"].getSelfdriveState();
const uint64_t selfdrive_frame = sm.rcv_frame("selfdriveState");
const cereal::StarPilotSelfdriveState::Reader &fpss = fpsm["starpilotSelfdriveState"].getStarpilotSelfdriveState();
const bool starpilot_alert_received = fpsm.rcv_frame("starpilotSelfdriveState") > 0;
Alert a = {};
static QString crash_log_path = "/data/error_logs/error.txt";
if (QFile::exists(crash_log_path)) {
if (starpilot_toggles.value("random_events").toBool()) {
a = {tr("openpilot crashed 💩"),
tr("Please post the \"Error Log\" in the StarPilot Discord!"),
"openpilotCrashedRandomEvent",
cereal::SelfdriveState::AlertSize::MID,
cereal::SelfdriveState::AlertStatus::CRITICAL};
} else {
a = {tr("openpilot crashed"),
tr("Please post the \"Error Log\" in the StarPilot Discord!"),
"openpilotCrashed",
cereal::SelfdriveState::AlertSize::MID,
cereal::SelfdriveState::AlertStatus::CRITICAL};
}
return a;
} else if (selfdrive_frame >= started_frame) { // Don't get old alert.
a = {ss.getAlertText1().cStr(), ss.getAlertText2().cStr(),
ss.getAlertType().cStr(), ss.getAlertSize(), ss.getAlertStatus()};
if (a.size == cereal::SelfdriveState::AlertSize::NONE && starpilot_alert_received) {
a = {fpss.getAlertText1().cStr(), fpss.getAlertText2().cStr(),
fpss.getAlertType().cStr(), static_cast<cereal::SelfdriveState::AlertSize>(fpss.getAlertSize()), static_cast<cereal::SelfdriveState::AlertStatus>(fpss.getAlertStatus())};
}
}
if (!sm.updated("selfdriveState") && (sm.frame - started_frame) > 5 * UI_FREQ && !starpilot_toggles.value("force_onroad").toBool()) {
const int SELFDRIVE_STATE_TIMEOUT = 5;
const int ss_missing = (nanos_since_boot() - sm.rcv_time("selfdriveState")) / 1e9;
// Handle selfdrive timeout
if (selfdrive_frame < started_frame) {
// car is started, but selfdriveState hasn't been seen at all
a = {tr("openpilot Unavailable"), tr("Waiting to start"),
"selfdriveWaiting", cereal::SelfdriveState::AlertSize::MID,
cereal::SelfdriveState::AlertStatus::NORMAL};
} else if (ss_missing > SELFDRIVE_STATE_TIMEOUT && !Hardware::PC()) {
// car is started, but selfdrive is lagging or died
if (ss.getEnabled() && (ss_missing - SELFDRIVE_STATE_TIMEOUT) < 10) {
a = {tr("TAKE CONTROL IMMEDIATELY"), tr("System Unresponsive"),
"selfdriveUnresponsive", cereal::SelfdriveState::AlertSize::FULL,
cereal::SelfdriveState::AlertStatus::CRITICAL};
} else {
a = {tr("System Unresponsive"), tr("Reboot Device"),
"selfdriveUnresponsivePermanent", cereal::SelfdriveState::AlertSize::MID,
cereal::SelfdriveState::AlertStatus::NORMAL};
}
}
}
return a;
}
void OnroadAlerts::paintEvent(QPaintEvent *event) {
if (alert.size == cereal::SelfdriveState::AlertSize::NONE) {
alertHeight = 0;
return;
}
static std::map<cereal::SelfdriveState::AlertSize, const int> alert_heights = {
{cereal::SelfdriveState::AlertSize::SMALL, 271},
{cereal::SelfdriveState::AlertSize::MID, 420},
{cereal::SelfdriveState::AlertSize::FULL, height()},
};
alertHeight = alert_heights[alert.size];
int h = alertHeight;
int margin = 40;
int radius = 30;
if (alert.size == cereal::SelfdriveState::AlertSize::FULL) {
margin = 0;
radius = 0;
}
alertHeight -= margin;
QRect r = QRect(0 + margin, height() - h + margin, width() - margin*2, h - margin*2);
QPainter p(this);
const bool simple_mode = starpilot_toggles.value("simple_mode").toBool();
QColor alert_color;
if (simple_mode) {
cereal::SelfdriveState::AlertStatus status = alert.status;
if (status == static_cast<cereal::SelfdriveState::AlertStatus>(cereal::StarPilotSelfdriveState::AlertStatus::STARPILOT)) {
status = cereal::SelfdriveState::AlertStatus::NORMAL;
}
alert_color = alert_colors.value(status, alert_colors.value(cereal::SelfdriveState::AlertStatus::NORMAL));
} else {
alert_color = starpilot_alert_colors.value(static_cast<cereal::StarPilotSelfdriveState::AlertStatus>(alert.status),
alert_colors.value(cereal::SelfdriveState::AlertStatus::NORMAL));
}
// draw background + gradient
p.setPen(Qt::NoPen);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setBrush(QBrush(alert_color));
p.drawRoundedRect(r, radius, radius);
QLinearGradient g(0, r.y(), 0, r.bottom());
g.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.05));
g.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.35));
p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
p.setBrush(QBrush(g));
p.drawRoundedRect(r, radius, radius);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
// text
const QPoint c = r.center();
p.setPen(QColor(0xff, 0xff, 0xff));
p.setRenderHint(QPainter::TextAntialiasing);
if (alert.size == cereal::SelfdriveState::AlertSize::SMALL) {
bool long_alert1 = alert.text1.length() > 40;
p.setFont(InterFont(long_alert1 && sidebarsOpen ? 64 : 74, QFont::DemiBold));
p.drawText(r, Qt::AlignCenter, alert.text1);
} else if (alert.size == cereal::SelfdriveState::AlertSize::MID) {
bool long_alert1 = alert.text1.length() > 30;
p.setFont(InterFont(long_alert1 && sidebarsOpen ? 78 : 88, QFont::Bold));
p.drawText(QRect(0, c.y() - 125, width(), 150), Qt::AlignHCenter | Qt::AlignTop, alert.text1);
bool long_alert2 = alert.text2.length() > 40;
p.setFont(InterFont(long_alert2 && sidebarsOpen ? 56 : 66));
p.drawText(QRect(0, c.y() + 21, width(), 90), Qt::AlignHCenter, alert.text2);
} else if (alert.size == cereal::SelfdriveState::AlertSize::FULL) {
bool l = alert.text1.length() > 15;
p.setFont(InterFont(l ? 132 : 177, QFont::Bold));
p.drawText(QRect(0, r.y() + (l ? 240 : 270), width(), 600), Qt::AlignHCenter | Qt::TextWordWrap, alert.text1);
p.setFont(InterFont(88));
p.drawText(QRect(0, r.height() - (l ? 361 : 420), width(), 300), Qt::AlignHCenter | Qt::TextWordWrap, alert.text2);
}
}
-53
View File
@@ -1,53 +0,0 @@
#pragma once
#include <QWidget>
#include "selfdrive/ui/ui.h"
class OnroadAlerts : public QWidget {
Q_OBJECT
public:
OnroadAlerts(QWidget *parent = 0) : QWidget(parent) {}
void updateState(const UIState &s, const StarPilotUIState &fs);
void clear();
int alertHeight;
QJsonObject starpilot_toggles;
protected:
struct Alert {
QString text1;
QString text2;
QString type;
cereal::SelfdriveState::AlertSize size;
cereal::SelfdriveState::AlertStatus status;
bool equal(const Alert &other) const {
return text1 == other.text1 && text2 == other.text2 && type == other.type &&
size == other.size && status == other.status;
}
};
const QMap<cereal::SelfdriveState::AlertStatus, QColor> alert_colors = {
{cereal::SelfdriveState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)},
{cereal::SelfdriveState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
{cereal::SelfdriveState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)},
};
void paintEvent(QPaintEvent*) override;
OnroadAlerts::Alert getAlert(const SubMaster &sm, const SubMaster &fpsm, uint64_t started_frame);
QColor bg;
Alert alert = {};
bool sidebarsOpen;
const QMap<cereal::StarPilotSelfdriveState::AlertStatus, QColor> starpilot_alert_colors = {
{cereal::StarPilotSelfdriveState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)},
{cereal::StarPilotSelfdriveState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
{cereal::StarPilotSelfdriveState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)},
{cereal::StarPilotSelfdriveState::AlertStatus::STARPILOT, QColor(0x17, 0x86, 0x44, 0xf1)},
};
};
-281
View File
@@ -1,281 +0,0 @@
#include "selfdrive/ui/qt/onroad/annotated_camera.h"
#include <QPainter>
#include <algorithm>
#include <cmath>
#include <exception>
#include <string>
#include <vector>
#include "common/params.h"
#include "common/swaglog.h"
#include "selfdrive/ui/qt/util.h"
constexpr int CAMERA_VIEW_NONE = 4;
// Window that shows camera view and variety of info drawn on top
AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget *parent)
: fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, parent) {
pm = std::make_unique<PubMaster>(std::vector<const char*>{"uiDebug"});
main_layout = new QVBoxLayout(this);
main_layout->setMargin(UI_BORDER_SIZE);
main_layout->setSpacing(0);
experimental_btn = new ExperimentalButton(this);
main_layout->addWidget(experimental_btn, 0, Qt::AlignTop | Qt::AlignRight);
personality_btn = new DrivingPersonalityButton(this);
personality_btn->setVisible(false);
for (int i = 0; i < static_cast<int>(favorite_btns.size()); ++i) {
favorite_btns[i] = new FavoriteButton(i, this);
favorite_btns[i]->setVisible(false);
}
screen_recorder = new ScreenRecorder(this);
screen_recorder->setVisible(false);
}
bool AnnotatedCameraWidget::handleHudPress(const QPoint &pos) {
return hud.handleNavigationPress(pos);
}
bool AnnotatedCameraWidget::handleHudRelease(const QPoint &pos) {
return hud.handleNavigationRelease(pos);
}
void AnnotatedCameraWidget::updateState(const UIState &s, const StarPilotUIState &fs) {
// update engageability/experimental mode button
experimental_btn->updateState(s, fs);
dmon.updateState(s);
const SubMaster &sm = *(s.sm);
const cereal::CarState::Reader &carState = sm["carState"].getCarState();
static Params params;
const bool hide_steering_wheel = starpilot_toggles.value("hide_steering_wheel").toBool() || params.getBool("HideSteeringWheel");
experimental_btn->setVisible(!hide_steering_wheel);
const QPoint experimental_button_position = hide_steering_wheel
? QPoint(width() - UI_BORDER_SIZE - btn_size, UI_BORDER_SIZE)
: QPoint(experimental_btn->x(), experimental_btn->y());
starpilot_nvg->experimentalButtonPosition = experimental_button_position;
std::vector<FavoriteButton*> visible_favorite_btns;
const bool favorites_anchor_ready = starpilot_nvg->dmIconPosition != QPoint(0, 0) && !starpilot_nvg->hideBottomIcons;
for (FavoriteButton *favorite_btn : favorite_btns) {
favorite_btn->updateState();
if (favorites_anchor_ready && favorite_btn->shouldShow()) {
visible_favorite_btns.push_back(favorite_btn);
} else {
favorite_btn->setVisible(false);
}
}
const bool onroad_distance_btn_enabled = favorites_anchor_ready && starpilot_toggles.value("onroad_distance_button").toBool();
const int gap = UI_BORDER_SIZE / 2;
int controls_width = 0;
if (!visible_favorite_btns.empty()) {
controls_width = visible_favorite_btns.size() * btn_size + (visible_favorite_btns.size() - 1) * gap;
}
if (onroad_distance_btn_enabled) {
controls_width += (controls_width > 0 ? gap : 0) + personality_btn->width();
}
dmon.onroad_controls_width = controls_width;
const int controls_y = favorites_anchor_ready
? std::clamp(starpilot_nvg->dmIconPosition.y() - (btn_size / 2), UI_BORDER_SIZE, height() - UI_BORDER_SIZE - btn_size)
: 0;
int cursor_x = starpilot_nvg->rightHandDM ? width() - UI_BORDER_SIZE : UI_BORDER_SIZE;
personality_btn->setVisible(onroad_distance_btn_enabled);
if (onroad_distance_btn_enabled) {
const int personality_x = starpilot_nvg->rightHandDM ? cursor_x - personality_btn->width() : cursor_x;
personality_btn->move(personality_x, controls_y);
personality_btn->updateState(s, fs);
cursor_x += starpilot_nvg->rightHandDM ? -(personality_btn->width() + gap) : personality_btn->width() + gap;
}
for (FavoriteButton *favorite_btn : visible_favorite_btns) {
const int favorite_x = starpilot_nvg->rightHandDM ? cursor_x - favorite_btn->width() : cursor_x;
favorite_btn->move(favorite_x, controls_y);
favorite_btn->setVisible(true);
cursor_x += starpilot_nvg->rightHandDM ? -(favorite_btn->width() + gap) : favorite_btn->width() + gap;
}
const QPoint screen_recorder_position = hide_steering_wheel
? experimental_button_position
: QPoint(experimental_button_position.x() - UI_BORDER_SIZE - btn_size, experimental_button_position.y());
screen_recorder->move(screen_recorder_position);
screen_recorder->setVisible(starpilot_nvg->standstillDuration == 0 && !(starpilot_nvg->signalStyle == "static" && carState.getRightBlinker()) && starpilot_toggles.value("screen_recorder").toBool());
}
void AnnotatedCameraWidget::initializeGL() {
CameraWidget::initializeGL();
qInfo() << "OpenGL version:" << QString((const char*)glGetString(GL_VERSION));
qInfo() << "OpenGL vendor:" << QString((const char*)glGetString(GL_VENDOR));
qInfo() << "OpenGL renderer:" << QString((const char*)glGetString(GL_RENDERER));
qInfo() << "OpenGL language version:" << QString((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
prev_draw_t = millis_since_boot();
setBackgroundColor(bg_colors[STATUS_DISENGAGED]);
}
mat4 AnnotatedCameraWidget::calcFrameMatrix() {
// Project point at "infinity" to compute x and y offsets
// to ensure this ends up in the middle of the screen
// for narrow come and a little lower for wide cam.
// TODO: use proper perspective transform?
// Select intrinsic matrix and calibration based on camera type
auto *s = uiState();
bool wide_cam = active_stream_type == VISION_STREAM_WIDE_ROAD;
const auto &intrinsic_matrix = wide_cam ? ECAM_INTRINSIC_MATRIX : FCAM_INTRINSIC_MATRIX;
const auto &calibration = wide_cam ? s->scene.view_from_wide_calib : s->scene.view_from_calib;
// Compute the calibration transformation matrix
const auto calib_transform = intrinsic_matrix * calibration;
float zoom = wide_cam ? 2.0 : 1.1;
Eigen::Vector3f inf(1000., 0., 0.);
auto Kep = calib_transform * inf;
int w = width(), h = height();
float center_x = intrinsic_matrix(0, 2);
float center_y = intrinsic_matrix(1, 2);
float max_x_offset = center_x * zoom - w / 2 - 5;
float max_y_offset = center_y * zoom - h / 2 - 5;
float x_offset = std::clamp<float>((Kep.x() / Kep.z() - center_x) * zoom, -max_x_offset, max_x_offset);
float y_offset = std::clamp<float>((Kep.y() / Kep.z() - center_y) * zoom, -max_y_offset, max_y_offset);
// Apply transformation such that video pixel coordinates match video
// 1) Put (0, 0) in the middle of the video
// 2) Apply same scaling as video
// 3) Put (0, 0) in top left corner of video
Eigen::Matrix3f video_transform =(Eigen::Matrix3f() <<
zoom, 0.0f, (w / 2 - x_offset) - (center_x * zoom),
0.0f, zoom, (h / 2 - y_offset) - (center_y * zoom),
0.0f, 0.0f, 1.0f).finished();
model.setTransform(video_transform * calib_transform);
float zx = zoom * 2 * center_x / w;
float zy = zoom * 2 * center_y / h;
return mat4{{
zx, 0.0, 0.0, -x_offset / w * 2,
0.0, zy, 0.0, y_offset / h * 2,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
}
void AnnotatedCameraWidget::paintGL() {
}
void AnnotatedCameraWidget::paintEvent(QPaintEvent *event) {
UIState *s = uiState();
SubMaster &sm = *(s->sm);
const double start_draw_t = millis_since_boot();
QPainter painter(this);
static Params params;
const std::string camera_view_param = params.get("CameraView");
int camera_view = starpilot_toggles.value("camera_view").toInt();
if (!camera_view_param.empty()) {
try {
camera_view = std::stoi(camera_view_param);
} catch (const std::exception &) {
LOGW("invalid CameraView param: %s", camera_view_param.c_str());
}
}
const bool camera_view_none = camera_view == CAMERA_VIEW_NONE;
// draw camera frame
if (camera_view_none) {
painter.fillRect(rect(), Qt::black);
} else {
std::lock_guard lk(frame_lock);
if (frames.empty()) {
if (skip_frame_count > 0) {
skip_frame_count--;
qDebug() << "skipping frame, not ready";
return;
}
} else {
// skip drawing up to this many frames if we're
// missing camera frames. this smooths out the
// transitions from the narrow and wide cameras
skip_frame_count = 5;
}
// Wide or narrow cam dependent on speed
bool has_wide_cam = available_streams.count(VISION_STREAM_WIDE_ROAD);
if (has_wide_cam) {
float v_ego = sm["carState"].getCarState().getVEgo();
if ((v_ego < 10) || available_streams.size() == 1) {
wide_cam_requested = true;
} else if (v_ego > 15) {
wide_cam_requested = false;
}
wide_cam_requested = wide_cam_requested && sm["selfdriveState"].getSelfdriveState().getExperimentalMode() && camera_view == 0;
}
CameraWidget::setStreamType(camera_view == 1 ? VISION_STREAM_DRIVER :
((camera_view == 3 && has_wide_cam) || wide_cam_requested) ? VISION_STREAM_WIDE_ROAD :
VISION_STREAM_ROAD);
CameraWidget::setFrameId(sm["modelV2"].getModelV2().getFrameId());
painter.beginNativePainting();
CameraWidget::paintGL();
painter.endNativePainting();
}
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
dmon.starpilot_nvg = starpilot_nvg;
hud.starpilot_nvg = starpilot_nvg;
model.starpilot_nvg = starpilot_nvg;
experimental_btn->starpilot_scene = starpilot_scene;
model.starpilot_scene = starpilot_scene;
dmon.starpilot_toggles = starpilot_toggles;
experimental_btn->starpilot_toggles = starpilot_toggles;
hud.starpilot_toggles = starpilot_toggles;
model.starpilot_toggles = starpilot_toggles;
if (!camera_view_none) {
model.draw(painter, rect());
}
dmon.draw(painter, rect());
hud.updateState(*s);
hud.draw(painter, rect());
starpilot_nvg->paintStarPilotWidgets(painter, *s, camera_view_none);
double cur_draw_t = millis_since_boot();
double dt = cur_draw_t - prev_draw_t;
fps = fps_filter.update(1. / dt * 1000);
if (fps < 15) {
LOGW("slow frame rate: %.2f fps", fps);
}
prev_draw_t = cur_draw_t;
// publish debug msg
MessageBuilder msg;
auto m = msg.initEvent().initUiDebug();
m.setDrawTimeMillis(cur_draw_t - start_draw_t);
pm->send("uiDebug", msg);
}
void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
CameraWidget::showEvent(event);
ui_update_params(uiState());
prev_draw_t = millis_since_boot();
}
-57
View File
@@ -1,57 +0,0 @@
#pragma once
#include <QVBoxLayout>
#include <array>
#include <memory>
#include "selfdrive/ui/qt/onroad/hud.h"
#include "selfdrive/ui/qt/onroad/buttons.h"
#include "selfdrive/ui/qt/onroad/driver_monitoring.h"
#include "selfdrive/ui/qt/onroad/model.h"
#include "selfdrive/ui/qt/widgets/cameraview.h"
#include "starpilot/ui/qt/onroad/starpilot_buttons.h"
#include "starpilot/ui/screenrecorder/screenrecorder.h"
class AnnotatedCameraWidget : public CameraWidget {
Q_OBJECT
public:
explicit AnnotatedCameraWidget(VisionStreamType type, QWidget* parent = 0);
void updateState(const UIState &s, const StarPilotUIState &fs);
bool handleHudPress(const QPoint &pos);
bool handleHudRelease(const QPoint &pos);
double fps;
StarPilotAnnotatedCameraWidget *starpilot_nvg;
StarPilotUIScene starpilot_scene;
QJsonObject starpilot_toggles;
private:
QVBoxLayout *main_layout;
ExperimentalButton *experimental_btn;
DriverMonitorRenderer dmon;
HudRenderer hud;
ModelRenderer model;
std::unique_ptr<PubMaster> pm;
int skip_frame_count = 0;
bool wide_cam_requested = false;
void paintEvent(QPaintEvent *event) override;
DrivingPersonalityButton *personality_btn;
std::array<FavoriteButton*, 3> favorite_btns;
ScreenRecorder *screen_recorder;
protected:
void paintGL() override;
void initializeGL() override;
void showEvent(QShowEvent *event) override;
mat4 calcFrameMatrix() override;
double prev_draw_t = 0;
FirstOrderFilter fps_filter;
};
-143
View File
@@ -1,143 +0,0 @@
#include "selfdrive/ui/qt/onroad/buttons.h"
#include <QPainter>
#include "selfdrive/ui/qt/util.h"
namespace {
bool ccmManualOverride(int status) {
return status == 1 || status == 2;
}
bool cemManualOverride(int status) {
return status == 1 || status == 2;
}
} // namespace
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity, const int &angle) {
p.setRenderHint(QPainter::Antialiasing);
p.setOpacity(1.0); // bg dictates opacity of ellipse
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawEllipse(center, btn_size / 2, btn_size / 2);
p.save();
p.translate(center);
p.rotate(angle);
p.setOpacity(opacity);
p.drawPixmap(-QPoint(img.width() / 2, img.height() / 2), img);
p.restore();
p.setOpacity(1.0);
}
// ExperimentalButton
ExperimentalButton::ExperimentalButton(QWidget *parent) : QPushButton(parent), experimental_mode(false), engageable(false), steering_angle_deg(0) {
setFixedSize(btn_size, btn_size);
engage_img = loadPixmap("../assets/icons/chffr_wheel.png", {img_size, img_size});
experimental_img = loadPixmap("../assets/icons/experimental.svg", {img_size, img_size});
QObject::connect(this, &QPushButton::clicked, this, &ExperimentalButton::changeMode);
QObject::connect(starpilotUIState(), &StarPilotUIState::themeUpdated, this, &ExperimentalButton::updateTheme);
}
void ExperimentalButton::changeMode() {
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
if (params.getBool("SafeMode")) {
return;
}
bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed");
if (can_change) {
if (starpilot_toggles.value("conditional_experimental_mode").toBool()) {
int override_value = cemManualOverride(starpilot_scene.conditional_status) ? 0 : experimental_mode ? 1 : 2;
params_memory.putInt("CEStatus", override_value);
params.putInt("PersistedCEStatus", params.getBool("PersistExperimentalState") ? override_value : 0);
} else if (starpilot_toggles.value("conditional_chill_mode").toBool()) {
int override_value = ccmManualOverride(starpilot_scene.conditional_status) ? 0 : experimental_mode ? 2 : 1;
params_memory.putInt("CCStatus", override_value);
params.putInt("PersistedCCStatus", params.getBool("PersistChillState") ? override_value : 0);
} else {
params.putBool("ExperimentalMode", !experimental_mode);
}
}
}
void ExperimentalButton::updateState(const UIState &s, const StarPilotUIState &fs) {
const auto cs = (*s.sm)["selfdriveState"].getSelfdriveState();
bool eng = cs.getEngageable() || cs.getEnabled() || fs.starpilot_scene.always_on_lateral_active;
if ((cs.getExperimentalMode() != experimental_mode) || (eng != engageable)) {
engageable = eng;
experimental_mode = cs.getExperimentalMode();
update();
}
const cereal::CarState::Reader &carState = (*s.sm)["carState"].getCarState();
updateBackgroundColor();
int current_steering_angle_deg = -carState.getSteeringAngleDeg();
if (current_steering_angle_deg != steering_angle_deg && starpilot_toggles.value("rotating_wheel").toBool()) {
steering_angle_deg = current_steering_angle_deg;
update();
} else if (!starpilot_toggles.value("rotating_wheel").toBool()) {
steering_angle_deg = 0;
}
if (params_memory.getBool("UpdateWheelImage")) {
updateTheme();
params_memory.remove("UpdateWheelImage");
}
}
void ExperimentalButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setClipRegion(QRegion(QRect(0, 0, btn_size, btn_size), QRegion::Ellipse));
p.setRenderHint(QPainter::Antialiasing);
if (starpilot_toggles.value("wheel_image").toString() == "stock") {
QPixmap img = experimental_mode ? experimental_img : engage_img;
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, background_color, (isDown() || !engageable) ? 0.6 : 1.0, steering_angle_deg);
} else if (wheel_gif) {
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), wheel_gif->currentPixmap(), background_color, (isDown() || !engageable) ? 0.6 : 1.0, steering_angle_deg);
} else if (!wheel_img.isNull()) {
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), wheel_img, background_color, (isDown() || !engageable) ? 0.6 : 1.0, steering_angle_deg);
} else {
QPixmap img = experimental_mode ? experimental_img : engage_img;
drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, background_color, (isDown() || !engageable) ? 0.6 : 1.0, steering_angle_deg);
}
}
void ExperimentalButton::showEvent(QShowEvent *event) {
updateTheme();
}
void ExperimentalButton::updateBackgroundColor() {
const bool conditional_experimental_mode = starpilot_toggles.value("conditional_experimental_mode").toBool();
const bool conditional_chill_mode = starpilot_toggles.value("conditional_chill_mode").toBool();
const bool highlight_override =
(conditional_experimental_mode && starpilot_scene.conditional_status == 1) ||
(conditional_chill_mode && ccmManualOverride(starpilot_scene.conditional_status));
if (starpilot_toggles.value("simple_mode").toBool()) {
background_color = QColor(0, 0, 0, 166);
} else if (isDown() || !engageable) {
background_color = QColor(0, 0, 0, 166);
} else if (starpilot_scene.switchback_mode_enabled) {
background_color = bg_colors[STATUS_SWITCHBACK_MODE_ENABLED];
} else if (starpilot_scene.always_on_lateral_active) {
background_color = bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE];
} else if (highlight_override) {
background_color = bg_colors[STATUS_CEM_DISABLED];
} else if (experimental_mode) {
background_color = bg_colors[STATUS_EXPERIMENTAL_MODE_ENABLED];
} else if (starpilot_scene.traffic_mode_enabled) {
background_color = bg_colors[STATUS_TRAFFIC_MODE_ENABLED];
} else {
background_color = QColor(0, 0, 0, 166);
}
}
void ExperimentalButton::updateTheme() {
loadImage("../../starpilot/assets/active_theme/steering_wheel/wheel", wheel_img, wheel_gif, QSize(img_size, img_size), this);
if (!wheel_gif && wheel_img.isNull()) {
loadImage("../../starpilot/assets/stock_theme/steering_wheel/wheel", wheel_img, wheel_gif, QSize(img_size, img_size), this);
}
}
-46
View File
@@ -1,46 +0,0 @@
#pragma once
#include <QPushButton>
#include "selfdrive/ui/ui.h"
const int btn_size = 192;
const int img_size = (btn_size / 4) * 3;
class ExperimentalButton : public QPushButton {
Q_OBJECT
public:
explicit ExperimentalButton(QWidget *parent = 0);
void updateState(const UIState &s, const StarPilotUIState &fs);
StarPilotUIScene starpilot_scene;
QJsonObject starpilot_toggles;
private:
void paintEvent(QPaintEvent *event) override;
void changeMode();
Params params;
QPixmap engage_img;
QPixmap experimental_img;
bool experimental_mode;
bool engageable;
void showEvent(QShowEvent *event) override;
void updateBackgroundColor();
void updateTheme();
int steering_angle_deg;
Params params_memory{"", true};
QColor background_color;
QPixmap wheel_img;
QSharedPointer<QMovie> wheel_gif;
};
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity, const int &angle = 0);
-129
View File
@@ -1,129 +0,0 @@
#include "selfdrive/ui/qt/onroad/driver_monitoring.h"
#include <algorithm>
#include <cmath>
#include "selfdrive/ui/qt/onroad/buttons.h"
#include "selfdrive/ui/qt/util.h"
// Default 3D coordinates for face keypoints
static constexpr vec3 DEFAULT_FACE_KPTS_3D[] = {
{-5.98, -51.20, 8.00}, {-17.64, -49.14, 8.00}, {-23.81, -46.40, 8.00}, {-29.98, -40.91, 8.00}, {-32.04, -37.49, 8.00},
{-34.10, -32.00, 8.00}, {-36.16, -21.03, 8.00}, {-36.16, 6.40, 8.00}, {-35.47, 10.51, 8.00}, {-32.73, 19.43, 8.00},
{-29.30, 26.29, 8.00}, {-24.50, 33.83, 8.00}, {-19.01, 41.37, 8.00}, {-14.21, 46.17, 8.00}, {-12.16, 47.54, 8.00},
{-4.61, 49.60, 8.00}, {4.99, 49.60, 8.00}, {12.53, 47.54, 8.00}, {14.59, 46.17, 8.00}, {19.39, 41.37, 8.00},
{24.87, 33.83, 8.00}, {29.67, 26.29, 8.00}, {33.10, 19.43, 8.00}, {35.84, 10.51, 8.00}, {36.53, 6.40, 8.00},
{36.53, -21.03, 8.00}, {34.47, -32.00, 8.00}, {32.42, -37.49, 8.00}, {30.36, -40.91, 8.00}, {24.19, -46.40, 8.00},
{18.02, -49.14, 8.00}, {6.36, -51.20, 8.00}, {-5.98, -51.20, 8.00},
};
// Colors used for drawing based on monitoring state
static const QColor DMON_ENGAGED_COLOR = QColor::fromRgbF(0.1, 0.945, 0.26);
static const QColor DMON_DISENGAGED_COLOR = QColor::fromRgbF(0.545, 0.545, 0.545);
DriverMonitorRenderer::DriverMonitorRenderer() : face_kpts_draw(std::size(DEFAULT_FACE_KPTS_3D)) {
dm_img = loadPixmap("../assets/icons/driver_face.png", {img_size + 5, img_size + 5});
}
void DriverMonitorRenderer::updateState(const UIState &s) {
auto &sm = *(s.sm);
is_visible = sm["selfdriveState"].getSelfdriveState().getAlertSize() == cereal::SelfdriveState::AlertSize::NONE &&
sm.rcv_frame("driverStateV2") > s.scene.started_frame;
if (!is_visible) return;
auto dm_state = sm["driverMonitoringState"].getDriverMonitoringState();
is_active = dm_state.getActivePolicy() == cereal::DriverMonitoringState::MonitoringPolicy::VISION;
is_rhd = dm_state.getIsRHD();
dm_fade_state = std::clamp(dm_fade_state + 0.2f * (0.5f - is_active), 0.0f, 1.0f);
const auto &driverstate = sm["driverStateV2"].getDriverStateV2();
const auto driver_orient = is_rhd ? driverstate.getRightDriverData().getFaceOrientation() : driverstate.getLeftDriverData().getFaceOrientation();
for (int i = 0; i < 3; ++i) {
float v_this = (i == 0 ? (driver_orient[i] < 0 ? 0.7 : 0.9) : 0.4) * driver_orient[i];
driver_pose_diff[i] = std::abs(driver_pose_vals[i] - v_this);
driver_pose_vals[i] = 0.8f * v_this + (1 - 0.8) * driver_pose_vals[i];
driver_pose_sins[i] = std::sin(driver_pose_vals[i] * (1.0f - dm_fade_state));
driver_pose_coss[i] = std::cos(driver_pose_vals[i] * (1.0f - dm_fade_state));
}
auto [sin_y, sin_x, sin_z] = driver_pose_sins;
auto [cos_y, cos_x, cos_z] = driver_pose_coss;
// Rotation matrix for transforming face keypoints based on driver's head orientation
const mat3 r_xyz = {{
cos_x * cos_z, cos_x * sin_z, -sin_x,
-sin_y * sin_x * cos_z - cos_y * sin_z, -sin_y * sin_x * sin_z + cos_y * cos_z, -sin_y * cos_x,
cos_y * sin_x * cos_z - sin_y * sin_z, cos_y * sin_x * sin_z + sin_y * cos_z, cos_y * cos_x,
}};
// Transform vertices
for (int i = 0; i < face_kpts_draw.size(); ++i) {
vec3 kpt = matvecmul3(r_xyz, DEFAULT_FACE_KPTS_3D[i]);
face_kpts_draw[i] = {{kpt.v[0], kpt.v[1], kpt.v[2] * (1.0f - dm_fade_state) + 8 * dm_fade_state}};
}
}
void DriverMonitorRenderer::draw(QPainter &painter, const QRect &surface_rect) {
if (!is_visible) return;
int offset = UI_BORDER_SIZE + btn_size / 2;
float x = is_rhd ? surface_rect.width() - offset : offset;
float y = surface_rect.height() - offset;
if (onroad_controls_width > 0) {
const int controls_offset = onroad_controls_width + (2 * UI_BORDER_SIZE);
if (is_rhd) {
x -= controls_offset;
} else {
x += controls_offset;
}
}
if (starpilot_toggles.value("road_name_ui").toBool()) {
y -= UI_BORDER_SIZE;
}
if (starpilot_nvg) {
starpilot_nvg->dmIconPosition.setX(x);
starpilot_nvg->dmIconPosition.setY(y);
starpilot_nvg->rightHandDM = is_rhd;
}
if (starpilot_toggles.value("hide_dm_icon").toBool()) return;
painter.save();
float opacity = is_active ? 0.65f : 0.2f;
drawIcon(painter, QPoint(x, y), dm_img, QColor(0, 0, 0, 70), opacity);
QPointF keypoints[std::size(DEFAULT_FACE_KPTS_3D)];
for (int i = 0; i < std::size(keypoints); ++i) {
const auto &v = face_kpts_draw[i].v;
float kp = (v[2] - 8) / 120.0f + 1.0f;
keypoints[i] = QPointF(v[0] * kp + x, v[1] * kp + y);
}
painter.setPen(QPen(QColor::fromRgbF(1.0, 1.0, 1.0, opacity), 5.2, Qt::SolidLine, Qt::RoundCap));
painter.drawPolyline(keypoints, std::size(keypoints));
// tracking arcs
const int arc_l = 133;
const float arc_t_default = 6.7f;
const float arc_t_extend = 12.0f;
QColor arc_color = uiState()->engaged() ? DMON_ENGAGED_COLOR : DMON_DISENGAGED_COLOR;
arc_color.setAlphaF(0.4 * (1.0f - dm_fade_state));
float delta_x = -driver_pose_sins[1] * arc_l / 2.0f;
float delta_y = -driver_pose_sins[0] * arc_l / 2.0f;
// Draw horizontal tracking arc
painter.setPen(QPen(arc_color, arc_t_default + arc_t_extend * std::min(1.0, driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
painter.drawArc(QRectF(std::min(x + delta_x, x), y - arc_l / 2, std::abs(delta_x), arc_l), (driver_pose_sins[1] > 0 ? 90 : -90) * 16, 180 * 16);
// Draw vertical tracking arc
painter.setPen(QPen(arc_color, arc_t_default + arc_t_extend * std::min(1.0, driver_pose_diff[0] * 5.0), Qt::SolidLine, Qt::RoundCap));
painter.drawArc(QRectF(x - arc_l / 2, std::min(y + delta_y, y), arc_l, std::abs(delta_y)), (driver_pose_sins[0] > 0 ? 0 : 180) * 16, 180 * 16);
painter.restore();
}
@@ -1,32 +0,0 @@
#pragma once
#include <vector>
#include <QPainter>
#include "selfdrive/ui/ui.h"
#include "starpilot/ui/qt/onroad/starpilot_annotated_camera.h"
class DriverMonitorRenderer {
public:
DriverMonitorRenderer();
void updateState(const UIState &s);
void draw(QPainter &painter, const QRect &surface_rect);
StarPilotAnnotatedCameraWidget *starpilot_nvg;
int onroad_controls_width = 0;
QJsonObject starpilot_toggles;
private:
float driver_pose_vals[3] = {};
float driver_pose_diff[3] = {};
float driver_pose_sins[3] = {};
float driver_pose_coss[3] = {};
bool is_visible = false;
bool is_active = false;
bool is_rhd = false;
float dm_fade_state = 1.0;
QPixmap dm_img;
std::vector<vec3> face_kpts_draw;
};
-427
View File
@@ -1,427 +0,0 @@
#include "selfdrive/ui/qt/onroad/hud.h"
#include <algorithm>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
#include <cmath>
#include "selfdrive/ui/qt/util.h"
constexpr int SET_SPEED_NA = 255;
constexpr int NAV_CANCEL_HOLD_MS = 650;
HudRenderer::HudRenderer() {}
bool HudRenderer::handleNavigationPress(const QPoint &pos) {
if (!navigation_valid || !nav_hit_rect.contains(pos)) {
return false;
}
nav_press_active = true;
nav_press_timer.restart();
return true;
}
bool HudRenderer::handleNavigationRelease(const QPoint &pos) {
if (!nav_press_active) {
return false;
}
nav_press_active = false;
if (!nav_hit_rect.contains(pos)) {
return true;
}
if (nav_press_timer.isValid() && nav_press_timer.elapsed() >= NAV_CANCEL_HOLD_MS) {
cancelNavigation();
} else {
params_memory.putBool("NavInstructionCollapsed", !navigation_collapsed);
}
return true;
}
void HudRenderer::cancelNavigation() {
params.remove("NavDestination");
params_memory.remove("NavInstructionState");
params_memory.remove("NavInstructionCollapsed");
navigation_valid = false;
navigation_collapsed = false;
nav_hit_rect = QRect();
nav_primary_text.clear();
nav_secondary_text.clear();
nav_distance.clear();
nav_maneuver_type.clear();
nav_modifier.clear();
nav_next_maneuver_type.clear();
nav_next_modifier.clear();
}
void HudRenderer::updateState(const UIState &s) {
is_metric = s.scene.is_metric;
status = s.status;
const SubMaster &sm = *(s.sm);
if (sm.rcv_frame("carState") < s.scene.started_frame) {
is_cruise_set = false;
set_speed = SET_SPEED_NA;
speed = 0.0;
return;
}
const auto &controls_state = sm["controlsState"].getControlsState();
const auto &car_state = sm["carState"].getCarState();
// Handle older routes where vCruiseCluster is not set
set_speed = car_state.getVCruiseCluster() == 0.0 ? controls_state.getVCruiseDEPRECATED() : car_state.getVCruiseCluster();
is_cruise_set = set_speed > 0 && set_speed != SET_SPEED_NA;
is_cruise_available = set_speed != -1;
if (is_cruise_set && starpilot_toggles.value("set_speed_offset").toDouble() > 0) {
set_speed += starpilot_toggles.value("set_speed_offset").toDouble();
}
if (is_cruise_set && !is_metric) {
set_speed *= KM_TO_MILE;
}
// Handle older routes where vEgoCluster is not set
v_ego_cluster_seen = v_ego_cluster_seen || car_state.getVEgoCluster() != 0.0;
float v_ego = v_ego_cluster_seen && !starpilot_toggles.value("use_wheel_speed").toBool() ? car_state.getVEgoCluster() : car_state.getVEgo();
speed = std::max<float>(0.0f, v_ego * (is_metric ? MS_TO_KPH : MS_TO_MPH));
navigation_enabled = params.getBool("NavigationUI");
navigation_valid = false;
navigation_has_next = false;
navigation_collapsed = false;
nav_hit_rect = QRect();
nav_primary_text.clear();
nav_secondary_text.clear();
nav_distance.clear();
nav_maneuver_type.clear();
nav_modifier.clear();
nav_next_maneuver_type.clear();
nav_next_modifier.clear();
if (!navigation_enabled) {
return;
}
if (params.get("NavDestination").empty()) {
return;
}
const std::string nav_state_raw = params_memory.get("NavInstructionState");
if (nav_state_raw.empty()) {
return;
}
const QJsonDocument nav_state_doc = QJsonDocument::fromJson(QByteArray::fromStdString(nav_state_raw));
if (!nav_state_doc.isObject()) {
return;
}
const QJsonObject nav = nav_state_doc.object();
if (!nav.value("valid").toBool(false)) {
return;
}
nav_primary_text = nav.value("maneuverPrimaryText").toString().trimmed();
if (nav_primary_text.isEmpty()) {
return;
}
navigation_valid = true;
nav_secondary_text = nav.value("maneuverSecondaryText").toString().trimmed();
nav_distance = formatNavDistance(static_cast<float>(nav.value("maneuverDistance").toDouble(0.0)));
nav_maneuver_type = nav.value("maneuverType").toString().trimmed();
nav_modifier = nav.value("maneuverModifier").toString().trimmed();
nav_next_maneuver_type = nav.value("nextManeuverType").toString().trimmed();
nav_next_modifier = nav.value("nextManeuverModifier").toString().trimmed();
navigation_has_next = !nav_next_maneuver_type.isEmpty() || !nav_next_modifier.isEmpty();
navigation_collapsed = params_memory.getBool("NavInstructionCollapsed");
}
void HudRenderer::draw(QPainter &p, const QRect &surface_rect) {
p.save();
// Draw header gradient — constant stops, build once
static const QLinearGradient bg = []() {
QLinearGradient g(0, UI_HEADER_HEIGHT - (UI_HEADER_HEIGHT / 2.5), 0, UI_HEADER_HEIGHT);
g.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.45));
g.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0));
return g;
}();
p.fillRect(0, 0, surface_rect.width(), UI_HEADER_HEIGHT, bg);
if (is_cruise_available) {
drawSetSpeed(p, surface_rect);
}
if (starpilot_nvg->standstillDuration == 0 && !starpilot_toggles.value("hide_speed").toBool()) {
drawCurrentSpeed(p, surface_rect);
}
if (navigation_valid) {
drawNavigationCard(p, surface_rect);
}
p.restore();
}
void HudRenderer::drawSetSpeed(QPainter &p, const QRect &surface_rect) {
// Draw outer box + border to contain set speed
const QSize default_size = {172, 204};
QSize set_speed_size = is_metric ? QSize(200, 204) : default_size;
if (starpilot_nvg->speedLimitHeight != 0) {
set_speed_size.rheight() += starpilot_nvg->speedLimitHeight;
if (starpilot_toggles.value("speed_limit_vienna").toBool()) {
set_speed_size.rwidth() = 200;
}
}
QRect set_speed_rect(QPoint(60 + (default_size.width() - set_speed_size.width()) / 2, 45), set_speed_size);
if (!starpilot_toggles.value("hide_max_speed").toBool()) {
// Draw set speed box
p.setPen(QPen(QColor(255, 255, 255, 75), 6));
p.setBrush(QColor(0, 0, 0, 166));
p.drawRoundedRect(set_speed_rect, 32, 32);
// Colors based on status
QColor max_color = QColor(0xa6, 0xa6, 0xa6, 0xff);
QColor set_speed_color = QColor(0x72, 0x72, 0x72, 0xff);
if (is_cruise_set) {
set_speed_color = QColor(255, 255, 255);
if (status == STATUS_DISENGAGED) {
max_color = QColor(255, 255, 255);
} else if (status == STATUS_OVERRIDE) {
max_color = QColor(0x91, 0x9b, 0x95, 0xff);
} else {
max_color = QColor(0x80, 0xd8, 0xa6, 0xff);
}
}
// Draw "MAX" text
p.setFont(InterFont(40, QFont::DemiBold));
p.setPen(max_color);
p.drawText(set_speed_rect.adjusted(0, 27, 0, 0), Qt::AlignTop | Qt::AlignHCenter, tr("MAX"));
// Draw set speed
QString setSpeedStr = is_cruise_set ? QString::number(std::nearbyint(set_speed)) : "";
p.setFont(InterFont(90, QFont::Bold));
p.setPen(set_speed_color);
p.drawText(set_speed_rect.adjusted(0, 77, 0, 0), Qt::AlignTop | Qt::AlignHCenter, setSpeedStr);
}
starpilot_nvg->defaultSize = default_size;
starpilot_nvg->isCruiseSet = is_cruise_set;
starpilot_nvg->setSpeedRect = set_speed_rect;
starpilot_nvg->speed = speed;
}
void HudRenderer::drawCurrentSpeed(QPainter &p, const QRect &surface_rect) {
QString speedStr = QString::number(std::nearbyint(speed));
p.setFont(InterFont(176, QFont::Bold));
drawText(p, surface_rect.center().x(), 210, speedStr);
p.setFont(InterFont(66));
drawText(p, surface_rect.center().x(), 290, is_metric ? tr("km/h") : tr("mph"), 200);
}
void HudRenderer::drawText(QPainter &p, int x, int y, const QString &text, int alpha) {
QRect real_rect = p.fontMetrics().boundingRect(text);
real_rect.moveCenter({x, y - real_rect.height() / 2});
p.setPen(QColor(0xff, 0xff, 0xff, alpha));
p.drawText(real_rect.x(), real_rect.bottom(), text);
}
QString HudRenderer::formatNavDistance(float distance_m) const {
if (is_metric) {
if (distance_m < 1000.0f) {
int step = distance_m < 500.0f ? 25 : 50;
return QString("%1 m").arg(qRound(distance_m / step) * step);
}
float km = distance_m / 1000.0f;
return km >= 10.0f ? QString("%1 km").arg(static_cast<int>(std::floor(km))) : QString("%1 km").arg(km, 0, 'f', 1);
}
float distance_ft = distance_m * METER_TO_FOOT;
if (distance_ft < 1000.0f) {
int step = distance_ft <= 100.0f ? 10 : 50;
return QString("%1 ft").arg(qRound(distance_ft / step) * step);
}
float miles = distance_ft / 5280.0f;
return miles >= 10.0f ? QString("%1 mi").arg(static_cast<int>(std::floor(miles))) : QString("%1 mi").arg(miles, 0, 'f', 1);
}
QString HudRenderer::navigationIconFilename(const QString &maneuver_type, const QString &modifier) const {
QString normalized_type = maneuver_type.isEmpty() ? "turn" : maneuver_type;
if (normalized_type == "rotary") {
normalized_type = "roundabout";
} else if (normalized_type == "new name" || normalized_type == "continue") {
normalized_type = "turn";
}
if (modifier == "uturn") {
return "direction_uturn.png";
}
static const QHash<QString, QString> suffixes = {
{"left", "left"},
{"right", "right"},
{"straight", "straight"},
{"slightLeft", "slight_left"},
{"slightRight", "slight_right"},
{"sharpLeft", "sharp_left"},
{"sharpRight", "sharp_right"},
};
normalized_type.replace(" ", "_");
const QString suffix = suffixes.value(modifier, "");
const QString candidate = suffix.isEmpty() ? QString("direction_%1.png").arg(normalized_type)
: QString("direction_%1_%2.png").arg(normalized_type, suffix);
const QString candidate_path = QString("../../starpilot/assets/navigation/%1").arg(candidate);
return QFileInfo::exists(candidate_path) ? candidate : "direction_turn_straight.png";
}
QPixmap HudRenderer::getNavigationIcon(const QString &maneuver_type, const QString &modifier, int size) {
const QString icon_name = navigationIconFilename(maneuver_type, modifier);
const QString cache_key = QString("%1|%2").arg(icon_name).arg(size);
if (!nav_icon_cache.contains(cache_key)) {
nav_icon_cache.insert(cache_key, loadPixmap(QString("../../starpilot/assets/navigation/%1").arg(icon_name), QSize(size, size)));
}
return nav_icon_cache.value(cache_key);
}
QStringList HudRenderer::wrapNavigationText(int max_width, int font_size, const QString &text) const {
QStringList words = text.split(' ', QString::SkipEmptyParts);
QStringList lines;
QString current_line;
const QFontMetrics metrics(InterFont(font_size, QFont::Bold));
for (const QString &word : words) {
QString test_line = current_line.isEmpty() ? word : current_line + " " + word;
if (metrics.horizontalAdvance(test_line) <= max_width) {
current_line = test_line;
} else {
if (!current_line.isEmpty()) {
lines.append(current_line);
}
current_line = word;
if (lines.size() >= 2) {
break;
}
}
}
if (!current_line.isEmpty() && lines.size() < 2) {
lines.append(current_line);
}
return lines;
}
void HudRenderer::drawNavigationCard(QPainter &p, const QRect &surface_rect) {
if (navigation_collapsed) {
const int chip_size = 94;
const int chip_x = surface_rect.right() - chip_size - 32;
const int chip_y = surface_rect.width() >= 1200 ? 232 : 204;
nav_hit_rect = QRect(chip_x, chip_y, chip_size, chip_size);
p.setPen(Qt::NoPen);
p.setBrush(QColor(7, 11, 18, 228));
p.drawRoundedRect(nav_hit_rect, 28, 28);
p.setPen(QPen(QColor(255, 255, 255, 40), 2));
p.setBrush(Qt::NoBrush);
p.drawRoundedRect(nav_hit_rect, 28, 28);
const int icon_size = 58;
const QPixmap icon = getNavigationIcon(nav_maneuver_type, nav_modifier, icon_size);
const int icon_x = chip_x + (chip_size - icon_size) / 2;
const int icon_y = chip_y + (chip_size - icon_size) / 2;
p.drawPixmap(icon_x, icon_y, icon);
return;
}
const int container_width = std::clamp(surface_rect.width() - 120, 760, 1080);
const int container_height = surface_rect.width() >= 1200 ? 238 : 206;
const int container_x = (surface_rect.width() - container_width) / 2;
const int container_y = surface_rect.width() >= 1200 ? 332 : 298;
const int border_radius = container_height == 238 ? 42 : 34;
const int icon_size = container_height == 238 ? 150 : 122;
const int icon_padding = container_height == 238 ? 30 : 24;
const int then_section_width = container_height == 238 ? 180 : 144;
const int then_icon_size = container_height == 238 ? 105 : 82;
const int title_font_size = container_height == 238 ? 75 : 58;
const int secondary_font_size = container_height == 238 ? 34 : 28;
const int distance_font_size = container_height == 238 ? 48 : 40;
const int title_top_padding = container_height == 238 ? 10 : 10;
const int title_line_spacing = container_height == 238 ? 68 : 56;
const int secondary_bottom_padding = container_height == 238 ? 24 : 20;
const int secondary_gap = container_height == 238 ? 10 : 8;
QRect container(container_x, container_y, container_width, container_height);
nav_hit_rect = container;
p.setPen(Qt::NoPen);
p.setBrush(QColor(0, 0, 0, 180));
p.drawRoundedRect(container, border_radius, border_radius);
const int icon_x = container_x + icon_padding;
const int icon_y = container_y + title_top_padding + 4;
const QPixmap icon = getNavigationIcon(nav_maneuver_type, nav_modifier, icon_size);
p.drawPixmap(icon_x, icon_y, icon);
p.setFont(InterFont(distance_font_size, QFont::Bold));
p.setPen(Qt::white);
const int distance_width = p.fontMetrics().horizontalAdvance(nav_distance);
p.drawText(icon_x + (icon_size - distance_width) / 2, container_y + container_height - 18, nav_distance);
const int text_x = icon_x + icon_size + 53;
const int right_gutter = icon_padding + (navigation_has_next ? then_section_width : 0);
const int text_width = container_width - (text_x - container_x) - right_gutter;
const QStringList title_lines = wrapNavigationText(text_width, title_font_size, nav_primary_text);
const QFont title_font = InterFont(title_font_size, QFont::Bold);
const QFontMetrics title_metrics(title_font);
const int title_baseline = container_y + title_top_padding + title_metrics.ascent();
p.setFont(title_font);
p.setPen(Qt::white);
for (int index = 0; index < title_lines.size() && index < 2; ++index) {
p.drawText(text_x, title_baseline + index * title_line_spacing, title_lines[index]);
}
if (!nav_secondary_text.isEmpty()) {
const QFont secondary_font = InterFont(secondary_font_size, QFont::Medium);
const QFontMetrics secondary_metrics(secondary_font);
const int title_bottom = title_baseline + (std::max(title_lines.size(), 1) - 1) * title_line_spacing + title_metrics.descent();
const int secondary_max_baseline = container_y + container_height - secondary_bottom_padding - secondary_metrics.descent();
const int secondary_preferred_baseline = title_bottom + secondary_gap + secondary_metrics.ascent();
const int secondary_baseline = std::min(secondary_preferred_baseline, secondary_max_baseline);
p.setFont(secondary_font);
p.setPen(QColor(255, 255, 255, 180));
p.drawText(text_x, secondary_baseline, nav_secondary_text);
}
if (!navigation_has_next) {
return;
}
const int divider_x = container_x + container_width - then_section_width - 8;
p.setPen(QPen(QColor(255, 255, 255, 50), 2));
p.drawLine(divider_x, container_y + 23, divider_x, container_y + container_height - 23);
p.setFont(InterFont(container_height == 225 ? 53 : 40, QFont::Medium));
p.setPen(Qt::white);
const QString then_label = tr("Then");
const int then_x = divider_x + 15;
const int then_label_width = p.fontMetrics().horizontalAdvance(then_label);
p.drawText(then_x + (then_section_width - 23 - then_label_width) / 2, container_y + (container_height == 238 ? 66 : 60), then_label);
const QPixmap next_icon = getNavigationIcon(nav_next_maneuver_type, nav_next_modifier, then_icon_size);
const int then_icon_x = then_x + (then_section_width - 23 - then_icon_size) / 2;
const int then_icon_y = container_y + (container_height == 238 ? 96 : 78);
p.drawPixmap(then_icon_x, then_icon_y, next_icon);
}
-61
View File
@@ -1,61 +0,0 @@
#pragma once
#include <QHash>
#include <QElapsedTimer>
#include <QJsonObject>
#include <QPainter>
#include <QPixmap>
#include "selfdrive/ui/ui.h"
#include "starpilot/ui/qt/onroad/starpilot_annotated_camera.h"
class HudRenderer : public QObject {
Q_OBJECT
public:
HudRenderer();
void updateState(const UIState &s);
void draw(QPainter &p, const QRect &surface_rect);
bool handleNavigationPress(const QPoint &pos);
bool handleNavigationRelease(const QPoint &pos);
StarPilotAnnotatedCameraWidget *starpilot_nvg;
QJsonObject starpilot_toggles;
private:
void drawSetSpeed(QPainter &p, const QRect &surface_rect);
void drawCurrentSpeed(QPainter &p, const QRect &surface_rect);
void drawNavigationCard(QPainter &p, const QRect &surface_rect);
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
QStringList wrapNavigationText(int max_width, int font_size, const QString &text) const;
QString formatNavDistance(float distance_m) const;
QString navigationIconFilename(const QString &maneuver_type, const QString &modifier) const;
QPixmap getNavigationIcon(const QString &maneuver_type, const QString &modifier, int size);
void cancelNavigation();
float speed = 0;
float set_speed = 0;
bool is_cruise_set = false;
bool is_cruise_available = true;
bool is_metric = false;
bool v_ego_cluster_seen = false;
bool navigation_enabled = false;
bool navigation_valid = false;
bool navigation_has_next = false;
bool navigation_collapsed = false;
int status = STATUS_DISENGAGED;
QString nav_distance;
QString nav_primary_text;
QString nav_secondary_text;
QString nav_maneuver_type;
QString nav_modifier;
QString nav_next_maneuver_type;
QString nav_next_modifier;
QRect nav_hit_rect;
QHash<QString, QPixmap> nav_icon_cache;
QElapsedTimer nav_press_timer;
bool nav_press_active = false;
Params params;
Params params_memory{"", true};
};
-94
View File
@@ -1,94 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'alerts.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "alerts.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'alerts.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_OnroadAlerts_t {
QByteArrayData data[1];
char stringdata0[13];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_OnroadAlerts_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_OnroadAlerts_t qt_meta_stringdata_OnroadAlerts = {
{
QT_MOC_LITERAL(0, 0, 12) // "OnroadAlerts"
},
"OnroadAlerts"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_OnroadAlerts[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void OnroadAlerts::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject OnroadAlerts::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_OnroadAlerts.data,
qt_meta_data_OnroadAlerts,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *OnroadAlerts::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *OnroadAlerts::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_OnroadAlerts.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int OnroadAlerts::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
@@ -1,94 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'annotated_camera.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "annotated_camera.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'annotated_camera.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_AnnotatedCameraWidget_t {
QByteArrayData data[1];
char stringdata0[22];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_AnnotatedCameraWidget_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_AnnotatedCameraWidget_t qt_meta_stringdata_AnnotatedCameraWidget = {
{
QT_MOC_LITERAL(0, 0, 21) // "AnnotatedCameraWidget"
},
"AnnotatedCameraWidget"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_AnnotatedCameraWidget[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void AnnotatedCameraWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject AnnotatedCameraWidget::staticMetaObject = { {
&CameraWidget::staticMetaObject,
qt_meta_stringdata_AnnotatedCameraWidget.data,
qt_meta_data_AnnotatedCameraWidget,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *AnnotatedCameraWidget::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *AnnotatedCameraWidget::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_AnnotatedCameraWidget.stringdata0))
return static_cast<void*>(this);
return CameraWidget::qt_metacast(_clname);
}
int AnnotatedCameraWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = CameraWidget::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-94
View File
@@ -1,94 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'buttons.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "buttons.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'buttons.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_ExperimentalButton_t {
QByteArrayData data[1];
char stringdata0[19];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_ExperimentalButton_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_ExperimentalButton_t qt_meta_stringdata_ExperimentalButton = {
{
QT_MOC_LITERAL(0, 0, 18) // "ExperimentalButton"
},
"ExperimentalButton"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_ExperimentalButton[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void ExperimentalButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject ExperimentalButton::staticMetaObject = { {
&QPushButton::staticMetaObject,
qt_meta_stringdata_ExperimentalButton.data,
qt_meta_data_ExperimentalButton,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *ExperimentalButton::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *ExperimentalButton::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_ExperimentalButton.stringdata0))
return static_cast<void*>(this);
return QPushButton::qt_metacast(_clname);
}
int ExperimentalButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QPushButton::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-94
View File
@@ -1,94 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'hud.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "hud.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'hud.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_HudRenderer_t {
QByteArrayData data[1];
char stringdata0[12];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_HudRenderer_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_HudRenderer_t qt_meta_stringdata_HudRenderer = {
{
QT_MOC_LITERAL(0, 0, 11) // "HudRenderer"
},
"HudRenderer"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_HudRenderer[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
void HudRenderer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
QT_INIT_METAOBJECT const QMetaObject HudRenderer::staticMetaObject = { {
&QObject::staticMetaObject,
qt_meta_stringdata_HudRenderer.data,
qt_meta_data_HudRenderer,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *HudRenderer::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *HudRenderer::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_HudRenderer.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int HudRenderer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-128
View File
@@ -1,128 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'onroad_home.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.12.8)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include "onroad_home.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'onroad_home.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.12.8. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_OnroadWindow_t {
QByteArrayData data[9];
char stringdata0[82];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_OnroadWindow_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_OnroadWindow_t qt_meta_stringdata_OnroadWindow = {
{
QT_MOC_LITERAL(0, 0, 12), // "OnroadWindow"
QT_MOC_LITERAL(1, 13, 17), // "offroadTransition"
QT_MOC_LITERAL(2, 31, 0), // ""
QT_MOC_LITERAL(3, 32, 7), // "offroad"
QT_MOC_LITERAL(4, 40, 11), // "updateState"
QT_MOC_LITERAL(5, 52, 7), // "UIState"
QT_MOC_LITERAL(6, 60, 1), // "s"
QT_MOC_LITERAL(7, 62, 16), // "StarPilotUIState"
QT_MOC_LITERAL(8, 79, 2) // "fs"
},
"OnroadWindow\0offroadTransition\0\0offroad\0"
"updateState\0UIState\0s\0StarPilotUIState\0"
"fs"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_OnroadWindow[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 1, 24, 2, 0x08 /* Private */,
4, 2, 27, 2, 0x08 /* Private */,
// slots: parameters
QMetaType::Void, QMetaType::Bool, 3,
QMetaType::Void, 0x80000000 | 5, 0x80000000 | 7, 6, 8,
0 // eod
};
void OnroadWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<OnroadWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->offroadTransition((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 1: _t->updateState((*reinterpret_cast< const UIState(*)>(_a[1])),(*reinterpret_cast< const StarPilotUIState(*)>(_a[2]))); break;
default: ;
}
}
}
QT_INIT_METAOBJECT const QMetaObject OnroadWindow::staticMetaObject = { {
&QWidget::staticMetaObject,
qt_meta_stringdata_OnroadWindow.data,
qt_meta_data_OnroadWindow,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *OnroadWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *OnroadWindow::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_OnroadWindow.stringdata0))
return static_cast<void*>(this);
return QWidget::qt_metacast(_clname);
}
int OnroadWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
-401
View File
@@ -1,401 +0,0 @@
#include "selfdrive/ui/qt/onroad/model.h"
constexpr int CLIP_MARGIN = 500;
static int get_path_length_idx(const cereal::XYZTData::Reader &line, const float path_height) {
const auto &line_x = line.getX();
int max_idx = 0;
for (int i = 1; i < line_x.size() && line_x[i] <= path_height; ++i) {
max_idx = i;
}
return max_idx;
}
void ModelRenderer::draw(QPainter &painter, const QRect &surface_rect) {
auto *s = uiState();
auto &sm = *(s->sm);
// Check if data is up-to-date
if (sm.rcv_frame("liveCalibration") < s->scene.started_frame ||
sm.rcv_frame("modelV2") < s->scene.started_frame) {
return;
}
clip_region = surface_rect.adjusted(-CLIP_MARGIN, -CLIP_MARGIN, CLIP_MARGIN, CLIP_MARGIN);
experimental_mode = sm["selfdriveState"].getSelfdriveState().getExperimentalMode();
longitudinal_control = sm["carParams"].getCarParams().getOpenpilotLongitudinalControl();
path_offset_z = sm["liveCalibration"].getLiveCalibration().getHeight()[0];
painter.save();
const auto &model = sm["modelV2"].getModelV2();
const auto &radar_state = sm["radarState"].getRadarState();
const auto &lead_one = radar_state.getLeadOne();
update_model(model, lead_one, surface_rect.height());
drawLaneLines(painter);
drawPath(painter, model, surface_rect.height());
if ((longitudinal_control || starpilot_toggles.value("lead_info").toBool()) && sm.alive("radarState") && !starpilot_toggles.value("hide_lead_marker").toBool()) {
update_leads(radar_state, model.getPosition());
const auto &lead_two = radar_state.getLeadTwo();
if (lead_one.getStatus()) {
if (lead_one.getModelProb() >= starpilot_toggles.value("lead_detection_probability").toDouble()) {
drawLead(painter, lead_one, lead_vertices[0], surface_rect, QColor(starpilot_toggles.value("lead_marker_color").toString()));
} else {
drawLead(painter, lead_one, lead_vertices[0], surface_rect, starpilot_nvg->whiteColor());
}
} else {
starpilot_nvg->leadTextRect = QRect();
}
if (lead_two.getStatus() && (std::abs(lead_one.getDRel() - lead_two.getDRel()) > 3.0)) {
drawLead(painter, lead_two, lead_vertices[1], surface_rect, QColor(starpilot_toggles.value("lead_marker_color").toString()));
}
// Adjacent leads may be published by radard for non-UI consumers (e.g. HumanLaneChanges),
// so gate drawing on the AdjacentLeadsUI toggle directly.
if (starpilot_toggles.value("adjacent_lead_tracking").toBool()) {
SubMaster &fpsm = *(starpilotUIState()->sm);
const cereal::StarPilotRadarState::Reader &starpilot_radar_state = fpsm["starpilotRadarState"].getStarpilotRadarState();
const cereal::StarPilotRadarState::LeadData::Reader &lead_left = starpilot_radar_state.getLeadLeft();
const cereal::StarPilotRadarState::LeadData::Reader &lead_right = starpilot_radar_state.getLeadRight();
updateAdjacentLeads(starpilot_radar_state, model.getPosition());
starpilot_nvg->adjacentLeadTextRect = QRect();
if (lead_left.getStatus() && lead_right.getStatus() && (lead_left.getDRel() < lead_right.getDRel())) {
drawLead(painter, reinterpret_cast<const cereal::RadarState::LeadData::Reader&>(lead_left), adjacent_lead_vertices[0], surface_rect, starpilot_nvg->blueColor(), true);
drawLead(painter, reinterpret_cast<const cereal::RadarState::LeadData::Reader&>(lead_right), adjacent_lead_vertices[1], surface_rect, starpilot_nvg->purpleColor(), true);
} else {
if (lead_left.getStatus()) {
drawLead(painter, reinterpret_cast<const cereal::RadarState::LeadData::Reader&>(lead_left), adjacent_lead_vertices[0], surface_rect, starpilot_nvg->blueColor(), true);
}
if (lead_right.getStatus()) {
drawLead(painter, reinterpret_cast<const cereal::RadarState::LeadData::Reader&>(lead_right), adjacent_lead_vertices[1], surface_rect, starpilot_nvg->purpleColor(), true);
}
}
}
}
if (starpilot_toggles.value("radar_tracks").toBool()) {
updateRadarTracks(model.getPosition());
}
painter.restore();
}
void ModelRenderer::update_leads(const cereal::RadarState::Reader &radar_state, const cereal::XYZTData::Reader &line) {
for (int i = 0; i < 2; ++i) {
const auto &lead_data = (i == 0) ? radar_state.getLeadOne() : radar_state.getLeadTwo();
if (lead_data.getStatus()) {
float z = line.getZ()[get_path_length_idx(line, lead_data.getDRel())];
mapToScreen(lead_data.getDRel(), -lead_data.getYRel(), z + path_offset_z, &lead_vertices[i]);
}
}
}
void ModelRenderer::update_model(const cereal::ModelDataV2::Reader &model, const cereal::RadarState::LeadData::Reader &lead, float height) {
const auto &model_position = model.getPosition();
float max_distance = *(model_position.getX().end() - 1);
// update lane lines
const auto &lane_lines = model.getLaneLines();
const auto &line_probs = model.getLaneLineProbs();
int max_idx = get_path_length_idx(lane_lines[0], max_distance);
for (int i = 0; i < std::size(lane_line_vertices); i++) {
lane_line_probs[i] = line_probs[i];
mapLineToPolygon(lane_lines[i], (starpilot_toggles.value("model_ui").toBool() ? starpilot_toggles.value("lane_line_width").toDouble() : 0.025) * lane_line_probs[i], 0, &lane_line_vertices[i], max_idx);
}
// update road edges
const auto &road_edges = model.getRoadEdges();
const auto &edge_stds = model.getRoadEdgeStds();
for (int i = 0; i < std::size(road_edge_vertices); i++) {
road_edge_stds[i] = edge_stds[i];
mapLineToPolygon(road_edges[i], starpilot_toggles.value("model_ui").toBool() ? starpilot_toggles.value("road_edge_width").toDouble() : 0.025, 0, &road_edge_vertices[i], max_idx);
}
// update path
if (lead.getStatus()) {
const float lead_d = lead.getDRel() * 2.;
max_distance = std::clamp((float)(lead_d - fmin(lead_d * 0.35, 10.)), 0.0f, max_distance);
}
max_idx = get_path_length_idx(model_position, max_distance);
float path_width = starpilot_toggles.value("path_width").toDouble();
if (starpilot_toggles.value("dynamic_path_width").toBool()) {
UIState *s = uiState();
path_width *= s->status == STATUS_ENGAGED ? 1.0f : s->status == STATUS_ALWAYS_ON_LATERAL_ACTIVE ? 0.75f : 0.50f;
}
mapLineToPolygon(model_position, starpilot_toggles.value("model_ui").toBool() ? path_width * (1 - (starpilot_toggles.value("path_edge_width").toDouble() / 100.0f)) : 0.9, path_offset_z, &track_vertices, max_idx, false);
StarPilotUIState *fs = starpilotUIState();
SubMaster &fpsm = *(fs->sm);
const cereal::StarPilotPlan::Reader &starpilotPlan = fpsm["starpilotPlan"].getStarpilotPlan();
starpilot_nvg->track_vertices = track_vertices;
mapLineToPolygon(model_position, starpilot_toggles.value("model_ui").toBool() ? path_width : 0, path_offset_z, &starpilot_nvg->track_edge_vertices, max_idx, false);
mapAveragedLineToPolygon(lane_lines[0], lane_lines[1], starpilotPlan.getLaneWidthLeft() / 2.0f, 0, &starpilot_nvg->track_adjacent_vertices[0], max_idx, height, false);
mapAveragedLineToPolygon(lane_lines[2], lane_lines[3], starpilotPlan.getLaneWidthRight() / 2.0f, 0, &starpilot_nvg->track_adjacent_vertices[1], max_idx, height, false);
}
void ModelRenderer::drawLaneLines(QPainter &painter) {
// lanelines
for (int i = 0; i < std::size(lane_line_vertices); ++i) {
if (starpilot_toggles.value("color_scheme").toString() != "stock") {
painter.setBrush(QColor::fromRgbF(1.0, 1.0, 1.0, std::clamp<float>(lane_line_probs[i], 0.0, 0.7)));
} else {
QColor lane_color = QColor(starpilot_toggles.value("lane_lines_color").toString());
lane_color.setAlphaF(lane_color.alphaF() * std::clamp<float>(lane_line_probs[i], 0.0, 0.7));
painter.setBrush(lane_color);
}
painter.drawPolygon(lane_line_vertices[i]);
}
// road edges
for (int i = 0; i < std::size(road_edge_vertices); ++i) {
painter.setBrush(QColor::fromRgbF(1.0, 0, 0, std::clamp<float>(1.0 - road_edge_stds[i], 0.0, 1.0)));
painter.drawPolygon(road_edge_vertices[i]);
}
}
void ModelRenderer::drawPath(QPainter &painter, const cereal::ModelDataV2::Reader &model, int height) {
QLinearGradient bg(0, height, 0, 0);
if (experimental_mode || starpilot_toggles.value("acceleration_path").toBool() || starpilot_toggles.value("rainbow_path").toBool()) {
// The first half of track_vertices are the points for the right side of the path
const auto &acceleration = model.getAcceleration().getX();
const int max_len = std::min<int>(track_vertices.length() / 2, acceleration.size());
for (int i = 0; i < max_len; ++i) {
// Some points are out of frame
int track_idx = max_len - i - 1; // flip idx to start from bottom right
if (track_vertices[track_idx].y() < 0 || track_vertices[track_idx].y() > height) continue;
// Flip so 0 is bottom of frame
float lin_grad_point = (height - track_vertices[track_idx].y()) / height;
if ((fabs(acceleration[i]) < 0.25 || !starpilot_toggles.value("acceleration_path").toBool()) && starpilot_toggles.value("rainbow_path").toBool()) {
starpilot_nvg->paintRainbowPath(painter, bg, lin_grad_point);
} else if (fabs(acceleration[i]) < 0.25 && starpilot_toggles.value("color_scheme").toString() != "stock") {
QColor color = QColor(starpilot_toggles.value("path_color").toString());
color.setAlphaF(util::map_val(lin_grad_point, 0.0f, 1.0f, 1.0f, 0.1f));
bg.setColorAt(lin_grad_point, color);
} else {
// speed up: 120, slow down: 0
float path_hue = fmax(fmin(60 + acceleration[i] * 35, 120), 0);
// FIXME: painter.drawPolygon can be slow if hue is not rounded
path_hue = int(path_hue * 100 + 0.5) / 100;
float saturation = fmin(fabs(acceleration[i] * 1.5), 1);
float lightness = util::map_val(saturation, 0.0f, 1.0f, 0.95f, 0.62f); // lighter when grey
float alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, 0.4f, 0.0f); // matches previous alpha fade
bg.setColorAt(lin_grad_point, QColor::fromHslF(path_hue / 360., saturation, lightness, alpha));
// Skip a point, unless next is last
i += (i + 2) < max_len ? 1 : 0;
}
}
} else {
updatePathGradient(bg);
}
painter.setBrush(bg);
painter.drawPolygon(track_vertices);
if (starpilot_toggles.value("adjacent_paths").toBool() || starpilot_toggles.value("adjacent_path_metrics").toBool()) {
starpilot_nvg->paintAdjacentPaths(painter);
} else if (starpilot_toggles.value("blind_spot_path").toBool()) {
starpilot_nvg->paintBlindSpotPath(painter);
}
starpilot_nvg->paintPathEdges(painter, height);
}
void ModelRenderer::updatePathGradient(QLinearGradient &bg) {
static const QColor throttle_colors[] = {
QColor::fromHslF(148. / 360., 0.94, 0.51, 0.4),
QColor::fromHslF(112. / 360., 1.0, 0.68, 0.35),
QColor::fromHslF(112. / 360., 1.0, 0.68, 0.0)};
static const QColor no_throttle_colors[] = {
QColor::fromHslF(148. / 360., 0.0, 0.95, 0.4),
QColor::fromHslF(112. / 360., 0.0, 0.95, 0.35),
QColor::fromHslF(112. / 360., 0.0, 0.95, 0.0),
};
// Transition speed; 0.1 corresponds to 0.5 seconds at UI_FREQ
constexpr float transition_speed = 0.1f;
// Start transition if throttle state changes
bool allow_throttle = (*uiState()->sm)["longitudinalPlan"].getLongitudinalPlan().getAllowThrottle() || !longitudinal_control;
if (allow_throttle != prev_allow_throttle) {
prev_allow_throttle = allow_throttle;
// Invert blend factor for a smooth transition when the state changes mid-animation
blend_factor = std::max(1.0f - blend_factor, 0.0f);
}
const QColor *begin_colors = allow_throttle ? no_throttle_colors : throttle_colors;
const QColor *end_colors = allow_throttle ? throttle_colors : no_throttle_colors;
if (blend_factor < 1.0f) {
blend_factor = std::min(blend_factor + transition_speed, 1.0f);
}
// Set gradient colors by blending the start and end colors
bg.setColorAt(0.0f, blendColors(begin_colors[0], end_colors[0], blend_factor));
bg.setColorAt(0.5f, blendColors(begin_colors[1], end_colors[1], blend_factor));
bg.setColorAt(1.0f, blendColors(begin_colors[2], end_colors[2], blend_factor));
}
QColor ModelRenderer::blendColors(const QColor &start, const QColor &end, float t) {
if (t == 1.0f) return end;
return QColor::fromRgbF(
(1 - t) * start.redF() + t * end.redF(),
(1 - t) * start.greenF() + t * end.greenF(),
(1 - t) * start.blueF() + t * end.blueF(),
(1 - t) * start.alphaF() + t * end.alphaF());
}
void ModelRenderer::drawLead(QPainter &painter, const cereal::RadarState::LeadData::Reader &lead_data,
const QPointF &vd, const QRect &surface_rect, QColor marker_color, bool adjacent) {
const float speedBuff = 10.;
const float leadBuff = 40.;
const float d_rel = lead_data.getDRel() + (adjacent ? fabs(lead_data.getYRel()) : 0);
const float v_rel = lead_data.getVRel();
float fillAlpha = 0;
if (d_rel < leadBuff) {
fillAlpha = 255 * (1.0 - (d_rel / leadBuff));
if (v_rel < 0) {
fillAlpha += 255 * (-1 * (v_rel / speedBuff));
}
fillAlpha = (int)(fmin(fillAlpha, 255));
}
float sz = std::clamp((25 * 30) / (d_rel / 3 + 30), 15.0f, 30.0f) * 2.35;
float x = std::clamp<float>(vd.x(), 0.f, surface_rect.width() - sz / 2);
float y = std::min<float>(vd.y(), surface_rect.height() - sz * 0.6);
float g_xo = sz / 5;
float g_yo = sz / 10;
QPointF glow[] = {{x + (sz * 1.35) + g_xo, y + sz + g_yo}, {x, y - g_yo}, {x - (sz * 1.35) - g_xo, y + sz + g_yo}};
painter.setBrush(QColor(218, 202, 37, 255));
painter.drawPolygon(glow, std::size(glow));
// chevron
QPointF chevron[] = {{x + (sz * 1.25), y + sz}, {x, y}, {x - (sz * 1.25), y + sz}};
painter.setBrush(QColor(marker_color.red(), marker_color.green(), marker_color.blue(), fillAlpha));
painter.drawPolygon(chevron, std::size(chevron));
if (starpilot_toggles.value("lead_info").toBool()) {
starpilot_nvg->paintLeadMetrics(painter, adjacent, chevron, lead_data);
}
}
// Projects a point in car to space to the corresponding point in full frame image space.
bool ModelRenderer::mapToScreen(float in_x, float in_y, float in_z, QPointF *out) {
Eigen::Vector3f input(in_x, in_y, in_z);
auto pt = car_space_transform * input;
*out = QPointF(pt.x() / pt.z(), pt.y() / pt.z());
return clip_region.contains(*out);
}
void ModelRenderer::mapLineToPolygon(const cereal::XYZTData::Reader &line, float y_off, float z_off,
QPolygonF *pvd, int max_idx, bool allow_invert) {
const auto line_x = line.getX(), line_y = line.getY(), line_z = line.getZ();
QPointF left, right;
pvd->clear();
for (int i = 0; i <= max_idx; i++) {
// highly negative x positions are drawn above the frame and cause flickering, clip to zy plane of camera
if (line_x[i] < 0) continue;
bool l = mapToScreen(line_x[i], line_y[i] - y_off, line_z[i] + z_off, &left);
bool r = mapToScreen(line_x[i], line_y[i] + y_off, line_z[i] + z_off, &right);
if (l && r) {
// For wider lines the drawn polygon will "invert" when going over a hill and cause artifacts
if (!allow_invert && pvd->size() && left.y() > pvd->back().y()) {
continue;
}
pvd->push_back(left);
pvd->push_front(right);
}
}
}
void ModelRenderer::mapAveragedLineToPolygon(const cereal::XYZTData::Reader &line1, const cereal::XYZTData::Reader &line2, float y_off, float z_off,
QPolygonF *pvd, int max_idx, float height, bool allow_invert) {
const auto line_x1 = line1.getX(), line_y1 = line1.getY(), line_z1 = line1.getZ();
const auto line_y2 = line2.getY();
QPointF left, right;
pvd->clear();
for (int i = 0; i <= max_idx; i++) {
// highly negative x positions are drawn above the frame and cause flickering, clip to zy plane of camera
if (line_x1[i] < 0) continue;
bool l = mapToScreen(line_x1[i], ((line_y1[i] + line_y2[i]) / 2.0f) - y_off, line_z1[i] + z_off, &left);
bool r = mapToScreen(line_x1[i], ((line_y1[i] + line_y2[i]) / 2.0f) + y_off, line_z1[i] + z_off, &right);
if (l && r) {
// For wider lines the drawn polygon will "invert" when going over a hill and cause artifacts
if (!allow_invert && pvd->size() && left.y() > pvd->back().y()) {
continue;
}
pvd->push_back(left);
pvd->push_front(right);
}
}
// Ground the path
if (pvd->size() >= 4) {
int mid = pvd->size() / 2;
std::function<void(int, int)> extendToBottom = [&](int idx1, int idx2) {
QPointF &p0 = (*pvd)[idx1];
QPointF &p1 = (*pvd)[idx2];
float dy = p0.y() - p1.y();
if (std::abs(dy) > 0.1f) {
float slope = (p0.x() - p1.x()) / dy;
p0.setX(p0.x() + (height - p0.y()) * slope);
p0.setY(height);
}
};
extendToBottom(mid, mid + 1);
extendToBottom(mid - 1, mid - 2);
}
}
void ModelRenderer::updateAdjacentLeads(const cereal::StarPilotRadarState::Reader &radar_state, const cereal::XYZTData::Reader &line) {
for (int i = 0; i < 2; ++i) {
const auto &lead_data = (i == 0) ? radar_state.getLeadLeft() : radar_state.getLeadRight();
if (lead_data.getStatus()) {
float z = line.getZ()[get_path_length_idx(line, lead_data.getDRel())];
mapToScreen(lead_data.getDRel(), -lead_data.getYRel(), z + path_offset_z, &adjacent_lead_vertices[i]);
}
}
}
void ModelRenderer::updateRadarTracks(const cereal::XYZTData::Reader &line) {
std::vector<QPointF> &radar_tracks = starpilot_nvg->radar_tracks;
radar_tracks.clear();
SubMaster &fpsm = *(starpilotUIState()->sm);
capnp::List<cereal::RadarData::RadarPoint>::Reader radar_points = fpsm["liveTracks"].getLiveTracks().getPoints();
radar_tracks.reserve(radar_points.size());
capnp::List<float>::Reader line_z = line.getZ();
for (cereal::RadarData::RadarPoint::Reader point : radar_points) {
float d_rel = point.getDRel();
float z = line_z[get_path_length_idx(line, d_rel)];
QPointF calibrated_point;
if (mapToScreen(d_rel, -point.getYRel(), z + path_offset_z, &calibrated_point)) {
radar_tracks.push_back(calibrated_point);
}
}
}
-54
View File
@@ -1,54 +0,0 @@
#pragma once
#include <QPainter>
#include <QPolygonF>
#include "selfdrive/ui/ui.h"
#include "starpilot/ui/qt/onroad/starpilot_annotated_camera.h"
class ModelRenderer {
public:
ModelRenderer() {}
void setTransform(const Eigen::Matrix3f &transform) { car_space_transform = transform; }
void draw(QPainter &painter, const QRect &surface_rect);
StarPilotAnnotatedCameraWidget *starpilot_nvg;
StarPilotUIScene starpilot_scene;
QJsonObject starpilot_toggles;
private:
bool mapToScreen(float in_x, float in_y, float in_z, QPointF *out);
void mapLineToPolygon(const cereal::XYZTData::Reader &line, float y_off, float z_off,
QPolygonF *pvd, int max_idx, bool allow_invert = true);
void drawLead(QPainter &painter, const cereal::RadarState::LeadData::Reader &lead_data, const QPointF &vd, const QRect &surface_rect, QColor marker_color, bool adjacent=false);
void update_leads(const cereal::RadarState::Reader &radar_state, const cereal::XYZTData::Reader &line);
void update_model(const cereal::ModelDataV2::Reader &model, const cereal::RadarState::LeadData::Reader &lead, float height);
void drawLaneLines(QPainter &painter);
void drawPath(QPainter &painter, const cereal::ModelDataV2::Reader &model, int height);
void updatePathGradient(QLinearGradient &bg);
QColor blendColors(const QColor &start, const QColor &end, float t);
bool longitudinal_control = false;
bool experimental_mode = false;
float blend_factor = 1.0f;
bool prev_allow_throttle = true;
float lane_line_probs[4] = {};
float road_edge_stds[2] = {};
float path_offset_z = 1.22f;
QPolygonF track_vertices;
QPolygonF lane_line_vertices[4] = {};
QPolygonF road_edge_vertices[2] = {};
QPointF lead_vertices[2] = {};
Eigen::Matrix3f car_space_transform = Eigen::Matrix3f::Zero();
QRectF clip_region;
void mapAveragedLineToPolygon(const cereal::XYZTData::Reader &line1, const cereal::XYZTData::Reader &line2, float y_off, float z_off,
QPolygonF *pvd, int max_idx, float height, bool allow_invert = true);
void updateAdjacentLeads(const cereal::StarPilotRadarState::Reader &radar_state, const cereal::XYZTData::Reader &line);
void updateRadarTracks(const cereal::XYZTData::Reader &line);
QPointF adjacent_lead_vertices[2] = {};
};
-149
View File
@@ -1,149 +0,0 @@
#include "selfdrive/ui/qt/onroad/onroad_home.h"
#include <QPainter>
#include <QStackedLayout>
#include "selfdrive/ui/qt/util.h"
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setMargin(UI_BORDER_SIZE);
QStackedLayout *stacked_layout = new QStackedLayout;
stacked_layout->setStackingMode(QStackedLayout::StackAll);
main_layout->addLayout(stacked_layout);
nvg = new AnnotatedCameraWidget(VISION_STREAM_ROAD, this);
QWidget * split_wrapper = new QWidget;
split = new QHBoxLayout(split_wrapper);
split->setContentsMargins(0, 0, 0, 0);
split->setSpacing(0);
split->addWidget(nvg);
if (getenv("DUAL_CAMERA_VIEW")) {
CameraWidget *arCam = new CameraWidget("camerad", VISION_STREAM_ROAD, this);
split->insertWidget(0, arCam);
}
stacked_layout->addWidget(split_wrapper);
alerts = new OnroadAlerts(this);
alerts->setAttribute(Qt::WA_TransparentForMouseEvents, true);
stacked_layout->addWidget(alerts);
// setup stacking order
alerts->raise();
setAttribute(Qt::WA_OpaquePaintEvent);
QObject::connect(uiState(), &UIState::uiUpdate, this, &OnroadWindow::updateState);
QObject::connect(uiState(), &UIState::offroadTransition, this, &OnroadWindow::offroadTransition);
starpilot_nvg = new StarPilotAnnotatedCameraWidget(this);
starpilot_onroad = new StarPilotOnroadWindow(this);
starpilot_onroad->setAttribute(Qt::WA_TransparentForMouseEvents, true);
stacked_layout->addWidget(starpilot_nvg);
stacked_layout->addWidget(starpilot_onroad);
starpilot_onroad->raise();
alerts->raise();
nvg->starpilot_nvg = starpilot_nvg;
}
void OnroadWindow::updateState(const UIState &s, const StarPilotUIState &fs) {
if (!s.scene.started) {
return;
}
alerts->updateState(s, fs);
nvg->updateState(s, fs);
const StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
const QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
const auto selfdriveState = (*s.sm)["selfdriveState"].getSelfdriveState();
const bool enabled = selfdriveState.getEnabled();
QColor bgColor = bg_colors[s.status];
const bool conditional_experimental_mode = starpilot_toggles.value("conditional_experimental_mode").toBool();
const bool conditional_chill_mode = starpilot_toggles.value("conditional_chill_mode").toBool();
const bool highlight_override =
enabled && ((conditional_experimental_mode && starpilot_scene.conditional_status == 1) ||
(conditional_chill_mode && (starpilot_scene.conditional_status == 1 || starpilot_scene.conditional_status == 2)));
if (starpilot_scene.switchback_mode_enabled && (enabled || starpilot_scene.always_on_lateral_active)) {
bgColor = bg_colors[STATUS_SWITCHBACK_MODE_ENABLED];
} else if (starpilot_scene.always_on_lateral_active) {
bgColor = bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE];
} else if (highlight_override) {
bgColor = bg_colors[STATUS_CEM_DISABLED];
} else if (enabled && selfdriveState.getExperimentalMode()) {
bgColor = bg_colors[STATUS_EXPERIMENTAL_MODE_ENABLED];
} else if (starpilot_scene.traffic_mode_enabled && enabled) {
bgColor = bg_colors[STATUS_TRAFFIC_MODE_ENABLED];
}
if (bg != bgColor) {
// repaint border
bg = bgColor;
update();
}
starpilot_nvg->alertHeight = alerts->alertHeight;
starpilot_onroad->bg = bg;
starpilot_onroad->fps = nvg->fps;
nvg->starpilot_nvg = starpilot_nvg;
nvg->starpilot_scene = starpilot_scene;
starpilot_nvg->starpilot_scene = starpilot_scene;
starpilot_onroad->starpilot_scene = starpilot_scene;
alerts->starpilot_toggles = starpilot_toggles;
starpilot_nvg->starpilot_toggles = starpilot_toggles;
starpilot_onroad->starpilot_toggles = starpilot_toggles;
nvg->starpilot_toggles = starpilot_toggles;
starpilot_onroad->setGeometry(rect());
starpilot_nvg->updateState(s, fs);
starpilot_onroad->updateState(s, fs);
}
void OnroadWindow::offroadTransition(bool offroad) {
alerts->clear();
}
void OnroadWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255));
}
void OnroadWindow::mousePressEvent(QMouseEvent* mouseEvent) {
if (nvg->handleHudPress(mouseEvent->pos())) {
grabMouse();
mouseEvent->accept();
return;
}
starpilot_nvg->mousePressEvent(mouseEvent);
if (mouseEvent->isAccepted()) {
return;
}
// propagation event to parent(HomeWindow)
QWidget::mousePressEvent(mouseEvent);
}
void OnroadWindow::mouseReleaseEvent(QMouseEvent* mouseEvent) {
const bool handled = nvg->handleHudRelease(mouseEvent->pos());
if (QWidget::mouseGrabber() == this) {
releaseMouse();
}
if (handled) {
mouseEvent->accept();
return;
}
QWidget::mouseReleaseEvent(mouseEvent);
}
-30
View File
@@ -1,30 +0,0 @@
#pragma once
#include "selfdrive/ui/qt/onroad/alerts.h"
#include "selfdrive/ui/qt/onroad/annotated_camera.h"
#include "starpilot/ui/qt/onroad/starpilot_onroad.h"
class OnroadWindow : public QWidget {
Q_OBJECT
public:
OnroadWindow(QWidget* parent = 0);
private:
void paintEvent(QPaintEvent *event);
OnroadAlerts *alerts;
AnnotatedCameraWidget *nvg;
QColor bg = bg_colors[STATUS_DISENGAGED];
QHBoxLayout* split;
void mousePressEvent(QMouseEvent* mouseEvent);
void mouseReleaseEvent(QMouseEvent* mouseEvent);
StarPilotAnnotatedCameraWidget *starpilot_nvg;
StarPilotOnroadWindow *starpilot_onroad;
private slots:
void offroadTransition(bool offroad);
void updateState(const UIState &s, const StarPilotUIState &fs);
};
-48
View File
@@ -1,48 +0,0 @@
#include "selfdrive/ui/qt/prime_state.h"
#include <QJsonDocument>
#include "selfdrive/ui/qt/api.h"
#include "selfdrive/ui/qt/request_repeater.h"
#include "selfdrive/ui/qt/util.h"
PrimeState::PrimeState(QObject* parent) : QObject(parent) {
const char *env_prime_type = std::getenv("PRIME_TYPE");
auto type = env_prime_type ? env_prime_type : Params().get("PrimeType");
if (!type.empty()) {
prime_type = static_cast<PrimeState::Type>(std::atoi(type.c_str()));
}
if (auto dongleId = getDongleId()) {
QString url = CommaApi::BASE_URL + "/v1.1/devices/" + *dongleId + "/";
RequestRepeater* repeater = new RequestRepeater(this, url, "ApiCache_Device", 60);
QObject::connect(repeater, &RequestRepeater::requestDone, this, &PrimeState::handleReply);
}
// Emit the initial state change
QTimer::singleShot(1, [this]() { emit changed(prime_type); });
}
void PrimeState::handleReply(const QString& response, bool success) {
if (!success) return;
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
if (doc.isNull()) {
qDebug() << "JSON Parse failed on getting pairing and PrimeState status";
return;
}
QJsonObject json = doc.object();
bool is_paired = json["is_paired"].toBool();
auto type = static_cast<PrimeState::Type>(json["prime_type"].toInt());
setType(is_paired ? type : PrimeState::PRIME_TYPE_UNPAIRED);
}
void PrimeState::setType(PrimeState::Type type) {
if (type != prime_type) {
prime_type = type;
Params().put("PrimeType", std::to_string(prime_type));
emit changed(prime_type);
}
}
-33
View File
@@ -1,33 +0,0 @@
#pragma once
#include <QObject>
class PrimeState : public QObject {
Q_OBJECT
public:
enum Type {
PRIME_TYPE_UNKNOWN = -2,
PRIME_TYPE_UNPAIRED = -1,
PRIME_TYPE_NONE = 0,
PRIME_TYPE_MAGENTA = 1,
PRIME_TYPE_LITE = 2,
PRIME_TYPE_BLUE = 3,
PRIME_TYPE_MAGENTA_NEW = 4,
PRIME_TYPE_PURPLE = 5,
};
PrimeState(QObject *parent);
void setType(PrimeState::Type type);
inline PrimeState::Type currentType() const { return prime_type; }
inline bool isSubscribed() const { return prime_type > PrimeState::PRIME_TYPE_NONE; }
signals:
void changed(PrimeState::Type prime_type);
private:
void handleReply(const QString &response, bool success);
PrimeState::Type prime_type = PrimeState::PRIME_TYPE_UNKNOWN;
};
-36
View File
@@ -1,36 +0,0 @@
#include "selfdrive/ui/qt/qt_window.h"
void setMainWindow(QWidget *w) {
const float scale = util::getenv("SCALE", 1.0f);
const QSize sz = QGuiApplication::primaryScreen()->size();
if (Hardware::PC() && scale == 1.0 && !(sz - DEVICE_SCREEN_SIZE).isValid()) {
w->setMinimumSize(QSize(640, 480)); // allow resize smaller than fullscreen
w->setMaximumSize(DEVICE_SCREEN_SIZE);
w->resize(sz);
} else {
w->setFixedSize(DEVICE_SCREEN_SIZE * scale);
}
w->show();
#ifdef QCOM2
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
wl_surface *s = reinterpret_cast<wl_surface*>(native->nativeResourceForWindow("surface", w->windowHandle()));
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
wl_surface_commit(s);
w->setWindowState(Qt::WindowFullScreen);
w->setVisible(true);
// ensure we have a valid eglDisplay, otherwise the ui will silently fail
void *egl = native->nativeResourceForWindow("egldisplay", w->windowHandle());
assert(egl != nullptr);
#endif
}
extern "C" {
void set_main_window(void *w) {
setMainWindow((QWidget*)w);
}
}
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include <string>
#include <QApplication>
#include <QScreen>
#include <QWidget>
#ifdef QCOM2
#include <qpa/qplatformnativeinterface.h>
#include <wayland-client-protocol.h>
#include <QPlatformSurfaceEvent>
#endif
#include "system/hardware/hw.h"
const QString ASSET_PATH = ":/";
const QSize DEVICE_SCREEN_SIZE = {2160, 1080};
void setMainWindow(QWidget *w);
-27
View File
@@ -1,27 +0,0 @@
#include "selfdrive/ui/qt/request_repeater.h"
RequestRepeater::RequestRepeater(QObject *parent, const QString &requestURL, const QString &cacheKey,
int period, bool while_onroad) : HttpRequest(parent) {
timer = new QTimer(this);
timer->setTimerType(Qt::VeryCoarseTimer);
QObject::connect(timer, &QTimer::timeout, [=]() {
if ((!uiState()->scene.started || while_onroad) && device()->isAwake() && !active()) {
sendRequest(requestURL);
}
});
timer->start(period * 1000);
if (!cacheKey.isEmpty()) {
prevResp = QString::fromStdString(params.get(cacheKey.toStdString()));
if (!prevResp.isEmpty()) {
QTimer::singleShot(500, [=]() { emit requestDone(prevResp, true, QNetworkReply::NoError); });
}
QObject::connect(this, &HttpRequest::requestDone, [=](const QString &resp, bool success) {
if (success && resp != prevResp) {
params.put(cacheKey.toStdString(), resp.toStdString());
prevResp = resp;
}
});
}
}
-15
View File
@@ -1,15 +0,0 @@
#pragma once
#include "common/util.h"
#include "selfdrive/ui/qt/api.h"
#include "selfdrive/ui/ui.h"
class RequestRepeater : public HttpRequest {
public:
RequestRepeater(QObject *parent, const QString &requestURL, const QString &cacheKey = "", int period = 0, bool while_onroad=false);
private:
Params params;
QTimer *timer;
QString prevResp;
};
-336
View File
@@ -1,336 +0,0 @@
#include "selfdrive/ui/qt/sidebar.h"
#include <cstdlib>
#include <string>
#include <QMouseEvent>
#include "selfdrive/ui/qt/util.h"
void Sidebar::drawMetric(QPainter &p, const QPair<QString, QString> &label, QColor c, int y) {
const QRect rect = {30, y, 240, 126};
p.setPen(Qt::NoPen);
p.setBrush(QBrush(c));
p.setClipRect(rect.x() + 4, rect.y(), 18, rect.height(), Qt::ClipOperation::ReplaceClip);
p.drawRoundedRect(QRect(rect.x() + 4, rect.y() + 4, 100, 118), 18, 18);
p.setClipping(false);
QPen pen = QPen(QColor(0xff, 0xff, 0xff, 0x55));
pen.setWidth(2);
p.setPen(pen);
p.setBrush(Qt::NoBrush);
p.drawRoundedRect(rect, 20, 20);
p.setPen(QColor(0xff, 0xff, 0xff));
p.setFont(InterFont(35, QFont::DemiBold));
p.drawText(rect.adjusted(22, 0, 0, 0), Qt::AlignCenter, label.first + "\n" + label.second);
}
Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(false), settings_pressed(false), mic_indicator_pressed(false) {
home_img = loadPixmap("../assets/images/button_home.png", home_btn.size());
flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size());
settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio);
mic_img = loadPixmap("../assets/icons/microphone.png", QSize(30, 30));
link_img = loadPixmap("../assets/icons/link.png", QSize(60, 60));
connect(this, &Sidebar::valueChanged, [=] { update(); });
setAttribute(Qt::WA_OpaquePaintEvent);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
setFixedWidth(300);
QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState);
pm = std::make_unique<PubMaster>(std::vector<const char*>{"bookmarkButton"});
QObject::connect(starpilotUIState(), &StarPilotUIState::themeUpdated, this, &Sidebar::updateTheme);
}
void Sidebar::mousePressEvent(QMouseEvent *event) {
QPoint pos = event->pos();
static constexpr QRect cpuRect = {30, 496, 240, 126};
static constexpr QRect memoryRect = {30, 654, 240, 126};
static constexpr QRect tempRect = {30, 338, 240, 126};
static int showChip = 0;
static int showMemory = 0;
static int showTemp = 0;
StarPilotUIState *fs = starpilotUIState();
StarPilotUIScene &starpilot_scene = fs->starpilot_scene;
QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
const bool simple_mode = starpilot_toggles.value("simple_mode").toBool();
if (!simple_mode && cpuRect.contains(pos) && starpilot_toggles.value("developer_ui").toBool()) {
showChip = (showChip + 1) % 3;
params.putBool("ShowCPU", showChip == 1);
params.putBool("ShowGPU", showChip == 2);
} else if (!simple_mode && memoryRect.contains(pos) && starpilot_toggles.value("developer_ui").toBool()) {
showMemory = (showMemory + 1) % 4;
params.putBool("ShowMemoryUsage", showMemory == 1);
params.putBool("ShowStorageLeft", showMemory == 2);
params.putBool("ShowStorageUsed", showMemory == 3);
} else if (!simple_mode && tempRect.contains(pos) && starpilot_toggles.value("developer_ui").toBool()) {
showTemp = (showTemp + 1) % 3;
params.putBool("Fahrenheit", showTemp == 2);
params.putBool("NumericalTemp", showTemp != 0);
} else if (onroad && home_btn.contains(pos)) {
flag_pressed = true;
} else if (settings_btn.contains(pos)) {
settings_pressed = true;
} else if (recording_audio && mic_indicator_btn.contains(event->pos())) {
mic_indicator_pressed = true;
}
if (!(flag_pressed || mic_indicator_pressed || settings_pressed)) {
update();
updateStarPilotToggles();
}
}
void Sidebar::mouseReleaseEvent(QMouseEvent *event) {
if (flag_pressed || settings_pressed || mic_indicator_pressed) {
flag_pressed = settings_pressed = mic_indicator_pressed = false;
update();
}
if (onroad && home_btn.contains(event->pos())) {
MessageBuilder msg;
msg.initEvent().initBookmarkButton();
pm->send("bookmarkButton", msg);
} else if (settings_btn.contains(event->pos())) {
emit openSettings();
} else if (recording_audio && mic_indicator_btn.contains(event->pos())) {
emit openSettings(2, "RecordAudio");
}
}
void Sidebar::offroadTransition(bool offroad) {
onroad = !offroad;
update();
}
void Sidebar::updateState(const UIState &s, const StarPilotUIState &fs) {
if (!isVisible()) return;
const StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
const QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
const bool simple_mode = starpilot_toggles.value("simple_mode").toBool();
static bool previous_simple_mode = simple_mode;
if (previous_simple_mode != simple_mode) {
updateTheme();
previous_simple_mode = simple_mode;
}
const SubMaster &fpsm = *(fs.sm);
const cereal::StarPilotDeviceState::Reader &starpilotDeviceState = fpsm["starpilotDeviceState"].getStarpilotDeviceState();
auto &sm = *(s.sm);
networking = networking ? networking : window()->findChild<Networking *>("");
bool tethering_on = networking && networking->wifi->tethering_on;
auto deviceState = sm["deviceState"].getDeviceState();
const char *desktop_fake_wifi_env = std::getenv("SP_ALLOW_DESKTOP_FAKE_WIFI");
const bool desktop_force_online = Hardware::PC() && desktop_fake_wifi_env != nullptr && std::string(desktop_fake_wifi_env) != "0";
auto net_type_value = desktop_force_online ? cereal::DeviceState::NetworkType::WIFI : deviceState.getNetworkType();
setProperty("netType", tethering_on ? "Hotspot" : network_type[net_type_value]);
int strength = tethering_on ? 4 : (desktop_force_online ? 4 : (int)deviceState.getNetworkStrength());
setProperty("netStrength", strength > 0 ? strength + 1 : 0);
ItemStatus connectStatus;
auto last_ping = deviceState.getLastAthenaPingTime();
if (desktop_force_online) {
connectStatus = ItemStatus{{tr("CONNECT"), tr("ONLINE")}, simple_mode ? good_color : QColor(starpilot_toggles.value("sidebar_color3").toString())};
} else if (last_ping == 0) {
connectStatus = ItemStatus{{tr("CONNECT"), tr("OFFLINE")}, warning_color};
} else {
connectStatus = nanos_since_boot() - last_ping < 80e9
? ItemStatus{{tr("CONNECT"), tr("ONLINE")}, simple_mode ? good_color : QColor(starpilot_toggles.value("sidebar_color3").toString())}
: ItemStatus{{tr("CONNECT"), tr("ERROR")}, danger_color};
}
setProperty("connectStatus", QVariant::fromValue(connectStatus));
int maxTempC = deviceState.getMaxTempC();
QString max_temp = starpilot_toggles.value("fahrenheit").toBool() ? QString::number(maxTempC * 9 / 5 + 32) + "°F" : QString::number(maxTempC) + "°C";
ItemStatus tempStatus = {{tr("TEMP"), simple_mode ? tr("HIGH") : (starpilot_toggles.value("numerical_temp").toBool() ? max_temp : tr("HIGH"))}, danger_color};
auto ts = deviceState.getThermalStatus();
if (ts == cereal::DeviceState::ThermalStatus::GREEN) {
tempStatus = {{tr("TEMP"), simple_mode ? tr("GOOD") : (starpilot_toggles.value("numerical_temp").toBool() ? max_temp : tr("GOOD"))},
simple_mode ? good_color : QColor(starpilot_toggles.value("sidebar_color1").toString())};
} else if (ts == cereal::DeviceState::ThermalStatus::YELLOW) {
tempStatus = {{tr("TEMP"), simple_mode ? tr("OK") : (starpilot_toggles.value("numerical_temp").toBool() ? max_temp : tr("OK"))}, warning_color};
}
setProperty("tempStatus", QVariant::fromValue(tempStatus));
ItemStatus pandaStatus = {{tr("VEHICLE"), tr("ONLINE")}, simple_mode ? good_color : QColor(starpilot_toggles.value("sidebar_color2").toString())};
if (s.scene.pandaType == cereal::PandaState::PandaType::UNKNOWN) {
pandaStatus = {{tr("NO"), tr("PANDA")}, danger_color};
}
setProperty("pandaStatus", QVariant::fromValue(pandaStatus));
setProperty("recordingAudio", s.scene.recording_audio);
if (!simple_mode && (starpilot_toggles.value("cpu_metrics").toBool() || starpilot_toggles.value("gpu_metrics").toBool())) {
capnp::List<int8_t>::Reader cpu_loads = deviceState.getCpuUsagePercent();
int cpu_usage = cpu_loads.size() != 0 ? std::accumulate(cpu_loads.begin(), cpu_loads.end(), 0) / cpu_loads.size() : 0;
int gpu_usage = deviceState.getGpuUsagePercent();
int usage = starpilot_toggles.value("cpu_metrics").toBool() ? cpu_usage : gpu_usage;
QString chip_usage = QString::number(usage) + "%";
ItemStatus chipStatus = {{starpilot_toggles.value("gpu_metrics").toBool() ? tr("GPU") : tr("CPU"), chip_usage}, QColor(starpilot_toggles.value("sidebar_color2").toString())};
if (usage >= 85) {
chipStatus = {{starpilot_toggles.value("gpu_metrics").toBool() ? tr("GPU") : tr("CPU"), chip_usage}, danger_color};
} else if (usage >= 70) {
chipStatus = {{starpilot_toggles.value("gpu_metrics").toBool() ? tr("GPU") : tr("CPU"), chip_usage}, warning_color};
}
setProperty("chipStatus", QVariant::fromValue(chipStatus));
}
if (!simple_mode && (starpilot_toggles.value("memory_metrics").toBool() || starpilot_toggles.value("storage_left_metrics").toBool() || starpilot_toggles.value("storage_used_metrics").toBool())) {
int free_space = deviceState.getFreeSpacePercent();
int memory_usage = deviceState.getMemoryUsagePercent();
int storage_left = starpilotDeviceState.getFreeSpace();
int storage_used = starpilotDeviceState.getUsedSpace();
QString memory = QString::number(memory_usage) + "%";
QString storage = QString::number(starpilot_toggles.value("storage_left_metrics").toBool() ? storage_left : storage_used) + tr(" GB");
if (starpilot_toggles.value("memory_metrics").toBool()) {
ItemStatus memoryStatus = {{tr("MEMORY"), memory}, QColor(starpilot_toggles.value("sidebar_color3").toString())};
if (memory_usage >= 85) {
memoryStatus = {{tr("MEMORY"), memory}, danger_color};
} else if (memory_usage >= 70) {
memoryStatus = {{tr("MEMORY"), memory}, warning_color};
}
setProperty("memoryStatus", QVariant::fromValue(memoryStatus));
} else {
ItemStatus storageStatus = {{starpilot_toggles.value("storage_left_metrics").toBool() ? tr("LEFT") : tr("USED"), storage}, QColor(starpilot_toggles.value("sidebar_color3").toString())};
if (free_space < 25 && free_space >= 10) {
storageStatus = {{starpilot_toggles.value("storage_left_metrics").toBool() ? tr("LEFT") : tr("USED"), storage}, warning_color};
} else if (10 > free_space) {
storageStatus = {{starpilot_toggles.value("storage_left_metrics").toBool() ? tr("LEFT") : tr("USED"), storage}, danger_color};
}
setProperty("storageStatus", QVariant::fromValue(storageStatus));
}
}
}
void Sidebar::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect(), QColor(57, 57, 57));
// buttons
p.setOpacity(settings_pressed ? 0.65 : 1.0);
p.drawPixmap(settings_btn.x(), settings_btn.y(), settings_gif ? settings_gif->currentPixmap() : settings_img);
p.setOpacity(onroad && flag_pressed ? 0.65 : 1.0);
p.drawPixmap(home_btn.x(), home_btn.y(), onroad ? flag_gif ? flag_gif->currentPixmap() : flag_img : home_gif ? home_gif->currentPixmap() : home_img);
if (recording_audio) {
p.setBrush(danger_color);
p.setOpacity(mic_indicator_pressed ? 0.65 : 1.0);
p.drawRoundedRect(mic_indicator_btn, mic_indicator_btn.height() / 2, mic_indicator_btn.height() / 2);
int icon_x = mic_indicator_btn.x() + (mic_indicator_btn.width() - mic_img.width()) / 2;
int icon_y = mic_indicator_btn.y() + (mic_indicator_btn.height() - mic_img.height()) / 2;
p.drawPixmap(icon_x, icon_y, mic_img);
}
p.setOpacity(1.0);
StarPilotUIState *fs = starpilotUIState();
StarPilotUIScene &starpilot_scene = fs->starpilot_scene;
QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
const bool simple_mode = starpilot_toggles.value("simple_mode").toBool();
// network
if (!simple_mode && starpilot_toggles.value("ip_metrics").toBool()) {
p.setPen(QColor(0xff, 0xff, 0xff));
p.save();
p.setFont(InterFont(30));
p.drawText(QRect(50, 196, 225, 27), Qt::AlignLeft | Qt::AlignVCenter, starpilotUIState()->wifi->getIp4Address());
p.restore();
} else {
int x = 58;
const QColor gray(0x54, 0x54, 0x54);
for (int i = 0; i < 5; ++i) {
p.setBrush(i < net_strength ? Qt::white : gray);
p.drawEllipse(x, 196, 27, 27);
x += 37;
}
}
p.setFont(InterFont(35));
p.setPen(QColor(0xff, 0xff, 0xff));
const QRect r = QRect(58, 247, width() - 100, 50);
if (net_type == "Hotspot") {
p.drawPixmap(r.x(), r.y() + (r.height() - link_img.height()) / 2, link_img);
} else {
p.drawText(r, Qt::AlignLeft | Qt::AlignVCenter, net_type);
}
// metrics
drawMetric(p, temp_status.first, temp_status.second, 338);
if (simple_mode) {
drawMetric(p, panda_status.first, panda_status.second, 496);
drawMetric(p, connect_status.first, connect_status.second, 654);
} else if (starpilot_toggles.value("cpu_metrics").toBool() || starpilot_toggles.value("gpu_metrics").toBool()) {
drawMetric(p, chip_status.first, chip_status.second, 496);
} else {
drawMetric(p, panda_status.first, panda_status.second, 496);
}
if (starpilot_toggles.value("memory_metrics").toBool()) {
drawMetric(p, memory_status.first, memory_status.second, 654);
} else if (starpilot_toggles.value("storage_left_metrics").toBool() || starpilot_toggles.value("storage_used_metrics").toBool()) {
drawMetric(p, storage_status.first, storage_status.second, 654);
} else {
drawMetric(p, connect_status.first, connect_status.second, 654);
}
}
void Sidebar::showEvent(QShowEvent *event) {
updateTheme();
}
void Sidebar::updateTheme() {
auto clearMovie = [](QSharedPointer<QMovie> &movie) {
if (!movie.isNull()) {
movie->stop();
movie.reset();
}
};
if (starpilotUIState()->starpilot_scene.starpilot_toggles.value("simple_mode").toBool()) {
clearMovie(home_gif);
clearMovie(flag_gif);
clearMovie(settings_gif);
home_img = loadPixmap("../assets/images/button_home.png", home_btn.size());
flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size());
settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio);
return;
}
loadImage("../../starpilot/assets/active_theme/icons/button_home", home_img, home_gif, home_btn.size(), this);
loadImage("../../starpilot/assets/active_theme/icons/button_flag", flag_img, flag_gif, home_btn.size(), this);
loadImage("../../starpilot/assets/active_theme/icons/button_settings", settings_img, settings_gif, settings_btn.size(), this);
// Keep stock icons visible when a theme is partial or missing an icon.
if (!home_gif && home_img.isNull()) {
home_img = loadPixmap("../assets/images/button_home.png", home_btn.size());
}
if (!flag_gif && flag_img.isNull()) {
flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size());
}
if (!settings_gif && settings_img.isNull()) {
settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio);
}
}
-82
View File
@@ -1,82 +0,0 @@
#pragma once
#include <memory>
#include <QFrame>
#include <QMap>
#include "selfdrive/ui/ui.h"
#include "selfdrive/ui/qt/network/networking.h"
typedef QPair<QPair<QString, QString>, QColor> ItemStatus;
Q_DECLARE_METATYPE(ItemStatus);
class Sidebar : public QFrame {
Q_OBJECT
Q_PROPERTY(ItemStatus connectStatus MEMBER connect_status NOTIFY valueChanged);
Q_PROPERTY(ItemStatus pandaStatus MEMBER panda_status NOTIFY valueChanged);
Q_PROPERTY(ItemStatus tempStatus MEMBER temp_status NOTIFY valueChanged);
Q_PROPERTY(QString netType MEMBER net_type NOTIFY valueChanged);
Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged);
Q_PROPERTY(bool recordingAudio MEMBER recording_audio NOTIFY valueChanged);
// Additional properties
Q_PROPERTY(ItemStatus chipStatus MEMBER chip_status NOTIFY valueChanged)
Q_PROPERTY(ItemStatus memoryStatus MEMBER memory_status NOTIFY valueChanged)
Q_PROPERTY(ItemStatus storageStatus MEMBER storage_status NOTIFY valueChanged)
public:
explicit Sidebar(QWidget* parent = 0);
signals:
void openSettings(int index = 0, const QString &param = "");
void valueChanged();
public slots:
void offroadTransition(bool offroad);
void updateState(const UIState &s, const StarPilotUIState &fs);
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void drawMetric(QPainter &p, const QPair<QString, QString> &label, QColor c, int y);
QPixmap home_img, flag_img, settings_img, mic_img, link_img;
bool onroad, recording_audio, flag_pressed, settings_pressed, mic_indicator_pressed;
const QMap<cereal::DeviceState::NetworkType, QString> network_type = {
{cereal::DeviceState::NetworkType::NONE, tr("--")},
{cereal::DeviceState::NetworkType::WIFI, tr("Wi-Fi")},
{cereal::DeviceState::NetworkType::ETHERNET, tr("ETH")},
{cereal::DeviceState::NetworkType::CELL2_G, tr("2G")},
{cereal::DeviceState::NetworkType::CELL3_G, tr("3G")},
{cereal::DeviceState::NetworkType::CELL4_G, tr("LTE")},
{cereal::DeviceState::NetworkType::CELL5_G, tr("5G")}
};
const QRect home_btn = QRect(60, 860, 180, 180);
const QRect settings_btn = QRect(50, 35, 200, 117);
const QRect mic_indicator_btn = QRect(158, 252, 75, 40);
const QColor good_color = QColor(255, 255, 255);
const QColor warning_color = QColor(218, 202, 37);
const QColor danger_color = QColor(201, 34, 49);
ItemStatus connect_status, panda_status, temp_status;
QString net_type;
int net_strength = 0;
ItemStatus chip_status, memory_status, storage_status;
private:
std::unique_ptr<PubMaster> pm;
Networking *networking = nullptr;
void showEvent(QShowEvent *event);
void updateTheme();
Params params;
QSharedPointer<QMovie> flag_gif;
QSharedPointer<QMovie> home_gif;
QSharedPointer<QMovie> settings_gif;
};
Binary file not shown.
Binary file not shown.
-248
View File
@@ -1,248 +0,0 @@
#include "selfdrive/ui/qt/util.h"
#include <map>
#include <string>
#include <vector>
#include <QApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QHash>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLayoutItem>
#include <QStyleOption>
#include <QPainterPath>
#include <QStringList>
#include <QTextStream>
#include <QtXml/QDomDocument>
#include "common/swaglog.h"
#include "common/util.h"
#include "system/hardware/hw.h"
QString getVersion() {
static QString version = QString::fromStdString(Params().get("Version"));
return version;
}
QString getBrand() {
return QObject::tr("StarPilot");
}
QString getStarPilotDisplayVersion() {
return "6.7";
}
QString formatStarPilotDisplayVersionDescription(const QString &description) {
if (description.isEmpty()) {
return "";
}
QStringList parts = description.split(" / ");
if (parts.isEmpty()) {
return getStarPilotDisplayVersion();
}
parts[0] = getStarPilotDisplayVersion();
return parts.join(" / ");
}
QString getUserAgent() {
return "openpilot-" + getVersion();
}
std::optional<QString> getDongleId() {
std::string id = Params().get("DongleId");
if (!id.empty() && (id != "UnregisteredDevice")) {
return QString::fromStdString(id);
} else {
return {};
}
}
QMap<QString, QString> getSupportedLanguages() {
QFile f(":/languages.json");
f.open(QIODevice::ReadOnly | QIODevice::Text);
QString val = f.readAll();
QJsonObject obj = QJsonDocument::fromJson(val.toUtf8()).object();
QMap<QString, QString> map;
for (auto key : obj.keys()) {
map[key] = obj[key].toString();
}
return map;
}
QString timeAgo(const QDateTime &date) {
if (!util::system_time_valid()) {
return date.date().toString();
}
int diff = date.secsTo(QDateTime::currentDateTimeUtc());
QString s;
if (diff < 60) {
s = QObject::tr("now");
} else if (diff < 60 * 60) {
int minutes = diff / 60;
s = QObject::tr("%n minute(s) ago", "", minutes);
} else if (diff < 60 * 60 * 24) {
int hours = diff / (60 * 60);
s = QObject::tr("%n hour(s) ago", "", hours);
} else if (diff < 3600 * 24 * 7) {
int days = diff / (60 * 60 * 24);
s = QObject::tr("%n day(s) ago", "", days);
} else {
s = date.date().toString();
}
return s;
}
void setQtSurfaceFormat() {
QSurfaceFormat fmt;
#ifdef __APPLE__
fmt.setVersion(3, 2);
fmt.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
#else
fmt.setRenderableType(QSurfaceFormat::OpenGLES);
#endif
fmt.setSamples(16);
fmt.setStencilBufferSize(1);
QSurfaceFormat::setDefaultFormat(fmt);
}
void sigTermHandler(int s) {
std::signal(s, SIG_DFL);
qApp->quit();
}
void initApp(int argc, char *argv[], bool disable_hidpi) {
Hardware::set_display_power(true);
Hardware::set_brightness(65);
// setup signal handlers to exit gracefully
std::signal(SIGINT, sigTermHandler);
std::signal(SIGTERM, sigTermHandler);
QString app_dir;
#ifdef __APPLE__
// Get the devicePixelRatio, and scale accordingly to maintain 1:1 rendering
QApplication tmp(argc, argv);
app_dir = QCoreApplication::applicationDirPath();
if (disable_hidpi) {
qputenv("QT_SCALE_FACTOR", QString::number(1.0 / tmp.devicePixelRatio()).toLocal8Bit());
}
#else
app_dir = QFileInfo(util::readlink("/proc/self/exe").c_str()).path();
#endif
qputenv("QT_DBL_CLICK_DIST", QByteArray::number(150));
// ensure the current dir matches the exectuable's directory
QDir::setCurrent(app_dir);
setQtSurfaceFormat();
}
void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
static std::map<QtMsgType, int> levels = {
{QtMsgType::QtDebugMsg, CLOUDLOG_DEBUG},
{QtMsgType::QtInfoMsg, CLOUDLOG_INFO},
{QtMsgType::QtWarningMsg, CLOUDLOG_WARNING},
{QtMsgType::QtCriticalMsg, CLOUDLOG_ERROR},
{QtMsgType::QtSystemMsg, CLOUDLOG_ERROR},
{QtMsgType::QtFatalMsg, CLOUDLOG_CRITICAL},
};
std::string file, function;
if (context.file != nullptr) file = context.file;
if (context.function != nullptr) function = context.function;
auto bts = msg.toUtf8();
cloudlog_e(levels[type], file.c_str(), context.line, function.c_str(), "%s", bts.constData());
}
QWidget* topWidget(QWidget* widget) {
while (widget->parentWidget() != nullptr) widget=widget->parentWidget();
return widget;
}
QPixmap loadPixmap(const QString &fileName, const QSize &size, Qt::AspectRatioMode aspectRatioMode) {
if (size.isEmpty()) {
return QPixmap(fileName);
} else {
return QPixmap(fileName).scaled(size, aspectRatioMode, Qt::SmoothTransformation);
}
}
static QHash<QString, QByteArray> load_bootstrap_icons() {
QHash<QString, QByteArray> icons;
QFile f(":/bootstrap-icons.svg");
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
QDomDocument xml;
xml.setContent(&f);
QDomNode n = xml.documentElement().firstChild();
while (!n.isNull()) {
QDomElement e = n.toElement();
if (!e.isNull() && e.hasAttribute("id")) {
QString svg_str;
QTextStream stream(&svg_str);
n.save(stream, 0);
svg_str.replace("<symbol", "<svg");
svg_str.replace("</symbol>", "</svg>");
icons[e.attribute("id")] = svg_str.toUtf8();
}
n = n.nextSibling();
}
}
return icons;
}
QPixmap bootstrapPixmap(const QString &id) {
static QHash<QString, QByteArray> icons = load_bootstrap_icons();
QPixmap pixmap;
if (auto it = icons.find(id); it != icons.end()) {
pixmap.loadFromData(it.value(), "svg");
}
return pixmap;
}
bool hasLongitudinalControl(const cereal::CarParams::Reader &car_params) {
// Using the experimental longitudinal toggle, returns whether longitudinal control
// will be active without needing a restart of openpilot
Params params = Params();
return (car_params.getAlphaLongitudinalAvailable()
? params.getBool("AlphaLongitudinalEnabled")
: car_params.getOpenpilotLongitudinalControl()) && !params.getBool("DisableOpenpilotLongitudinal");
}
// ParamWatcher
ParamWatcher::ParamWatcher(QObject *parent) : QObject(parent) {
watcher = new QFileSystemWatcher(this);
QObject::connect(watcher, &QFileSystemWatcher::fileChanged, this, &ParamWatcher::fileChanged);
}
void ParamWatcher::fileChanged(const QString &path) {
auto param_name = QFileInfo(path).fileName();
auto param_value = QString::fromStdString(params.get(param_name.toStdString()));
auto it = params_hash.find(param_name);
bool content_changed = (it == params_hash.end()) || (it.value() != param_value);
params_hash[param_name] = param_value;
// emit signal when the content changes.
if (content_changed) {
emit paramChanged(param_name, param_value);
}
}
void ParamWatcher::addParam(const QString &param_name) {
watcher->addPath(QString::fromStdString(params.getParamPath(param_name.toStdString())));
}
-56
View File
@@ -1,56 +0,0 @@
#pragma once
#include <optional>
#include <vector>
#include <QDateTime>
#include <QFileSystemWatcher>
#include <QPainter>
#include <QPixmap>
#include <QSurfaceFormat>
#include <QWidget>
#include "cereal/gen/cpp/car.capnp.h"
#include "common/params.h"
QString getVersion();
QString getBrand();
QString getStarPilotDisplayVersion();
QString formatStarPilotDisplayVersionDescription(const QString &description);
QString getUserAgent();
std::optional<QString> getDongleId();
QMap<QString, QString> getSupportedLanguages();
void setQtSurfaceFormat();
void sigTermHandler(int s);
QString timeAgo(const QDateTime &date);
void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
void initApp(int argc, char *argv[], bool disable_hidpi = true);
QWidget* topWidget(QWidget* widget);
QPixmap loadPixmap(const QString &fileName, const QSize &size = {}, Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
QPixmap bootstrapPixmap(const QString &id);
bool hasLongitudinalControl(const cereal::CarParams::Reader &car_params);
struct InterFont : public QFont {
InterFont(int pixel_size, QFont::Weight weight = QFont::Normal) : QFont("Inter") {
setPixelSize(pixel_size);
setWeight(weight);
}
};
class ParamWatcher : public QObject {
Q_OBJECT
public:
ParamWatcher(QObject *parent);
void addParam(const QString &param_name);
signals:
void paramChanged(const QString &param_name, const QString &param_value);
private:
void fileChanged(const QString &path);
QFileSystemWatcher *watcher;
QHash<QString, QString> params_hash;
Params params;
};
-365
View File
@@ -1,365 +0,0 @@
#include "selfdrive/ui/qt/widgets/cameraview.h"
#ifdef __APPLE__
#include <OpenGL/gl3.h>
#else
#include <GLES3/gl3.h>
#endif
#include <cmath>
#include <QApplication>
namespace {
const char frame_vertex_shader[] =
#ifdef __APPLE__
"#version 330 core\n"
#else
"#version 300 es\n"
#endif
"layout(location = 0) in vec4 aPosition;\n"
"layout(location = 1) in vec2 aTexCoord;\n"
"uniform mat4 uTransform;\n"
"out vec2 vTexCoord;\n"
"void main() {\n"
" gl_Position = uTransform * aPosition;\n"
" vTexCoord = aTexCoord;\n"
"}\n";
const char frame_fragment_shader[] =
#ifdef QCOM2
"#version 300 es\n"
"#extension GL_OES_EGL_image_external_essl3 : enable\n"
"precision mediump float;\n"
"uniform samplerExternalOES uTexture;\n"
"in vec2 vTexCoord;\n"
"out vec4 colorOut;\n"
"void main() {\n"
" colorOut = texture(uTexture, vTexCoord);\n"
// gamma to improve worst case visibility when dark
" colorOut.rgb = pow(colorOut.rgb, vec3(1.0/1.28));\n"
"}\n";
#else
#ifdef __APPLE__
"#version 330 core\n"
#else
"#version 300 es\n"
"precision mediump float;\n"
#endif
"uniform sampler2D uTextureY;\n"
"uniform sampler2D uTextureUV;\n"
"in vec2 vTexCoord;\n"
"out vec4 colorOut;\n"
"void main() {\n"
" float y = texture(uTextureY, vTexCoord).r;\n"
" vec2 uv = texture(uTextureUV, vTexCoord).rg - 0.5;\n"
" float r = y + 1.402 * uv.y;\n"
" float g = y - 0.344 * uv.x - 0.714 * uv.y;\n"
" float b = y + 1.772 * uv.x;\n"
" colorOut = vec4(r, g, b, 1.0);\n"
"}\n";
#endif
} // namespace
CameraWidget::CameraWidget(std::string stream_name, VisionStreamType type, QWidget* parent) :
stream_name(stream_name), active_stream_type(type), requested_stream_type(type), QOpenGLWidget(parent) {
setAttribute(Qt::WA_OpaquePaintEvent);
qRegisterMetaType<std::set<VisionStreamType>>("availableStreams");
QObject::connect(this, &CameraWidget::vipcThreadConnected, this, &CameraWidget::vipcConnected, Qt::BlockingQueuedConnection);
QObject::connect(this, &CameraWidget::vipcThreadFrameReceived, this, &CameraWidget::vipcFrameReceived, Qt::QueuedConnection);
QObject::connect(this, &CameraWidget::vipcAvailableStreamsUpdated, this, &CameraWidget::availableStreamsUpdated, Qt::QueuedConnection);
QObject::connect(QApplication::instance(), &QCoreApplication::aboutToQuit, this, &CameraWidget::stopVipcThread);
}
CameraWidget::~CameraWidget() {
makeCurrent();
stopVipcThread();
if (isValid()) {
glDeleteVertexArrays(1, &frame_vao);
glDeleteBuffers(1, &frame_vbo);
glDeleteBuffers(1, &frame_ibo);
#ifndef QCOM2
glDeleteTextures(2, textures);
#endif
}
doneCurrent();
}
// Qt uses device-independent pixels, depending on platform this may be
// different to what OpenGL uses
int CameraWidget::glWidth() {
return width() * devicePixelRatio();
}
int CameraWidget::glHeight() {
return height() * devicePixelRatio();
}
void CameraWidget::initializeGL() {
initializeOpenGLFunctions();
program = std::make_unique<QOpenGLShaderProgram>(context());
bool ret = program->addShaderFromSourceCode(QOpenGLShader::Vertex, frame_vertex_shader);
assert(ret);
ret = program->addShaderFromSourceCode(QOpenGLShader::Fragment, frame_fragment_shader);
assert(ret);
program->link();
GLint frame_pos_loc = program->attributeLocation("aPosition");
GLint frame_texcoord_loc = program->attributeLocation("aTexCoord");
auto [x1, x2, y1, y2] = requested_stream_type == VISION_STREAM_DRIVER ? std::tuple(0.f, 1.f, 1.f, 0.f) : std::tuple(1.f, 0.f, 1.f, 0.f);
const uint8_t frame_indicies[] = {0, 1, 2, 0, 2, 3};
const float frame_coords[4][4] = {
{-1.0, -1.0, x2, y1}, // bl
{-1.0, 1.0, x2, y2}, // tl
{ 1.0, 1.0, x1, y2}, // tr
{ 1.0, -1.0, x1, y1}, // br
};
glGenVertexArrays(1, &frame_vao);
glBindVertexArray(frame_vao);
glGenBuffers(1, &frame_vbo);
glBindBuffer(GL_ARRAY_BUFFER, frame_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(frame_coords), frame_coords, GL_STATIC_DRAW);
glEnableVertexAttribArray(frame_pos_loc);
glVertexAttribPointer(frame_pos_loc, 2, GL_FLOAT, GL_FALSE,
sizeof(frame_coords[0]), (const void *)0);
glEnableVertexAttribArray(frame_texcoord_loc);
glVertexAttribPointer(frame_texcoord_loc, 2, GL_FLOAT, GL_FALSE,
sizeof(frame_coords[0]), (const void *)(sizeof(float) * 2));
glGenBuffers(1, &frame_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, frame_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(frame_indicies), frame_indicies, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(program->programId());
#ifdef QCOM2
glUniform1i(program->uniformLocation("uTexture"), 0);
#else
glGenTextures(2, textures);
glUniform1i(program->uniformLocation("uTextureY"), 0);
glUniform1i(program->uniformLocation("uTextureUV"), 1);
#endif
}
void CameraWidget::showEvent(QShowEvent *event) {
if (!vipc_thread) {
clearFrames();
vipc_thread = new QThread();
connect(vipc_thread, &QThread::started, [=]() { vipcThread(); });
connect(vipc_thread, &QThread::finished, vipc_thread, &QObject::deleteLater);
vipc_thread->start();
}
}
void CameraWidget::stopVipcThread() {
makeCurrent();
if (vipc_thread) {
vipc_thread->requestInterruption();
vipc_thread->quit();
vipc_thread->wait();
vipc_thread = nullptr;
}
#ifdef QCOM2
EGLDisplay egl_display = eglGetCurrentDisplay();
assert(egl_display != EGL_NO_DISPLAY);
for (auto &pair : egl_images) {
eglDestroyImageKHR(egl_display, pair.second);
assert(eglGetError() == EGL_SUCCESS);
}
egl_images.clear();
#endif
}
void CameraWidget::availableStreamsUpdated(std::set<VisionStreamType> streams) {
available_streams = streams;
}
mat4 CameraWidget::calcFrameMatrix() {
// Scale the frame to fit the widget while maintaining the aspect ratio.
float widget_aspect_ratio = (float)width() / height();
float frame_aspect_ratio = (float)stream_width / stream_height;
float zx = std::min(frame_aspect_ratio / widget_aspect_ratio, 1.0f);
float zy = std::min(widget_aspect_ratio / frame_aspect_ratio, 1.0f);
return mat4{{
zx, 0.0, 0.0, 0.0,
0.0, zy, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
}
void CameraWidget::paintGL() {
glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF());
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
std::lock_guard lk(frame_lock);
if (frames.empty()) return;
int frame_idx = frames.size() - 1;
// Always draw latest frame until sync logic is more stable
// for (frame_idx = 0; frame_idx < frames.size() - 1; frame_idx++) {
// if (frames[frame_idx].first == draw_frame_id) break;
// }
// Log duplicate/dropped frames
if (frames[frame_idx].first == prev_frame_id) {
qDebug() << "Drawing same frame twice" << frames[frame_idx].first;
} else if (frames[frame_idx].first != prev_frame_id + 1) {
qDebug() << "Skipped frame" << frames[frame_idx].first;
}
prev_frame_id = frames[frame_idx].first;
VisionBuf *frame = frames[frame_idx].second;
assert(frame != nullptr);
auto frame_mat = calcFrameMatrix();
glViewport(0, 0, glWidth(), glHeight());
glBindVertexArray(frame_vao);
glUseProgram(program->programId());
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
#ifdef QCOM2
// no frame copy
glActiveTexture(GL_TEXTURE0);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_images[frame->idx]);
assert(glGetError() == GL_NO_ERROR);
#else
// fallback to copy
glPixelStorei(GL_UNPACK_ROW_LENGTH, stream_stride);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, stream_width, stream_height, GL_RED, GL_UNSIGNED_BYTE, frame->y);
assert(glGetError() == GL_NO_ERROR);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stream_stride/2);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, stream_width/2, stream_height/2, GL_RG, GL_UNSIGNED_BYTE, frame->uv);
assert(glGetError() == GL_NO_ERROR);
#endif
glUniformMatrix4fv(program->uniformLocation("uTransform"), 1, GL_TRUE, frame_mat.v);
glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void *)0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
void CameraWidget::vipcConnected(VisionIpcClient *vipc_client) {
makeCurrent();
stream_width = vipc_client->buffers[0].width;
stream_height = vipc_client->buffers[0].height;
stream_stride = vipc_client->buffers[0].stride;
#ifdef QCOM2
EGLDisplay egl_display = eglGetCurrentDisplay();
assert(egl_display != EGL_NO_DISPLAY);
for (auto &pair : egl_images) {
eglDestroyImageKHR(egl_display, pair.second);
}
egl_images.clear();
for (int i = 0; i < vipc_client->num_buffers; i++) { // import buffers into OpenGL
int fd = dup(vipc_client->buffers[i].fd); // eglDestroyImageKHR will close, so duplicate
EGLint img_attrs[] = {
EGL_WIDTH, (int)vipc_client->buffers[i].width,
EGL_HEIGHT, (int)vipc_client->buffers[i].height,
EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_NV12,
EGL_DMA_BUF_PLANE0_FD_EXT, fd,
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
EGL_DMA_BUF_PLANE0_PITCH_EXT, (int)vipc_client->buffers[i].stride,
EGL_DMA_BUF_PLANE1_FD_EXT, fd,
EGL_DMA_BUF_PLANE1_OFFSET_EXT, (int)vipc_client->buffers[i].uv_offset,
EGL_DMA_BUF_PLANE1_PITCH_EXT, (int)vipc_client->buffers[i].stride,
EGL_NONE
};
egl_images[i] = eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, 0, img_attrs);
assert(eglGetError() == EGL_SUCCESS);
}
#else
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, stream_width, stream_height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
assert(glGetError() == GL_NO_ERROR);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, stream_width/2, stream_height/2, 0, GL_RG, GL_UNSIGNED_BYTE, nullptr);
assert(glGetError() == GL_NO_ERROR);
#endif
}
void CameraWidget::vipcFrameReceived() {
update();
}
void CameraWidget::vipcThread() {
VisionStreamType cur_stream = requested_stream_type;
std::unique_ptr<VisionIpcClient> vipc_client;
VisionIpcBufExtra meta_main = {0};
while (!QThread::currentThread()->isInterruptionRequested()) {
if (!vipc_client || cur_stream != requested_stream_type) {
clearFrames();
qDebug().nospace() << "connecting to stream " << requested_stream_type << ", was connected to " << cur_stream;
cur_stream = requested_stream_type;
vipc_client.reset(new VisionIpcClient(stream_name, cur_stream, false));
}
active_stream_type = cur_stream;
if (!vipc_client->connected) {
clearFrames();
auto streams = VisionIpcClient::getAvailableStreams(stream_name, false);
if (streams.empty()) {
QThread::msleep(100);
continue;
}
emit vipcAvailableStreamsUpdated(streams);
if (!vipc_client->connect(false)) {
QThread::msleep(100);
continue;
}
emit vipcThreadConnected(vipc_client.get());
}
if (VisionBuf *buf = vipc_client->recv(&meta_main, 1000)) {
{
std::lock_guard lk(frame_lock);
frames.push_back(std::make_pair(meta_main.frame_id, buf));
while (frames.size() > FRAME_BUFFER_SIZE) {
frames.pop_front();
}
}
emit vipcThreadFrameReceived();
} else {
if (!isVisible()) {
vipc_client->connected = false;
}
}
}
}
void CameraWidget::clearFrames() {
std::lock_guard lk(frame_lock);
frames.clear();
available_streams.clear();
}
-89
View File
@@ -1,89 +0,0 @@
#pragma once
#include <deque>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <utility>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLWidget>
#include <QThread>
#ifdef QCOM2
#define EGL_EGLEXT_PROTOTYPES
#define EGL_NO_X11
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <drm/drm_fourcc.h>
#endif
#include "msgq/visionipc/visionipc_client.h"
#include "selfdrive/ui/ui.h"
const int FRAME_BUFFER_SIZE = 5;
class CameraWidget : public QOpenGLWidget, protected QOpenGLFunctions {
Q_OBJECT
public:
using QOpenGLWidget::QOpenGLWidget;
explicit CameraWidget(std::string stream_name, VisionStreamType stream_type, QWidget* parent = nullptr);
~CameraWidget();
void setBackgroundColor(const QColor &color) { bg = color; }
void setFrameId(int frame_id) { draw_frame_id = frame_id; }
void setStreamType(VisionStreamType type) { requested_stream_type = type; }
VisionStreamType getStreamType() { return active_stream_type; }
void stopVipcThread();
signals:
void clicked();
void vipcThreadConnected(VisionIpcClient *);
void vipcThreadFrameReceived();
void vipcAvailableStreamsUpdated(std::set<VisionStreamType>);
protected:
void paintGL() override;
void initializeGL() override;
void showEvent(QShowEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override { emit clicked(); }
virtual mat4 calcFrameMatrix();
void vipcThread();
void clearFrames();
int glWidth();
int glHeight();
GLuint frame_vao, frame_vbo, frame_ibo;
GLuint textures[2];
std::unique_ptr<QOpenGLShaderProgram> program;
QColor bg = QColor("#000000");
#ifdef QCOM2
std::map<int, EGLImageKHR> egl_images;
#endif
std::string stream_name;
int stream_width = 0;
int stream_height = 0;
int stream_stride = 0;
std::atomic<VisionStreamType> active_stream_type;
std::atomic<VisionStreamType> requested_stream_type;
std::set<VisionStreamType> available_streams;
QThread *vipc_thread = nullptr;
std::recursive_mutex frame_lock;
std::deque<std::pair<uint32_t, VisionBuf*>> frames;
uint32_t draw_frame_id = 0;
uint32_t prev_frame_id = 0;
protected slots:
void vipcConnected(VisionIpcClient *vipc_client);
void vipcFrameReceived();
void availableStreamsUpdated(std::set<VisionStreamType> streams);
};
Q_DECLARE_METATYPE(std::set<VisionStreamType>);

Some files were not shown because too many files have changed in this diff Show More