Merge remote-tracking branch 'upstream/master' into zstd-uploader

pull/32736/head
Shane Smiskol 12 months ago
commit 4c184af547
  1. 11
      pyproject.toml
  2. 3
      selfdrive/debug/run_process_on_route.py
  3. 3
      selfdrive/test/process_replay/model_replay.py
  4. 3
      selfdrive/test/process_replay/regen.py
  5. 3
      selfdrive/test/process_replay/test_processes.py
  6. 13
      tools/latencylogger/latency_logger.py
  7. 16
      tools/lib/helpers.py
  8. 12
      tools/lib/logreader.py
  9. 147
      tools/op.sh
  10. 3
      tools/plotjuggler/juggle.py
  11. 4
      tools/setup.sh
  12. 1
      tools/webcam/camera.py
  13. 208
      uv.lock

@ -60,13 +60,14 @@ dependencies = [
"psutil", "psutil",
"pycryptodome", # used in updated/casync, panda, body, and a test "pycryptodome", # used in updated/casync, panda, body, and a test
#logreader # logreader
"zstd", "zstd",
] ]
[project.optional-dependencies] [project.optional-dependencies]
docs = [ docs = [
"Jinja2", "Jinja2",
"natsort",
"mkdocs==1.4.3", # needed for mkdocs-plugin-commonmark "mkdocs==1.4.3", # needed for mkdocs-plugin-commonmark
"mkdocs-terminal", "mkdocs-terminal",
"mkdocs-plugin-commonmark", "mkdocs-plugin-commonmark",
@ -95,7 +96,6 @@ dev = [
"av", "av",
"azure-identity", "azure-identity",
"azure-storage-blob", "azure-storage-blob",
"breathe",
"control", "control",
"dictdiffer", "dictdiffer",
"flaky", "flaky",
@ -103,12 +103,8 @@ dev = [
"lru-dict", "lru-dict",
"matplotlib", "matplotlib",
"metadrive-simulator@git+https://github.com/commaai/metadrive@opencv_headless ; platform_machine != 'aarch64'", "metadrive-simulator@git+https://github.com/commaai/metadrive@opencv_headless ; platform_machine != 'aarch64'",
"mpld3",
"myst-parser",
"natsort",
"opencv-python-headless",
"parameterized >=0.8, <0.9", "parameterized >=0.8, <0.9",
#pprofile = "*" #"pprofile",
"pyautogui", "pyautogui",
"pyopencl; platform_machine != 'aarch64'", # broken on arm64 "pyopencl; platform_machine != 'aarch64'", # broken on arm64
"pytools < 2024.1.11; platform_machine != 'aarch64'", # pyopencl use a broken version "pytools < 2024.1.11; platform_machine != 'aarch64'", # pyopencl use a broken version
@ -122,7 +118,6 @@ dev = [
# this is only pinned since 5.15.11 is broken # this is only pinned since 5.15.11 is broken
"pyqt5 ==5.15.2; platform_machine == 'x86_64'", # no aarch64 wheels for macOS/linux "pyqt5 ==5.15.2; platform_machine == 'x86_64'", # no aarch64 wheels for macOS/linux
] ]
[project.urls] [project.urls]

@ -3,8 +3,7 @@
import argparse import argparse
from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, replay_process from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, replay_process
from openpilot.tools.lib.helpers import save_log from openpilot.tools.lib.logreader import LogReader, save_log
from openpilot.tools.lib.logreader import LogReader
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Run process on route and create new logs", parser = argparse.ArgumentParser(description="Run process on route and create new logs",

@ -10,8 +10,7 @@ from openpilot.tools.lib.openpilotci import BASE_URL, get_url
from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff
from openpilot.selfdrive.test.process_replay.process_replay import get_process_config, replay_process from openpilot.selfdrive.test.process_replay.process_replay import get_process_config, replay_process
from openpilot.tools.lib.framereader import FrameReader from openpilot.tools.lib.framereader import FrameReader
from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.logreader import LogReader, save_log
from openpilot.tools.lib.helpers import save_log
TEST_ROUTE = "2f4452b03ccb98f0|2022-12-03--13-45-30" TEST_ROUTE = "2f4452b03ccb98f0|2022-12-03--13-45-30"
SEGMENT = 6 SEGMENT = 6

@ -14,8 +14,7 @@ from openpilot.selfdrive.test.process_replay.vision_meta import DRIVER_CAMERA_FR
from openpilot.selfdrive.test.update_ci_routes import upload_route from openpilot.selfdrive.test.update_ci_routes import upload_route
from openpilot.tools.lib.route import Route from openpilot.tools.lib.route import Route
from openpilot.tools.lib.framereader import FrameReader, BaseFrameReader, FrameType from openpilot.tools.lib.framereader import FrameReader, BaseFrameReader, FrameType
from openpilot.tools.lib.logreader import LogReader, LogIterable from openpilot.tools.lib.logreader import LogReader, LogIterable, save_log
from openpilot.tools.lib.helpers import save_log
class DummyFrameReader(BaseFrameReader): class DummyFrameReader(BaseFrameReader):

@ -14,8 +14,7 @@ from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, f
from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, replay_process, \ from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, replay_process, \
check_openpilot_enabled, check_most_messages_valid check_openpilot_enabled, check_most_messages_valid
from openpilot.tools.lib.filereader import FileReader from openpilot.tools.lib.filereader import FileReader
from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.logreader import LogReader, save_log
from openpilot.tools.lib.helpers import save_log
source_segments = [ source_segments = [
("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.COMMA_BODY ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.COMMA_BODY

@ -3,7 +3,6 @@ import argparse
import json import json
import matplotlib.patches as mpatches import matplotlib.patches as mpatches
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import mpld3
import sys import sys
from bisect import bisect_left, bisect_right from bisect import bisect_left, bisect_right
from collections import defaultdict from collections import defaultdict
@ -174,7 +173,6 @@ def print_timestamps(timestamps, durations, start_times, relative):
print(" "+'%-53s%-53s' %(event, str(time*1000))) print(" "+'%-53s%-53s' %(event, str(time*1000)))
def graph_timestamps(timestamps, start_times, end_times, relative, offset_services=False, title=""): def graph_timestamps(timestamps, start_times, end_times, relative, offset_services=False, title=""):
# mpld3 doesn't convert properly to D3 font sizes
plt.rcParams.update({'font.size': 18}) plt.rcParams.update({'font.size': 18})
t0 = find_t0(start_times) t0 = find_t0(start_times)
@ -203,15 +201,14 @@ def graph_timestamps(timestamps, start_times, end_times, relative, offset_servic
points['labels'].append(event[0]) points['labels'].append(event[0])
ax.broken_barh(service_bars, (i-height/2, height), facecolors=(colors), alpha=0.5, offsets=offsets) ax.broken_barh(service_bars, (i-height/2, height), facecolors=(colors), alpha=0.5, offsets=offsets)
scatter = ax.scatter(points['x'], points['y'], marker='d', edgecolor='black') ax.scatter(points['x'], points['y'], marker='d', edgecolor='black')
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=points['labels']) for i, label in enumerate(points['labels']):
mpld3.plugins.connect(fig, tooltip) ax.annotate(label, (points['x'][i], points['y'][i]), textcoords="offset points", xytext=(0,10), ha='center')
plt.title(title) plt.title(title)
# Set size relative window size is not trivial: https://github.com/mpld3/mpld3/issues/65
fig.set_size_inches(18, 9) fig.set_size_inches(18, 9)
plt.legend(handles=[mpatches.Patch(color=colors[i], label=SERVICES[i]) for i in range(len(SERVICES))]) plt.legend(handles=[mpatches.Patch(color=colors[i], label=SERVICES[i]) for i in range(len(SERVICES))])
return fig plt.show()
def get_timestamps(lr): def get_timestamps(lr):
lr = list(lr) lr = list(lr)
@ -239,4 +236,4 @@ if __name__ == "__main__":
data, _ = get_timestamps(lr) data, _ = get_timestamps(lr)
print_timestamps(data['timestamp'], data['duration'], data['start'], args.relative) print_timestamps(data['timestamp'], data['duration'], data['start'], args.relative)
if args.plot: if args.plot:
mpld3.show(graph_timestamps(data['timestamp'], data['start'], data['end'], args.relative, offset_services=args.offset, title=r)) graph_timestamps(data['timestamp'], data['start'], data['end'], args.relative, offset_services=args.offset, title=r)

@ -1,7 +1,3 @@
import bz2
import zstd
# regex patterns # regex patterns
class RE: class RE:
DONGLE_ID = r'(?P<dongle_id>[a-f0-9]{16})' DONGLE_ID = r'(?P<dongle_id>[a-f0-9]{16})'
@ -19,15 +15,3 @@ class RE:
EXPLORER_FILE = fr'^(?P<segment_name>{SEGMENT_NAME})--(?P<file_name>[a-z]+\.[a-z0-9]+)$' EXPLORER_FILE = fr'^(?P<segment_name>{SEGMENT_NAME})--(?P<file_name>[a-z]+\.[a-z0-9]+)$'
OP_SEGMENT_DIR = fr'^(?P<segment_name>{SEGMENT_NAME})$' OP_SEGMENT_DIR = fr'^(?P<segment_name>{SEGMENT_NAME})$'
def save_log(dest, log_msgs, compress=True):
dat = b"".join(msg.as_builder().to_bytes() for msg in log_msgs)
if compress and dest.endswith(".bz2"):
dat = bz2.compress(dat)
elif compress and dest.endswith(".zst"):
dat = zstd.compress(dat, 10)
with open(dest, "wb") as f:
f.write(dat)

@ -27,6 +27,18 @@ LogIterable = Iterable[LogMessage]
RawLogIterable = Iterable[bytes] RawLogIterable = Iterable[bytes]
def save_log(dest, log_msgs, compress=True):
dat = b"".join(msg.as_builder().to_bytes() for msg in log_msgs)
if compress and dest.endswith(".bz2"):
dat = bz2.compress(dat)
elif compress and dest.endswith(".zst"):
dat = zstd.compress(dat, 10)
with open(dest, "wb") as f:
f.write(dat)
class _LogFileReader: class _LogFileReader:
def __init__(self, fn, canonicalize=True, only_union_types=False, sort_by_time=False, dat=None): def __init__(self, fn, canonicalize=True, only_union_types=False, sort_by_time=False, dat=None):
self.data_version = None self.data_version = None

@ -6,7 +6,7 @@ UNDERLINE='\033[4m'
BOLD='\033[1m' BOLD='\033[1m'
NC='\033[0m' NC='\033[0m'
function op_first_install() { function op_install() {
(set -e (set -e
echo "Installing op system-wide..." echo "Installing op system-wide..."
@ -30,16 +30,22 @@ function op_run_command() {
# be default, assume openpilot dir is in current directory # be default, assume openpilot dir is in current directory
OPENPILOT_ROOT=$(pwd) OPENPILOT_ROOT=$(pwd)
function op_check_openpilot_dir() { function op_get_openpilot_dir() {
echo "Checking for openpilot directory..."
while [[ "$OPENPILOT_ROOT" != '/' ]]; while [[ "$OPENPILOT_ROOT" != '/' ]];
do do
if find "$OPENPILOT_ROOT/launch_openpilot.sh" -maxdepth 1 -mindepth 1 &> /dev/null; then if find "$OPENPILOT_ROOT/launch_openpilot.sh" -maxdepth 1 -mindepth 1 &> /dev/null; then
echo -e " ↳ [${GREEN}${NC}] openpilot found.\n"
return 0 return 0
fi fi
OPENPILOT_ROOT="$(readlink -f "$OPENPILOT_ROOT/"..)" OPENPILOT_ROOT="$(readlink -f "$OPENPILOT_ROOT/"..)"
done done
}
function op_check_openpilot_dir() {
echo "Checking for openpilot directory..."
if [[ -f "$OPENPILOT_ROOT/launch_openpilot.sh" ]]; then
echo -e " ↳ [${GREEN}${NC}] openpilot found.\n"
return 0
fi
echo -e " ↳ [${RED}${NC}] openpilot directory not found! Make sure that you are" echo -e " ↳ [${RED}${NC}] openpilot directory not found! Make sure that you are"
echo " inside the openpilot directory or specify one with the" echo " inside the openpilot directory or specify one with the"
@ -52,28 +58,28 @@ function op_check_git() {
echo "Checking for git..." echo "Checking for git..."
if ! command -v "git" > /dev/null 2>&1; then if ! command -v "git" > /dev/null 2>&1; then
echo -e " ↳ [${RED}${NC}] git not found on your system!\n" echo -e " ↳ [${RED}${NC}] git not found on your system!"
return 1 return 1
else else
echo -e " ↳ [${GREEN}${NC}] git found.\n" echo -e " ↳ [${GREEN}${NC}] git found."
fi fi
echo "Checking for git lfs files..." echo "Checking for git lfs files..."
if [[ $(file -b $OPENPILOT_ROOT/selfdrive/modeld/models/supercombo.onnx) == "ASCII text" ]]; then if [[ $(file -b $OPENPILOT_ROOT/selfdrive/modeld/models/supercombo.onnx) == "data" ]]; then
echo -e " ↳ [${RED}${NC}] git lfs files not found! Run 'git lfs pull'\n" echo -e " ↳ [${GREEN}${NC}] git lfs files found."
return 1
else else
echo -e " ↳ [${GREEN}${NC}] git lfs files found.\n" echo -e " ↳ [${RED}${NC}] git lfs files not found! Run 'git lfs pull'"
return 1
fi fi
echo "Checking for git submodules..." echo "Checking for git submodules..."
for name in body msgq_repo opendbc panda rednose_repo tinygrad_repo; do for name in body msgq_repo opendbc panda rednose_repo tinygrad_repo; do
if [[ -z $(ls $OPENPILOT_ROOT/$name) ]]; then if [[ -z $(ls $OPENPILOT_ROOT/$name) ]]; then
echo -e " ↳ [${RED}${NC}] git submodule $name not found! Run 'git submodule update --init --recursive'\n" echo -e " ↳ [${RED}${NC}] git submodule $name not found! Run 'git submodule update --init --recursive'"
return 1 return 1
fi fi
done done
echo -e " ↳ [${GREEN}${NC}] git submodules found.\n" echo -e " ↳ [${GREEN}${NC}] git submodules found."
) )
} }
@ -88,22 +94,22 @@ function op_check_os() {
source /etc/os-release source /etc/os-release
case "$VERSION_CODENAME" in case "$VERSION_CODENAME" in
"jammy" | "kinetic" | "noble" | "focal") "jammy" | "kinetic" | "noble" | "focal")
echo -e " ↳ [${GREEN}${NC}] Ubuntu $VERSION_CODENAME detected.\n" echo -e " ↳ [${GREEN}${NC}] Ubuntu $VERSION_CODENAME detected."
;; ;;
* ) * )
echo -e " ↳ [${RED}${NC}] Incompatible Ubuntu version $VERSION_CODENAME detected!\n" echo -e " ↳ [${RED}${NC}] Incompatible Ubuntu version $VERSION_CODENAME detected!"
return 1 return 1
;; ;;
esac esac
else else
echo -e " ↳ [${RED}${NC}] No /etc/os-release on your system. Make sure you're running on Ubuntu, or similar!\n" echo -e " ↳ [${RED}${NC}] No /etc/os-release on your system. Make sure you're running on Ubuntu, or similar!"
return 1 return 1
fi fi
elif [[ "$OSTYPE" == "darwin"* ]]; then elif [[ "$OSTYPE" == "darwin"* ]]; then
echo -e " ↳ [${GREEN}${NC}] macos detected.\n" echo -e " ↳ [${GREEN}${NC}] macos detected.\n"
else else
echo -e " ↳ [${RED}${NC}] OS type $OSTYPE not supported!\n" echo -e " ↳ [${RED}${NC}] OS type $OSTYPE not supported!"
return 1 return 1
fi fi
@ -118,12 +124,12 @@ function op_check_python() {
INSTALLED_PYTHON_VERSION=$(python3 --version 2> /dev/null || true) INSTALLED_PYTHON_VERSION=$(python3 --version 2> /dev/null || true)
if [[ -z $INSTALLED_PYTHON_VERSION ]]; then if [[ -z $INSTALLED_PYTHON_VERSION ]]; then
echo -e " ↳ [${RED}${NC}] python3 not found on your system. You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!\n" echo -e " ↳ [${RED}${NC}] python3 not found on your system. You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!"
return 1 return 1
elif [[ $(echo $INSTALLED_PYTHON_VERSION | tr -d -c '[0-9]') -ge $(($(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9]') * 10)) ]]; then elif [[ $(echo $INSTALLED_PYTHON_VERSION | tr -d -c '[0-9]') -ge $(($(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9]') * 10)) ]]; then
echo -e " ↳ [${GREEN}${NC}] $INSTALLED_PYTHON_VERSION detected.\n" echo -e " ↳ [${GREEN}${NC}] $INSTALLED_PYTHON_VERSION detected."
else else
echo -e " ↳ [${RED}${NC}] You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!\n" echo -e " ↳ [${RED}${NC}] You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!"
return 1 return 1
fi fi
@ -133,9 +139,9 @@ function op_check_python() {
function op_check_venv() { function op_check_venv() {
echo "Checking for venv..." echo "Checking for venv..."
if source $OPENPILOT_ROOT/.venv/bin/activate; then if source $OPENPILOT_ROOT/.venv/bin/activate; then
echo -e " ↳ [${GREEN}${NC}] venv detected.\n" echo -e " ↳ [${GREEN}${NC}] venv detected."
else else
echo -e " ↳ [${RED}${NC}] Can't activate venv in $OPENPILOT_ROOT. Assuming global env!\n" echo -e " ↳ [${RED}${NC}] Can't activate venv in $OPENPILOT_ROOT. Assuming global env!"
fi fi
} }
@ -144,20 +150,32 @@ function op_before_cmd() {
return 0 return 0
fi fi
op_check_openpilot_dir op_get_openpilot_dir
cd $OPENPILOT_ROOT cd $OPENPILOT_ROOT
op_check_git
op_check_os result="$((op_check_openpilot_dir ) 2>&1)" || (echo -e "$result" && return 1)
op_check_venv result="${result}\n$(( op_check_git ) 2>&1)" || (echo -e "$result" && return 1)
op_check_python result="${result}\n$(( op_check_os ) 2>&1)" || (echo -e "$result" && return 1)
echo -e "-----------------------------\n" result="${result}\n$(( op_check_venv ) 2>&1)" || (echo -e "$result" && return 1)
op_activate_venv
result="${result}\n$(( op_check_python ) 2>&1)" || (echo -e "$result" && return 1)
if [[ -z $VERBOSE ]]; then
echo -e "Checking system → [${GREEN}${NC}] system is good."
else
echo -e "$result"
fi
} }
function op_install() { function op_setup() {
(set -e (set -e
op_check_openpilot_dir op_get_openpilot_dir
cd $OPENPILOT_ROOT cd $OPENPILOT_ROOT
op_check_openpilot_dir
op_check_os op_check_os
op_check_python op_check_python
@ -182,6 +200,10 @@ function op_install() {
) )
} }
function op_activate_venv() {
source $OPENPILOT_ROOT/.venv/bin/activate &> /dev/null || true
}
function op_venv() { function op_venv() {
( set -e ( set -e
@ -191,7 +213,7 @@ function op_venv() {
if [[ "$?" -eq 0 ]]; then if [[ "$?" -eq 0 ]]; then
# this must be run in the same shell as the user calling "op" # this must be run in the same shell as the user calling "op"
op_check_openpilot_dir > /dev/null op_get_openpilot_dir
op_run_command source $OPENPILOT_ROOT/.venv/bin/activate op_run_command source $OPENPILOT_ROOT/.venv/bin/activate
fi fi
} }
@ -199,16 +221,9 @@ function op_venv() {
function op_check() { function op_check() {
(set -e (set -e
VERBOSE=1
op_before_cmd op_before_cmd
unset VERBOSE
)
}
function op_run() {
(set -e
op_before_cmd
op_run_command $OPENPILOT_ROOT/launch_openpilot.sh $@
) )
} }
@ -226,12 +241,12 @@ function op_juggle() {
(set -e (set -e
op_before_cmd op_before_cmd
op_run_command $OPENPILOT_ROOT/tools/plotjuggler/juggle.py $@ op_run_command tools/plotjuggler/juggle.py $@
) )
} }
function op_linter() { function op_lint() {
(set -e (set -e
op_before_cmd op_before_cmd
@ -244,7 +259,7 @@ function op_replay() {
(set -e (set -e
op_before_cmd op_before_cmd
op_run_command $OPENPILOT_ROOT/tools/replay/replay $@ op_run_command tools/replay/replay $@
) )
} }
@ -253,7 +268,7 @@ function op_cabana() {
(set -e (set -e
op_before_cmd op_before_cmd
op_run_command $OPENPILOT_ROOT/tools/cabana/cabana $@ op_run_command tools/cabana/cabana $@
) )
} }
@ -262,8 +277,8 @@ function op_sim() {
(set -e (set -e
op_before_cmd op_before_cmd
op_run_command exec $OPENPILOT_ROOT/tools/sim/run_bridge.py & op_run_command exec tools/sim/run_bridge.py &
op_run_command exec $OPENPILOT_ROOT/tools/sim/launch_openpilot.sh op_run_command exec tools/sim/launch_openpilot.sh
) )
} }
@ -273,7 +288,7 @@ function op_default() {
echo "" echo ""
echo -e "${BOLD}${UNDERLINE}Description:${NC}" echo -e "${BOLD}${UNDERLINE}Description:${NC}"
echo " op is your entry point for all things related to openpilot development." echo " op is your entry point for all things related to openpilot development."
echo " op is only a wrapper for scripts, tools and commands already existing." echo " op is only a wrapper for existing scripts, tools, and commands."
echo " op will always show you what it will run on your system." echo " op will always show you what it will run on your system."
echo "" echo ""
echo " op will try to find your openpilot directory in the following order:" echo " op will try to find your openpilot directory in the following order:"
@ -284,26 +299,27 @@ function op_default() {
echo -e "${BOLD}${UNDERLINE}Usage:${NC} op [OPTIONS] <COMMAND>" echo -e "${BOLD}${UNDERLINE}Usage:${NC} op [OPTIONS] <COMMAND>"
echo "" echo ""
echo -e "${BOLD}${UNDERLINE}Commands:${NC}" echo -e "${BOLD}${UNDERLINE}Commands:${NC}"
echo -e " ${BOLD}venv${NC} Activate the virtual environment" echo -e " ${BOLD}venv${NC} Activate the Python virtual environment"
echo -e " ${BOLD}check${NC} Check system requirements (git, os, python) to start using openpilot" echo -e " ${BOLD}check${NC} Check the development environment (git, os, python) to start using openpilot"
echo -e " ${BOLD}install${NC} Install requirements to use openpilot" echo -e " ${BOLD}setup${NC} Install openpilot dependencies"
echo -e " ${BOLD}build${NC} Build openpilot" echo -e " ${BOLD}build${NC} Build openpilot"
echo -e " ${BOLD}run${NC} Run openpilot"
echo -e " ${BOLD}sim${NC} Run openpilot in a simulator" echo -e " ${BOLD}sim${NC} Run openpilot in a simulator"
echo -e " ${BOLD}juggle${NC} Run Plotjuggler" echo -e " ${BOLD}juggle${NC} Run Plotjuggler"
echo -e " ${BOLD}replay${NC} Run replay" echo -e " ${BOLD}replay${NC} Run replay"
echo -e " ${BOLD}cabana${NC} Run cabana" echo -e " ${BOLD}cabana${NC} Run cabana"
echo -e " ${BOLD}linter${NC} Run all the pre-commit checks" echo -e " ${BOLD}lint${NC} Run all the pre-commit checks"
echo -e " ${BOLD}help${NC} Show this message" echo -e " ${BOLD}help${NC} Show this message"
echo -e " ${BOLD}--install${NC} Install this tool system wide" echo -e " ${BOLD}install${NC} Install the 'op' tool system wide"
echo "" echo ""
echo -e "${BOLD}${UNDERLINE}Options:${NC}" echo -e "${BOLD}${UNDERLINE}Options:${NC}"
echo -e " ${BOLD}-d, --dir${NC}" echo -e " ${BOLD}-d, --dir${NC}"
echo " Specify the openpilot directory you want to use" echo " Specify the openpilot directory you want to use"
echo -e " ${BOLD}--dry${NC}" echo -e " ${BOLD}--dry${NC}"
echo " Don't actually run anything, just print what would be" echo " Don't actually run anything, just print what would be run"
echo -e " ${BOLD}-n, --no-verify${NC}" echo -e " ${BOLD}-n, --no-verify${NC}"
echo " Don't run checks before running a command" echo " Skip environment check before running commands"
echo -e " ${BOLD}-v, --verbose${NC}"
echo " Show the result of all checks before running a command"
echo "" echo ""
echo -e "${BOLD}${UNDERLINE}Examples:${NC}" echo -e "${BOLD}${UNDERLINE}Examples:${NC}"
echo " op --dir /tmp/openpilot check" echo " op --dir /tmp/openpilot check"
@ -325,21 +341,21 @@ function _op() {
-d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;; -d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;;
--dry ) shift 1; DRY="1" ;; --dry ) shift 1; DRY="1" ;;
-n | --no-verify ) shift 1; NO_VERIFY="1" ;; -n | --no-verify ) shift 1; NO_VERIFY="1" ;;
-v | --verbose ) shift 1; VERBOSE="1" ;;
esac esac
# parse Commands # parse Commands
case $1 in case $1 in
venv ) shift 1; op_venv "$@" ;; venv ) shift 1; op_venv "$@" ;;
check ) shift 1; op_check "$@" ;; check ) shift 1; op_check "$@" ;;
install ) shift 1; op_install "$@" ;; setup ) shift 1; op_setup "$@" ;;
build ) shift 1; op_build "$@" ;; build ) shift 1; op_build "$@" ;;
run ) shift 1; op_run "$@" ;;
juggle ) shift 1; op_juggle "$@" ;; juggle ) shift 1; op_juggle "$@" ;;
cabana ) shift 1; op_cabana "$@" ;; cabana ) shift 1; op_cabana "$@" ;;
linter ) shift 1; op_linter "$@" ;; lint ) shift 1; op_lint "$@" ;;
replay ) shift 1; op_replay "$@" ;; replay ) shift 1; op_replay "$@" ;;
sim ) shift 1; op_sim "$@" ;; sim ) shift 1; op_sim "$@" ;;
--install ) shift 1; op_first_install "$@" ;; install ) shift 1; op_install "$@" ;;
* ) op_default "$@" ;; * ) op_default "$@" ;;
esac esac
} }
@ -349,24 +365,31 @@ _op $@
# remove from env # remove from env
unset -f _op unset -f _op
unset -f op_check unset -f op_check
unset -f op_install unset -f op_setup
unset -f op_build unset -f op_build
unset -f op_run
unset -f op_juggle unset -f op_juggle
unset -f op_venv unset -f op_venv
unset -f op_check_openpilot_dir unset -f op_check_openpilot_dir
unset -f op_check_git unset -f op_check_git
unset -f op_check_python unset -f op_check_python
unset -f op_check_os unset -f op_check_os
unset -f op_first_install unset -f op_install
unset -f op_default unset -f op_default
unset -f op_run_command unset -f op_run_command
unset -f op_linter unset -f op_lint
unset -f op_replay unset -f op_replay
unset -f op_cabana unset -f op_cabana
unset -f op_check_venv unset -f op_check_venv
unset -f op_before_cmd unset -f op_before_cmd
unset -f op_sim unset -f op_sim
unset -f op_activate_venv
unset -f op_get_openpilot_dir
unset DRY unset DRY
unset NC
unset RED
unset GREEN
unset UNDERLINE
unset BOLD
unset OPENPILOT_ROOT unset OPENPILOT_ROOT
unset NO_VERIFY unset NO_VERIFY
unset VERBOSE

@ -12,8 +12,7 @@ from functools import partial
from openpilot.common.basedir import BASEDIR from openpilot.common.basedir import BASEDIR
from openpilot.selfdrive.car.fingerprints import MIGRATION from openpilot.selfdrive.car.fingerprints import MIGRATION
from openpilot.tools.lib.helpers import save_log from openpilot.tools.lib.logreader import LogReader, ReadMode, save_log
from openpilot.tools.lib.logreader import LogReader, ReadMode
juggle_dir = os.path.dirname(os.path.realpath(__file__)) juggle_dir = os.path.dirname(os.path.realpath(__file__))

@ -31,7 +31,7 @@ function check_git() {
function git_clone() { function git_clone() {
echo "Cloning openpilot..." echo "Cloning openpilot..."
if $(git clone --depth=1 https://github.com/commaai/openpilot.git "$OPENPILOT_ROOT"); then if $(git clone --filter=blob:none https://github.com/commaai/openpilot.git "$OPENPILOT_ROOT"); then
if [[ -f $OPENPILOT_ROOT/launch_openpilot.sh ]]; then if [[ -f $OPENPILOT_ROOT/launch_openpilot.sh ]]; then
echo -e " ↳ [${GREEN}${NC}] Successfully cloned openpilot.\n" echo -e " ↳ [${GREEN}${NC}] Successfully cloned openpilot.\n"
return 0 return 0
@ -44,8 +44,8 @@ function git_clone() {
function install_with_op() { function install_with_op() {
cd $OPENPILOT_ROOT cd $OPENPILOT_ROOT
$OPENPILOT_ROOT/tools/op.sh --install
$OPENPILOT_ROOT/tools/op.sh install $OPENPILOT_ROOT/tools/op.sh install
$OPENPILOT_ROOT/tools/op.sh setup
# make op usable right now # make op usable right now
alias op="source $OPENPILOT_ROOT/tools/op.sh \"\$@\"" alias op="source $OPENPILOT_ROOT/tools/op.sh \"\$@\""

@ -1,3 +1,4 @@
# TODO: remove the cv2 dependency, it's only used here
import cv2 as cv import cv2 as cv
import numpy as np import numpy as np

@ -96,15 +96,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 }, { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 },
] ]
[[distribution]]
name = "alabaster"
version = "0.7.16"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 },
]
[[distribution]] [[distribution]]
name = "attrs" name = "attrs"
version = "23.2.0" version = "23.2.0"
@ -179,28 +170,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f4/da/4033cee3855395e84ff73da4b50d3528f9338205299cde89676639387fcc/azure_storage_blob-12.21.0-py3-none-any.whl", hash = "sha256:f9ede187dd5a0ef296b583a7c1861c6938ddd6708d6e70f4203a163c2ab42d43", size = 396449 }, { url = "https://files.pythonhosted.org/packages/f4/da/4033cee3855395e84ff73da4b50d3528f9338205299cde89676639387fcc/azure_storage_blob-12.21.0-py3-none-any.whl", hash = "sha256:f9ede187dd5a0ef296b583a7c1861c6938ddd6708d6e70f4203a163c2ab42d43", size = 396449 },
] ]
[[distribution]]
name = "babel"
version = "2.15.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/15/d2/9671b93d623300f0aef82cde40e25357f11330bdde91743891b22a555bed/babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413", size = 9390000 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/27/45/377f7e32a5c93d94cd56542349b34efab5ca3f9e2fd5a68c5e93169aa32d/Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb", size = 9634913 },
]
[[distribution]]
name = "breathe"
version = "4.35.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "docutils" },
{ name = "sphinx" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a2/9f/0c6f4ae0608d5edbb1df357c2487edfcbda13e75f4e48a898972592e2e48/breathe-4.35.0.tar.gz", hash = "sha256:5165541c3c67b6c7adde8b3ecfe895c6f7844783c4076b6d8d287e4f33d62386", size = 83358 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/eb/61/faddc25913de74e60e175bcfd962ec83532653c5895c0a06a83a6b5bbf3d/breathe-4.35.0-py3-none-any.whl", hash = "sha256:52c581f42ca4310737f9e435e3851c3d1f15446205a85fbc272f1f97ed74f5be", size = 92955 },
]
[[distribution]] [[distribution]]
name = "casadi" name = "casadi"
version = "3.6.5" version = "3.6.5"
@ -538,15 +507,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 }, { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 },
] ]
[[distribution]]
name = "docutils"
version = "0.21.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 },
]
[[distribution]] [[distribution]]
name = "ewmhlib" name = "ewmhlib"
version = "0.2" version = "0.2"
@ -838,15 +798,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314 }, { url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314 },
] ]
[[distribution]]
name = "imagesize"
version = "1.4.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 },
]
[[distribution]] [[distribution]]
name = "import-linter" name = "import-linter"
version = "2.0" version = "2.0"
@ -1066,18 +1017,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f3/df/ca72f352e15b6f8ce32b74af029f1189abffb906f7c137501ffe69c98a65/Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621", size = 97778 }, { url = "https://files.pythonhosted.org/packages/f3/df/ca72f352e15b6f8ce32b74af029f1189abffb906f7c137501ffe69c98a65/Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621", size = 97778 },
] ]
[[distribution]]
name = "markdown-it-py"
version = "3.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mdurl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
]
[[distribution]] [[distribution]]
name = "markupsafe" name = "markupsafe"
version = "2.1.5" version = "2.1.5"
@ -1137,27 +1076,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e3/31/aeab8a3db1fb22a7d04c5215f872b92451baf7f6595ffd59004aeead0b2c/matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7", size = 7974774 }, { url = "https://files.pythonhosted.org/packages/e3/31/aeab8a3db1fb22a7d04c5215f872b92451baf7f6595ffd59004aeead0b2c/matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7", size = 7974774 },
] ]
[[distribution]]
name = "mdit-py-plugins"
version = "0.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown-it-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/00/6c/79c52651b22b64dba5c7bbabd7a294cc410bfb2353250dc8ade44d7d8ad8/mdit_py_plugins-0.4.1.tar.gz", hash = "sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c", size = 42713 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/f7/8a4dcea720a581e69ac8c5a38524baf0e3e2bb5f3819a9ff661464fe7d10/mdit_py_plugins-0.4.1-py3-none-any.whl", hash = "sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a", size = 54794 },
]
[[distribution]]
name = "mdurl"
version = "0.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
]
[[distribution]] [[distribution]]
name = "mergedeep" name = "mergedeep"
version = "1.3.4" version = "1.3.4"
@ -1267,19 +1185,6 @@ dependencies = [
] ]
sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850 } sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850 }
[[distribution]]
name = "mpld3"
version = "0.5.10"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jinja2" },
{ name = "matplotlib" },
]
sdist = { url = "https://files.pythonhosted.org/packages/90/58/19378f4189a034eb3efc17b133426b8551af1d3b2c70d641a63124579629/mpld3-0.5.10.tar.gz", hash = "sha256:a478eb404fa5212505c59133cf272cd9a94105872e605597720e7f84de38fbc7", size = 1027709 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/95/6a/e3691bcc47485f38b09853207c928130571821d187cf174eed5418d45e82/mpld3-0.5.10-py3-none-any.whl", hash = "sha256:80877acce87ea447380fad7374668737505c8c0684aab05238e7c5dc1fab38c1", size = 202561 },
]
[[distribution]] [[distribution]]
name = "mpmath" name = "mpmath"
version = "1.3.0" version = "1.3.0"
@ -1387,23 +1292,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 },
] ]
[[distribution]]
name = "myst-parser"
version = "3.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "docutils" },
{ name = "jinja2" },
{ name = "markdown-it-py" },
{ name = "mdit-py-plugins" },
{ name = "pyyaml" },
{ name = "sphinx" },
]
sdist = { url = "https://files.pythonhosted.org/packages/49/64/e2f13dac02f599980798c01156393b781aec983b52a6e4057ee58f07c43a/myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87", size = 92392 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", size = 83163 },
]
[[distribution]] [[distribution]]
name = "natsort" name = "natsort"
version = "8.4.0" version = "8.4.0"
@ -1573,7 +1461,6 @@ dev = [
{ name = "av" }, { name = "av" },
{ name = "azure-identity" }, { name = "azure-identity" },
{ name = "azure-storage-blob" }, { name = "azure-storage-blob" },
{ name = "breathe" },
{ name = "control" }, { name = "control" },
{ name = "dictdiffer" }, { name = "dictdiffer" },
{ name = "flaky" }, { name = "flaky" },
@ -1582,10 +1469,6 @@ dev = [
{ name = "lru-dict" }, { name = "lru-dict" },
{ name = "matplotlib" }, { name = "matplotlib" },
{ name = "metadrive-simulator", marker = "platform_machine != 'aarch64'" }, { name = "metadrive-simulator", marker = "platform_machine != 'aarch64'" },
{ name = "mpld3" },
{ name = "myst-parser" },
{ name = "natsort" },
{ name = "opencv-python-headless" },
{ name = "parameterized" }, { name = "parameterized" },
{ name = "pyautogui" }, { name = "pyautogui" },
{ name = "pyopencl", marker = "platform_machine != 'aarch64'" }, { name = "pyopencl", marker = "platform_machine != 'aarch64'" },
@ -1603,6 +1486,7 @@ docs = [
{ name = "mkdocs" }, { name = "mkdocs" },
{ name = "mkdocs-plugin-commonmark" }, { name = "mkdocs-plugin-commonmark" },
{ name = "mkdocs-terminal" }, { name = "mkdocs-terminal" },
{ name = "natsort" },
] ]
testing = [ testing = [
{ name = "coverage" }, { name = "coverage" },
@ -5204,15 +5088,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d6/5b/3ada173f07b4ec9bfa03b779e59ecada48eb7cb1a29f51cfce70edce7f3f/smbus2-0.4.3-py2.py3-none-any.whl", hash = "sha256:a2fc29cfda4081ead2ed61ef2c4fc041d71dd40a8d917e85216f44786fca2d1d", size = 11553 }, { url = "https://files.pythonhosted.org/packages/d6/5b/3ada173f07b4ec9bfa03b779e59ecada48eb7cb1a29f51cfce70edce7f3f/smbus2-0.4.3-py2.py3-none-any.whl", hash = "sha256:a2fc29cfda4081ead2ed61ef2c4fc041d71dd40a8d917e85216f44786fca2d1d", size = 11553 },
] ]
[[distribution]]
name = "snowballstemmer"
version = "2.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 },
]
[[distribution]] [[distribution]]
name = "sortedcontainers" name = "sortedcontainers"
version = "2.4.0" version = "2.4.0"
@ -5237,87 +5112,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d4/09/bfdd393f1bb1b90b4a6849b84972b7059c95e36818cc489922228d58cc63/sounddevice-0.4.7-py3-none-win_amd64.whl", hash = "sha256:0c8b3543da1496f282b66a7bc54b755577ba638b1af06c146d4ac7f39d86b548", size = 200096 }, { url = "https://files.pythonhosted.org/packages/d4/09/bfdd393f1bb1b90b4a6849b84972b7059c95e36818cc489922228d58cc63/sounddevice-0.4.7-py3-none-win_amd64.whl", hash = "sha256:0c8b3543da1496f282b66a7bc54b755577ba638b1af06c146d4ac7f39d86b548", size = 200096 },
] ]
[[distribution]]
name = "sphinx"
version = "7.4.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "alabaster" },
{ name = "babel" },
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "docutils" },
{ name = "imagesize" },
{ name = "jinja2" },
{ name = "packaging" },
{ name = "pygments" },
{ name = "requests" },
{ name = "snowballstemmer" },
{ name = "sphinxcontrib-applehelp" },
{ name = "sphinxcontrib-devhelp" },
{ name = "sphinxcontrib-htmlhelp" },
{ name = "sphinxcontrib-jsmath" },
{ name = "sphinxcontrib-qthelp" },
{ name = "sphinxcontrib-serializinghtml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624 },
]
[[distribution]]
name = "sphinxcontrib-applehelp"
version = "1.0.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/26/6b/68f470fc337ed24043fec987b101f25b35010970bd958970c2ae5990859f/sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619", size = 19674 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/56/89/fea3fbf6785b388e6cb8a1beaf62f96e80b37311bdeed6e133388a732426/sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4", size = 120035 },
]
[[distribution]]
name = "sphinxcontrib-devhelp"
version = "1.0.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c7/a1/80b7e9f677abc673cb9320bf255ad4e08931ccbc2e66bde4b59bad3809ad/sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3", size = 12480 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/52/1049d918d1d1c72857d285c3f0c64c1cbe0be394ce1c93a3d2aa4f39fe3b/sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f", size = 83499 },
]
[[distribution]]
name = "sphinxcontrib-htmlhelp"
version = "2.0.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/92/d9/a1c50c8a7b5e12f34bf4d63300a1e2629c29b71603115d900c0fa7c79219/sphinxcontrib_htmlhelp-2.0.6.tar.gz", hash = "sha256:c6597da06185f0e3b4dc952777a04200611ef563882e0c244d27a15ee22afa73", size = 21957 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a4/b4/6ebbdc57b5b216b400b355f34ef669e9b6b5c31a6ede8cf5ac36f9e8fc0c/sphinxcontrib_htmlhelp-2.0.6-py3-none-any.whl", hash = "sha256:1b9af5a2671a61410a868fce050cab7ca393c218e6205cbc7f590136f207395c", size = 99225 },
]
[[distribution]]
name = "sphinxcontrib-jsmath"
version = "1.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 },
]
[[distribution]]
name = "sphinxcontrib-qthelp"
version = "1.0.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a6/67/f5c7df6457315877202f370450acb28626d033822eec1e8163600612b4ef/sphinxcontrib_qthelp-1.0.8.tar.gz", hash = "sha256:db3f8fa10789c7a8e76d173c23364bdf0ebcd9449969a9e6a3dd31b8b7469f03", size = 16778 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/91/cec9416d27ebe9b8aa83f014a1ac8402c729aed791da67704e10bb2c8f33/sphinxcontrib_qthelp-1.0.8-py3-none-any.whl", hash = "sha256:323d6acc4189af76dfe94edd2a27d458902319b60fcca2aeef3b2180c106a75f", size = 89456 },
]
[[distribution]]
name = "sphinxcontrib-serializinghtml"
version = "1.1.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/13/8dd7a7ed9c58e16e20c7f4ce8e4cb6943eb580955236d0c0d00079a73c49/sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f", size = 15592 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/38/24/228bb903ea87b9e08ab33470e6102402a644127108c7117ac9c00d849f82/sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7", size = 92725 },
]
[[distribution]] [[distribution]]
name = "spidev" name = "spidev"
version = "3.6" version = "3.6"

Loading…
Cancel
Save