mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-10-01 03:53:41 +08:00
Merge branch 'upstream/openpilot/master' into sync-20260317
# Conflicts: # .github/workflows/auto_pr_review.yaml # .gitignore # opendbc_repo # panda # selfdrive/ui/mici/layouts/home.py # selfdrive/ui/mici/layouts/onboarding.py # selfdrive/ui/mici/layouts/settings/device.py # selfdrive/ui/tests/diff/replay.py # selfdrive/ui/translations/app_fr.po # system/ui/mici_setup.py Sync: `commaai/opendbc:master` → `sunnypilot/opendbc:master` Sync: `commaai/panda:master` → `sunnypilot/panda:master`
This commit is contained in:
+1
-1
@@ -38,7 +38,7 @@ scons -u -j$(nproc)
|
||||
|
||||
Follow [these instructions](https://docs.microsoft.com/en-us/windows/wsl/install) to setup the WSL and install the `Ubuntu-24.04` distribution. Once your Ubuntu WSL environment is setup, follow the Linux setup instructions to finish setting up your environment. See [these instructions](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps) for running GUI apps.
|
||||
|
||||
**NOTE**: If you are running WSL and any GUIs are failing (segfaulting or other strange issues) even after following the steps above, you may need to enable software rendering with `LIBGL_ALWAYS_SOFTWARE=1`, e.g. `LIBGL_ALWAYS_SOFTWARE=1 selfdrive/ui/ui`.
|
||||
**NOTE**: If you are running WSL 2 and experiencing performance issues with the UI or simulator, you may need to explicitly enable hardware acceleration by setting `GALLIUM_DRIVER=d3d12` before commands. Add `export GALLIUM_DRIVER=d3d12` to your `~/.bashrc` file to make it automatic for future sessions.
|
||||
|
||||
## CTF
|
||||
Learn about the openpilot ecosystem and tools by playing our [CTF](/tools/CTF.md).
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
av
|
||||
av-10.0.0/*
|
||||
key.pem
|
||||
cert.pem
|
||||
@@ -1,6 +1,8 @@
|
||||
moc_*
|
||||
*.moc
|
||||
|
||||
assets.cc
|
||||
|
||||
_cabana
|
||||
dbc/car_fingerprint_to_dbc.json
|
||||
tests/test_cabana
|
||||
|
||||
+15
-13
@@ -2,6 +2,8 @@ import subprocess
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import libusb
|
||||
|
||||
Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal')
|
||||
|
||||
# Detect Qt - skip build if not available
|
||||
@@ -64,21 +66,18 @@ qt_env['LIBPATH'] += ['#selfdrive/ui', ]
|
||||
qt_env['LIBS'] = qt_libs
|
||||
|
||||
base_frameworks = qt_env['FRAMEWORKS']
|
||||
base_libs = [common, messaging, cereal, visionipc, 'm', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"]
|
||||
base_libs = [common, messaging, cereal, visionipc, 'm', 'pthread'] + qt_env["LIBS"]
|
||||
|
||||
if arch == "Darwin":
|
||||
base_frameworks.append('QtCharts')
|
||||
else:
|
||||
base_libs.append('Qt5Charts')
|
||||
|
||||
qt_libs = base_libs
|
||||
|
||||
cabana_env = qt_env.Clone()
|
||||
if arch == "Darwin":
|
||||
cabana_env['CPPPATH'] += [f"{brew_prefix}/include"]
|
||||
cabana_env['LIBPATH'] += [f"{brew_prefix}/lib"]
|
||||
cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR]
|
||||
cabana_env['LIBPATH'] += [libusb.LIB_DIR]
|
||||
|
||||
cabana_libs = [cereal, messaging, visionipc, replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'usb-1.0'] + qt_libs
|
||||
cabana_libs = [cereal, messaging, visionipc, replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs
|
||||
opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../opendbc/dbc").abspath)
|
||||
cabana_env['CXXFLAGS'] += [opendbc_path]
|
||||
|
||||
@@ -88,12 +87,15 @@ assets_src = "assets/assets.qrc"
|
||||
cabana_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET")
|
||||
cabana_env.Depends(assets, Glob('/assets/*', exclude=[assets, assets_src, "assets/assets.o"]))
|
||||
|
||||
cabana_lib = cabana_env.Library("cabana_lib", ['mainwin.cc', 'streams/socketcanstream.cc', 'streams/pandastream.cc', 'streams/devicestream.cc', 'streams/livestream.cc', 'streams/abstractstream.cc', 'streams/replaystream.cc', 'binaryview.cc', 'historylog.cc', 'videowidget.cc', 'signalview.cc',
|
||||
'streams/routes.cc', 'dbc/dbc.cc', 'dbc/dbcfile.cc', 'dbc/dbcmanager.cc',
|
||||
'utils/export.cc', 'utils/util.cc', 'utils/elidedlabel.cc',
|
||||
'chart/chartswidget.cc', 'chart/chart.cc', 'chart/signalselector.cc', 'chart/tiplabel.cc', 'chart/sparkline.cc',
|
||||
'commands.cc', 'messageswidget.cc', 'streamselector.cc', 'settings.cc', 'panda.cc',
|
||||
'cameraview.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc', 'tools/findsignal.cc', 'tools/routeinfo.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
cabana_srcs = ['mainwin.cc', 'streams/pandastream.cc', 'streams/devicestream.cc', 'streams/livestream.cc', 'streams/abstractstream.cc', 'streams/replaystream.cc', 'binaryview.cc', 'historylog.cc', 'videowidget.cc', 'signalview.cc',
|
||||
'streams/routes.cc', 'dbc/dbc.cc', 'dbc/dbcfile.cc', 'dbc/dbcmanager.cc',
|
||||
'utils/export.cc', 'utils/util.cc', 'utils/elidedlabel.cc',
|
||||
'chart/chartswidget.cc', 'chart/chart.cc', 'chart/signalselector.cc', 'chart/tiplabel.cc', 'chart/sparkline.cc',
|
||||
'commands.cc', 'messageswidget.cc', 'streamselector.cc', 'settings.cc', 'panda.cc',
|
||||
'cameraview.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc', 'tools/findsignal.cc', 'tools/routeinfo.cc']
|
||||
if arch != "Darwin":
|
||||
cabana_srcs += ['streams/socketcanstream.cc']
|
||||
cabana_lib = cabana_env.Library("cabana_lib", cabana_srcs, LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
cabana_env.Program('_cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_libs, FRAMEWORKS=base_frameworks)
|
||||
|
||||
if GetOption('extras'):
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*.cc
|
||||
@@ -5,7 +5,9 @@
|
||||
#include "tools/cabana/streams/devicestream.h"
|
||||
#include "tools/cabana/streams/pandastream.h"
|
||||
#include "tools/cabana/streams/replaystream.h"
|
||||
#ifdef __linux__
|
||||
#include "tools/cabana/streams/socketcanstream.h"
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QCoreApplication::setApplicationName("Cabana");
|
||||
@@ -29,9 +31,11 @@ int main(int argc, char *argv[]) {
|
||||
cmd_parser.addOption({"msgq", "read can messages from the msgq"});
|
||||
cmd_parser.addOption({"panda", "read can messages from panda"});
|
||||
cmd_parser.addOption({"panda-serial", "read can messages from panda with given serial", "panda-serial"});
|
||||
#ifdef __linux__
|
||||
if (SocketCanStream::available()) {
|
||||
cmd_parser.addOption({"socketcan", "read can messages from given SocketCAN device", "socketcan"});
|
||||
}
|
||||
#endif
|
||||
cmd_parser.addOption({"zmq", "read can messages from zmq at the specified ip-address", "ip-address"});
|
||||
cmd_parser.addOption({"data_dir", "local directory with routes", "data_dir"});
|
||||
cmd_parser.addOption({"no-vipc", "do not output video"});
|
||||
@@ -51,8 +55,10 @@ int main(int argc, char *argv[]) {
|
||||
qWarning() << e.what();
|
||||
return 0;
|
||||
}
|
||||
#ifdef __linux__
|
||||
} else if (SocketCanStream::available() && cmd_parser.isSet("socketcan")) {
|
||||
stream = new SocketCanStream(&app, {.device = cmd_parser.value("socketcan").toStdString()});
|
||||
#endif
|
||||
} else {
|
||||
uint32_t replay_flags = REPLAY_FLAG_NONE;
|
||||
if (cmd_parser.isSet("ecam")) replay_flags |= REPLAY_FLAG_ECAM;
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "streams/socketcanstream.h"
|
||||
#include "tools/cabana/streams/devicestream.h"
|
||||
#include "tools/cabana/streams/pandastream.h"
|
||||
#include "tools/cabana/streams/replaystream.h"
|
||||
#ifdef __linux__
|
||||
#include "tools/cabana/streams/socketcanstream.h"
|
||||
#endif
|
||||
|
||||
StreamSelector::StreamSelector(QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle(tr("Open stream"));
|
||||
@@ -35,9 +36,11 @@ StreamSelector::StreamSelector(QWidget *parent) : QDialog(parent) {
|
||||
|
||||
addStreamWidget(new OpenReplayWidget, tr("&Replay"));
|
||||
addStreamWidget(new OpenPandaWidget, tr("&Panda"));
|
||||
#ifdef __linux__
|
||||
if (SocketCanStream::available()) {
|
||||
addStreamWidget(new OpenSocketCanWidget, tr("&SocketCAN"));
|
||||
}
|
||||
#endif
|
||||
addStreamWidget(new OpenDeviceWidget, tr("&Device"));
|
||||
|
||||
QObject::connect(btn_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
+8
-5
@@ -63,8 +63,10 @@ def parse_args():
|
||||
return args
|
||||
|
||||
|
||||
def setup_env(output_path: str, big: bool = False, speed: int = 1, target_mb: float = 0, duration: int = 0):
|
||||
os.environ.update({"RECORD": "1", "OFFSCREEN": "1", "RECORD_OUTPUT": str(Path(output_path).with_suffix(".mp4"))})
|
||||
def setup_env(output_path: str, big: bool = False, speed: int = 1, target_mb: float = 0, duration: int = 0, headless: bool = True):
|
||||
os.environ.update({"RECORD": "1", "RECORD_OUTPUT": str(Path(output_path).with_suffix(".mp4"))})
|
||||
if headless:
|
||||
os.environ["OFFSCREEN"] = "1"
|
||||
if speed > 1:
|
||||
os.environ["RECORD_SPEED"] = str(speed)
|
||||
if target_mb > 0 and duration > 0:
|
||||
@@ -302,11 +304,11 @@ def clip(route: Route, output: str, start: int, end: int, headless: bool = True,
|
||||
logger.error("No messages to render")
|
||||
sys.exit(1)
|
||||
|
||||
metadata = load_route_metadata(route) if show_metadata else None
|
||||
if headless:
|
||||
rl.set_config_flags(rl.ConfigFlags.FLAG_WINDOW_HIDDEN)
|
||||
|
||||
with OpenpilotPrefix(shared_download_cache=True):
|
||||
metadata = load_route_metadata(route) if show_metadata else None
|
||||
camera_paths = route.qcamera_paths() if use_qcam else route.camera_paths()
|
||||
frame_queue = FrameQueue(camera_paths, start, end, fps=FRAMERATE, use_qcam=use_qcam)
|
||||
|
||||
@@ -349,8 +351,9 @@ def main():
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s\t%(message)s")
|
||||
args = parse_args()
|
||||
|
||||
setup_env(args.output, big=args.big, speed=args.speed, target_mb=args.file_size, duration=args.end - args.start)
|
||||
clip(Route(args.route, data_dir=args.data_dir), args.output, args.start, args.end, not args.windowed,
|
||||
headless = not args.windowed
|
||||
setup_env(args.output, big=args.big, speed=args.speed, target_mb=args.file_size, duration=args.end - args.start, headless=headless)
|
||||
clip(Route(args.route, data_dir=args.data_dir), args.output, args.start, args.end, headless,
|
||||
args.big, args.title, not args.no_metadata, not args.no_time_overlay, args.qcam)
|
||||
|
||||
|
||||
|
||||
+1
-26
@@ -167,29 +167,6 @@ function op_check_os() {
|
||||
fi
|
||||
}
|
||||
|
||||
function op_check_python() {
|
||||
echo "Checking for compatible python version..."
|
||||
REQUIRED_PYTHON_VERSION=$(grep "requires-python" $OPENPILOT_ROOT/pyproject.toml)
|
||||
INSTALLED_PYTHON_VERSION=$(python3 --version 2> /dev/null || true)
|
||||
|
||||
if [[ -z $INSTALLED_PYTHON_VERSION ]]; then
|
||||
echo -e " ↳ [${RED}✗${NC}] python3 not found on your system. You need python version satisfying $(echo $REQUIRED_PYTHON_VERSION | cut -d '=' -f2-) to continue!"
|
||||
loge "ERROR_PYTHON_NOT_FOUND"
|
||||
return 1
|
||||
else
|
||||
LB=$(echo $REQUIRED_PYTHON_VERSION | tr -d '",' | awk '{ split($4, v, "."); printf "%d%02d%02d", v[1], v[2], v[3] }')
|
||||
UB=$(echo $REQUIRED_PYTHON_VERSION | tr -d '",' | awk '{ split($6, v, "."); printf "%d%02d%02d", v[1], v[2], v[3] }')
|
||||
VERSION=$(echo $INSTALLED_PYTHON_VERSION | awk '{ split($2, v, "."); printf "%d%02d%02d", v[1], v[2], v[3] }')
|
||||
if [[ $VERSION -ge LB && $VERSION -lt UB ]]; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] $INSTALLED_PYTHON_VERSION detected."
|
||||
else
|
||||
echo -e " ↳ [${RED}✗${NC}] You need a python version satisfying $(echo $REQUIRED_PYTHON_VERSION | cut -d '=' -f2-) to continue!"
|
||||
loge "ERROR_PYTHON_VERSION" "$INSTALLED_PYTHON_VERSION"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function op_check_venv() {
|
||||
echo "Checking for venv..."
|
||||
if [[ -f $OPENPILOT_ROOT/.venv/bin/activate ]]; then
|
||||
@@ -214,8 +191,6 @@ function op_before_cmd() {
|
||||
|
||||
op_activate_venv
|
||||
|
||||
result="${result}\n$(( op_check_python ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
|
||||
if [[ -z $VERBOSE ]]; then
|
||||
echo -e "${BOLD}Checking system →${NC} [${GREEN}✔${NC}]"
|
||||
else
|
||||
@@ -436,7 +411,7 @@ function op_default() {
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Commands [System]:${NC}"
|
||||
echo -e " ${BOLD}auth${NC} Authenticate yourself for API use"
|
||||
echo -e " ${BOLD}check${NC} Check the development environment (git, os, python) to start using openpilot"
|
||||
echo -e " ${BOLD}check${NC} Check the development environment (git, os) to start using openpilot"
|
||||
echo -e " ${BOLD}esim${NC} Manage eSIM profiles on your comma device"
|
||||
echo -e " ${BOLD}venv${NC} Activate the python virtual environment"
|
||||
echo -e " ${BOLD}setup${NC} Install openpilot dependencies"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
bin/
|
||||
bin
|
||||
*.rlog
|
||||
@@ -1,5 +1,2 @@
|
||||
moc_*
|
||||
*.moc
|
||||
|
||||
replay
|
||||
tests/test_replay
|
||||
|
||||
@@ -4,7 +4,7 @@ replay_env = env.Clone()
|
||||
replay_env['CCFLAGS'] += ['-Wno-deprecated-declarations']
|
||||
|
||||
base_frameworks = []
|
||||
base_libs = [common, messaging, cereal, visionipc, 'm', 'ssl', 'crypto', 'pthread']
|
||||
base_libs = [common, messaging, cereal, visionipc, 'm', 'pthread']
|
||||
|
||||
replay_lib_src = ["replay.cc", "consoleui.cc", "camera.cc", "filereader.cc", "logreader.cc", "framereader.cc",
|
||||
"route.cc", "util.cc", "seg_mgr.cc", "timeline.cc", "py_downloader.cc"]
|
||||
|
||||
+4
-4
@@ -218,7 +218,7 @@ def ui_thread(addr):
|
||||
# Update camera texture from numpy array
|
||||
img_rgba = cv2.cvtColor(img, cv2.COLOR_RGB2RGBA)
|
||||
rl.update_texture(camera_texture, rl.ffi.cast("void *", img_rgba.ctypes.data))
|
||||
rl.draw_texture(camera_texture, 0, 0, rl.WHITE)
|
||||
rl.draw_texture(camera_texture, 0, 0, rl.WHITE) # noqa: TID251
|
||||
|
||||
# display alerts
|
||||
rl.draw_text_ex(font, sm['selfdriveState'].alertText1, rl.Vector2(180, 150), 30, 0, rl.RED)
|
||||
@@ -227,15 +227,15 @@ def ui_thread(addr):
|
||||
# draw plots (texture is reused internally)
|
||||
plot_texture = draw_plots(plot_arr)
|
||||
if hor_mode:
|
||||
rl.draw_texture(plot_texture, 640 + 384, 0, rl.WHITE)
|
||||
rl.draw_texture(plot_texture, 640 + 384, 0, rl.WHITE) # noqa: TID251
|
||||
else:
|
||||
rl.draw_texture(plot_texture, 0, 600, rl.WHITE)
|
||||
rl.draw_texture(plot_texture, 0, 600, rl.WHITE) # noqa: TID251
|
||||
|
||||
# Convert lid_overlay to RGBA and update top_down texture
|
||||
# lid_overlay is (384, 960), need to transpose to (960, 384) for row-major RGBA buffer
|
||||
lid_rgba = palette[lid_overlay.T]
|
||||
rl.update_texture(top_down_texture, rl.ffi.cast("void *", np.ascontiguousarray(lid_rgba).ctypes.data))
|
||||
rl.draw_texture(top_down_texture, 640, 0, rl.WHITE)
|
||||
rl.draw_texture(top_down_texture, 640, 0, rl.WHITE) # noqa: TID251
|
||||
|
||||
SPACING = 25
|
||||
lines = [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "tools/replay/util.h"
|
||||
|
||||
#include <bzlib.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
@@ -162,15 +161,6 @@ void precise_nano_sleep(int64_t nanoseconds, std::atomic<bool> &interrupt_reques
|
||||
}
|
||||
}
|
||||
|
||||
std::string sha256(const std::string &str) {
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_CTX sha256;
|
||||
SHA256_Init(&sha256);
|
||||
SHA256_Update(&sha256, str.c_str(), str.size());
|
||||
SHA256_Final(hash, &sha256);
|
||||
return util::hexdump(hash, SHA256_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
std::vector<std::string> split(std::string_view source, char delimiter) {
|
||||
std::vector<std::string> fields;
|
||||
size_t last = 0;
|
||||
|
||||
@@ -46,7 +46,6 @@ private:
|
||||
static constexpr float growth_factor = 1.5;
|
||||
};
|
||||
|
||||
std::string sha256(const std::string &str);
|
||||
void precise_nano_sleep(int64_t nanoseconds, std::atomic<bool> &interrupt_requested);
|
||||
std::string decompressBZ2(const std::string &in, std::atomic<bool> *abort = nullptr);
|
||||
std::string decompressBZ2(const std::byte *in, size_t in_size, std::atomic<bool> *abort = nullptr);
|
||||
|
||||
@@ -31,8 +31,12 @@ for name, port in sorted(ports):
|
||||
PY
|
||||
)
|
||||
|
||||
# Forward SSH port first for interactive shell access.
|
||||
adb forward tcp:2222 tcp:22
|
||||
# Forward SSH port, finding a free local port if 2222 is taken.
|
||||
SSH_PORT=2222
|
||||
while ss -tln | grep -q ":${SSH_PORT} "; do
|
||||
SSH_PORT=$((SSH_PORT + 1))
|
||||
done
|
||||
adb forward tcp:${SSH_PORT} tcp:22
|
||||
|
||||
# SSH!
|
||||
ssh comma@localhost -p 2222 "$@"
|
||||
ssh comma@localhost -p ${SSH_PORT} "$@"
|
||||
|
||||
@@ -113,24 +113,12 @@ function install_python_deps() {
|
||||
source .venv/bin/activate
|
||||
}
|
||||
|
||||
function install_macos_deps() {
|
||||
if ! command -v brew > /dev/null 2>&1; then
|
||||
echo "homebrew not found, skipping macOS system dependency install"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! command -v cmake > /dev/null 2>&1; then
|
||||
brew install cmake
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Main ---
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
install_ubuntu_deps
|
||||
echo "[ ] installed system dependencies t=$SECONDS"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
install_macos_deps
|
||||
if [[ $SHELL == "/bin/zsh" ]]; then
|
||||
RC_FILE="$HOME/.zshrc"
|
||||
elif [[ $SHELL == "/bin/bash" ]]; then
|
||||
|
||||
@@ -13,11 +13,9 @@ class CopyRamRGBCamera(RGBCamera):
|
||||
|
||||
def get_rgb_array_cpu(self):
|
||||
origin_img = self.cpu_texture
|
||||
img = np.frombuffer(origin_img.getRamImage().getData(), dtype=np.uint8)
|
||||
img = img.reshape((origin_img.getYSize(), origin_img.getXSize(), -1))
|
||||
img = img[:,:,:3] # RGBA to RGB
|
||||
# img = np.swapaxes(img, 1, 0)
|
||||
img = img[::-1] # Flip on vertical axis
|
||||
img = np.frombuffer(origin_img.getRamImageAs("RGB").getData(), dtype=np.uint8)
|
||||
img = img.reshape((origin_img.getYSize(), origin_img.getXSize(), 3))
|
||||
img = img[::-1] # Flip on vertical axis
|
||||
return img
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user