Autonomous vehicle platform running on the NVIDIA Jetson AGX Thor to drive a Honda Bosch vehicle. Built at TreeHacks 2026.
Cameras → CUDA warp/YUV (CuPy) → driving_vision.onnx → driving_policy.onnx → controlsd → pandad → CAN bus → Honda
↑
IMU (104Hz) → locationd (Kalman) → livePose ────────────────────────────────────────┘
GPS (10Hz) → navd (Valhalla offline routing) → NavDesire → desire_helper ──────────┘
ORT_ENABLE_ALL graph optimization + EXHAUSTIVE cuDNN algo search| Model | Avg Latency | Output |
|---|---|---|
driving_vision.onnx | 7.06 ms | [1,1576] fp16 |
driving_policy.onnx | 0.93 ms | [1,1000] fp16 |
dmonitoring_model.onnx | 3.83 ms | [1,551] fp16 |
| Total driving pipeline | ~8 ms | Well within 50ms (20Hz) budget |
Replaced the entire OpenCL pipeline with CuPy CUDA kernels:
warpPerspective CUDA RawKernel — bilinear interpolation perspective warploadyuv — YUV420 channel packing via CuPy array slicingDrivingModelFrame / MonitoringModelFrame — full temporal buffer managementReplaced tinygrad/OpenCL model runner with ONNX Runtime + CUDA sessions for both the driving model and driver monitoring model.
holoscan-sensor-bridge/)Two IMX274 cameras are connected to the Jetson AGX Thor through a Lattice CPNX100 Holoscan Sensor Bridge board. The FPGA bridges MIPI camera data to 10GbE UDP, which ConnectX NICs can write directly into GPU memory via RDMA.
FPGA firmware flashing: The Lattice CPNX100 board requires its FPGA bitstream to be programmed before use. This is done from inside the Holoscan Sensor Bridge Docker container:
# 1. Connect ethernet from Jetson to the sensor bridge board (J6 for cam 0, J3 for cam 1)
# 2. Verify connectivity
ping 192.168.0.2
# 3. Launch the Holoscan Sensor Bridge Docker container
cd holoscan-sensor-bridge
xhost +
sh docker/demo.sh
# 4. Flash the FPGA bitstream to on-board SPI flash (~50 min)
# Use --force if upgrading from an older bitstream version
program_lattice_cpnx100 scripts/manifest.yaml
# 5. Program the FPGA from the SPI flash (~1 min)
# The board must be power-cycled after programming
The flash tool (tools/program_lattice_cpnx100/) programs both the CLNX17 (MIPI bridge) and CPNX100 (main 10GbE) FPGAs via SPI, with MD5 checksum verification and automatic firmware download.
Camera pipeline:
/dev/shm ring buffer (4 slots, sequence-counter torn-read detection)jetson_camerad publishes via VisionIPC + cereal at 20 Hz/dev/IMUsensorsOK, inputsOK, valid all 100%/dev/GPSpyvalhalla with Stanford-area OSM datamobileApp/)A native iOS app (SwiftUI) that lets users hail the autonomous vehicle, similar to the Waymo rider app. The phone and car communicate over MQTT via a VPS broker.
Ride flow:
from-phone/command-car MQTT message with pickup/destination coordinatesfrom-car/car-arrived — user taps "Start Driving"from-phone/start-ride — car drives to destinationfrom-car/ride-finished — ride completeFeatures:
mqtt-server/)We run an NVIDIA H100 GPU instance on Google Cloud (A3 machine type, 80GB HBM3) that serves as the central hub connecting the car, the mobile app, and the Alpamayo model.
Server setup: The server runs three services:
# On the H100 instance
cd mqtt-server
pip install -r requirements.txt
PYTHONPATH=/path/to/alpamayo/src uvicorn server.main:app --host 0.0.0.0 --port 8000
What the server does:
/ws/thor): The Jetson Thor streams JPEG camera frames + ego-motion data (orientation quaternion, velocity vector from livePose) over a msgpack WebSocket at ~10 Hz. The server buffers these in a thread-safe ring buffer, selecting frames at ~100ms intervals for inference.from-phone/* and from-car/* topics, forwards commands between phone and car (e.g. routing from-phone/command-car → from-server/command-car), and auto-accepts hail requests with the car's latest GPS position./ws/mobile/video): Forwards the latest JPEG frame from the car to connected mobile clients at ~5 FPS.alpamayo/)We run NVIDIA Alpamayo R1 (10B parameter Vision-Language-Action model) on the H100 server to provide high-level scene reasoning alongside the on-device driving stack.
How it works:
livePose) to the H100 server over a WebSocket at ~10 Hzfrom-server/coc-reasoning, from-server/trajectory)Pipeline:
Thor cameras + livePose → WebSocket (msgpack) → H100 server → Alpamayo R1 → CoC + trajectory → MQTT → mobile app
The server also relays a live JPEG video feed from the car to the app via a second WebSocket endpoint.
Running Alpamayo on a remote H100 works, but introduces network latency and a dependency on cloud connectivity — not ideal for a safety-critical driving system. Our goal is to distill Alpamayo R1 down to a model small enough to run directly on the Jetson AGX Thor in real time.
This is a significant undertaking. Alpamayo R1 is a 10B parameter Vision-Language-Action model with two distinct components that both need to be preserved through distillation:
Distilling a model of this scale while retaining both the reasoning quality and the trajectory accuracy — especially on long-tail driving scenarios where CoC reasoning matters most — requires careful multi-stage training and extensive validation.
For on-device inference, we are using Thunder Kittens and TensorRT-Edge-LLM to write hyperoptimized CUDA kernels targeting a quantized version of the distilled model in NVFP4 (4-bit floating point). This combination should allow us to hit real-time inference on the Thor's Blackwell GPU.
Stay tuned for future updates.
/JETSON marker file| Stage | Avg | p95 |
|---|---|---|
| CUDA preprocess (both cams) | 1.81 ms | 2.22 ms |
| Vision ONNX inference | 5.33 ms | 8.40 ms |
| Policy ONNX inference | 1.22 ms | 1.74 ms |
| Total driving pipeline | 8.66 ms | 12.34 ms |
| Driver monitoring (preprocess + inference) | 4.15 ms | 4.39 ms |
| Budget (20 Hz) | 50 ms | ~39 ms headroom |
Topic: from-phone/command-car
Payload: {"timestamp":...,"pickup":{"longitude":...,"latitude":...},"destination":{"name":"...","longitude":...,"latitude":...}}
Topic: from-phone/start-ride
Payload: null
Topic: from-car/ride-finished
sudo PYTHONPATH=/home/subha/.local/lib/python3.12/site-packages python3 main.py
28 commits
Python
55.7%
C
29.9%
Jupyter Notebook
4.5%
C++
3.5%
Cuda
1.7%
Shell
1.5%
Autonomous vehicle platform running on the NVIDIA Jetson AGX Thor to drive a Honda Bosch vehicle. Built at TreeHacks 2026.
Cameras → CUDA warp/YUV (CuPy) → driving_vision.onnx → driving_policy.onnx → controlsd → pandad → CAN bus → Honda
↑
IMU (104Hz) → locationd (Kalman) → livePose ────────────────────────────────────────┘
GPS (10Hz) → navd (Valhalla offline routing) → NavDesire → desire_helper ──────────┘
ORT_ENABLE_ALL graph optimization + EXHAUSTIVE cuDNN algo search| Model | Avg Latency | Output |
|---|---|---|
driving_vision.onnx | 7.06 ms | [1,1576] fp16 |
driving_policy.onnx | 0.93 ms | [1,1000] fp16 |
dmonitoring_model.onnx | 3.83 ms | [1,551] fp16 |
| Total driving pipeline | ~8 ms | Well within 50ms (20Hz) budget |
Replaced the entire OpenCL pipeline with CuPy CUDA kernels:
warpPerspective CUDA RawKernel — bilinear interpolation perspective warploadyuv — YUV420 channel packing via CuPy array slicingDrivingModelFrame / MonitoringModelFrame — full temporal buffer managementReplaced tinygrad/OpenCL model runner with ONNX Runtime + CUDA sessions for both the driving model and driver monitoring model.
holoscan-sensor-bridge/)Two IMX274 cameras are connected to the Jetson AGX Thor through a Lattice CPNX100 Holoscan Sensor Bridge board. The FPGA bridges MIPI camera data to 10GbE UDP, which ConnectX NICs can write directly into GPU memory via RDMA.
FPGA firmware flashing: The Lattice CPNX100 board requires its FPGA bitstream to be programmed before use. This is done from inside the Holoscan Sensor Bridge Docker container:
# 1. Connect ethernet from Jetson to the sensor bridge board (J6 for cam 0, J3 for cam 1)
# 2. Verify connectivity
ping 192.168.0.2
# 3. Launch the Holoscan Sensor Bridge Docker container
cd holoscan-sensor-bridge
xhost +
sh docker/demo.sh
# 4. Flash the FPGA bitstream to on-board SPI flash (~50 min)
# Use --force if upgrading from an older bitstream version
program_lattice_cpnx100 scripts/manifest.yaml
# 5. Program the FPGA from the SPI flash (~1 min)
# The board must be power-cycled after programming
The flash tool (tools/program_lattice_cpnx100/) programs both the CLNX17 (MIPI bridge) and CPNX100 (main 10GbE) FPGAs via SPI, with MD5 checksum verification and automatic firmware download.
Camera pipeline:
/dev/shm ring buffer (4 slots, sequence-counter torn-read detection)jetson_camerad publishes via VisionIPC + cereal at 20 Hz/dev/IMUsensorsOK, inputsOK, valid all 100%/dev/GPSpyvalhalla with Stanford-area OSM datamobileApp/)A native iOS app (SwiftUI) that lets users hail the autonomous vehicle, similar to the Waymo rider app. The phone and car communicate over MQTT via a VPS broker.
Ride flow:
from-phone/command-car MQTT message with pickup/destination coordinatesfrom-car/car-arrived — user taps "Start Driving"from-phone/start-ride — car drives to destinationfrom-car/ride-finished — ride completeFeatures:
mqtt-server/)We run an NVIDIA H100 GPU instance on Google Cloud (A3 machine type, 80GB HBM3) that serves as the central hub connecting the car, the mobile app, and the Alpamayo model.
Server setup: The server runs three services:
# On the H100 instance
cd mqtt-server
pip install -r requirements.txt
PYTHONPATH=/path/to/alpamayo/src uvicorn server.main:app --host 0.0.0.0 --port 8000
What the server does:
/ws/thor): The Jetson Thor streams JPEG camera frames + ego-motion data (orientation quaternion, velocity vector from livePose) over a msgpack WebSocket at ~10 Hz. The server buffers these in a thread-safe ring buffer, selecting frames at ~100ms intervals for inference.from-phone/* and from-car/* topics, forwards commands between phone and car (e.g. routing from-phone/command-car → from-server/command-car), and auto-accepts hail requests with the car's latest GPS position./ws/mobile/video): Forwards the latest JPEG frame from the car to connected mobile clients at ~5 FPS.alpamayo/)We run NVIDIA Alpamayo R1 (10B parameter Vision-Language-Action model) on the H100 server to provide high-level scene reasoning alongside the on-device driving stack.
How it works:
livePose) to the H100 server over a WebSocket at ~10 Hzfrom-server/coc-reasoning, from-server/trajectory)Pipeline:
Thor cameras + livePose → WebSocket (msgpack) → H100 server → Alpamayo R1 → CoC + trajectory → MQTT → mobile app
The server also relays a live JPEG video feed from the car to the app via a second WebSocket endpoint.
Running Alpamayo on a remote H100 works, but introduces network latency and a dependency on cloud connectivity — not ideal for a safety-critical driving system. Our goal is to distill Alpamayo R1 down to a model small enough to run directly on the Jetson AGX Thor in real time.
This is a significant undertaking. Alpamayo R1 is a 10B parameter Vision-Language-Action model with two distinct components that both need to be preserved through distillation:
Distilling a model of this scale while retaining both the reasoning quality and the trajectory accuracy — especially on long-tail driving scenarios where CoC reasoning matters most — requires careful multi-stage training and extensive validation.
For on-device inference, we are using Thunder Kittens and TensorRT-Edge-LLM to write hyperoptimized CUDA kernels targeting a quantized version of the distilled model in NVFP4 (4-bit floating point). This combination should allow us to hit real-time inference on the Thor's Blackwell GPU.
Stay tuned for future updates.
/JETSON marker file| Stage | Avg | p95 |
|---|---|---|
| CUDA preprocess (both cams) | 1.81 ms | 2.22 ms |
| Vision ONNX inference | 5.33 ms | 8.40 ms |
| Policy ONNX inference | 1.22 ms | 1.74 ms |
| Total driving pipeline | 8.66 ms | 12.34 ms |
| Driver monitoring (preprocess + inference) | 4.15 ms | 4.39 ms |
| Budget (20 Hz) | 50 ms | ~39 ms headroom |
Topic: from-phone/command-car
Payload: {"timestamp":...,"pickup":{"longitude":...,"latitude":...},"destination":{"name":"...","longitude":...,"latitude":...}}
Topic: from-phone/start-ride
Payload: null
Topic: from-car/ride-finished
sudo PYTHONPATH=/home/subha/.local/lib/python3.12/site-packages python3 main.py
28 commits
Python
55.7%
C
29.9%
Jupyter Notebook
4.5%
C++
3.5%
Cuda
1.7%
Shell
1.5%