Loading

Projects

Driverless Perception Pipeline

An animated walkthrough of the frame-wide PointNet transformer, from point sampling through candidate attention.

C++, ROS 2, Ouster OS1, Patchwork++, PointNet Transformer, ONNX Runtime, TensorRT

Built a LiDAR-only ROS 2 perception pipeline for an Ouster OS1. It deskews each scan from odometry, IMU, and twist data, transforms the cloud into the vehicle frame, removes ego and out-of-range returns, and uses Patchwork++ to separate ground from obstacles.

Range-adaptive curved-voxel clustering groups obstacle returns into size-gated cone candidates. For each candidate, the C++ runtime samples up to 64 XYZI returns and canonicalizes their coordinates within the candidate box. A shared 4→64→64 PointNet MLP produces point features, then masked maximum, mean, and standard deviation pooling creates a 192-value shape descriptor. The graph appends intensity summaries, six physical box features, and five position features before projecting each candidate to a 128-value token.

Flowchart from masked XYZI point rows through PointNet pooling and candidate token projection
PointNet turns each masked XYZI cluster into one 128-value candidate token.

All candidate tokens from one scan enter 12 post-LayerNorm transformer blocks in one frame-wide inference call. Each block uses eight-head dense self-attention and a 128→512→128 feed-forward network. A learned per-head bias encodes the planar distance and bearing between every candidate pair, while a mission token supplies acceleration, skidpad, or track context without hard-coded rules.

Flowchart of geometry-biased self-attention, residual connections, normalization, and token MLP
One post-LayerNorm transformer block: geometry-biased attention, residual updates, and a per-token MLP.

A five-class output head produces non-cone, blue, yellow, orange, and big-orange scores. A separate claim head estimates whether the winning color is reliable, so the runtime can move uncertain color probability to unknown without reducing cone objectness. The composable ROS 2 node executes the dynamic-candidate graph through ONNX Runtime with TensorRT, CUDA, and CPU providers, then republishes each source cluster with its decoded probabilities and original timestamp.

Flowchart from a final candidate token to cone objectness, conditional colors, and color claim
The final token feeds a joint class head for objectness and conditional color, plus a separate color-claim head.

Composable C++ nodes and intra-process transport limit point-cloud copies. Post-processing merges close clusters, confirms candidates across distinct odometry-associated views, applies mission- and range-aware color policy, and publishes centroid positions with calibrated uncertainty.

Recorded-scene replay: raw cloud, size-filtered clusters, labels, and final cone observations.

On a 630-frame real-scene replay, the complete detector reached 98.97% precision, 81.57% recall, 98.91% color accuracy, and 8.7 cm localization RMSE. Every measured callback had p95 latency below 1.9 ms.

2025–2026 IEM BMS

C, C++, FreeRTOS, STM32H7, Python, CAN, SPI, HIL

Led the migration of Illini Electric Motorsports' battery management system from bare-metal STM32F4 firmware to FreeRTOS on an STM32H733. The completed system monitors a 144-cell series pack through twelve LTC6811-2 devices connected by DMA-backed isoSPI.

IEM accumulator with twelve cell-monitoring boards and wiring
The 144-cell accumulator: twelve monitoring boards, each responsible for twelve cells.

Split cell polling, isolated pack sensing, state control, precharge protection, battery modeling, and CAN communication into scheduled tasks. The firmware samples pack current and bus voltage and updates SOC, SOH, and power limits at 500 Hz; a separate 1 kHz task monitors precharge and inrush faults.

Flowchart of STM32H7 FreeRTOS tasks, peripheral interfaces, accumulator sensors, and car signals
Firmware architecture from accumulator and car inputs through STM32 peripherals, FreeRTOS tasks, IPC, and CAN outputs. Open the diagram for the full-size view.
BMS bench setup with STM32H7 controller, cell monitors, CAN adapter, and power supplies
Bench validation of the H7 controller, cell-monitor chain, isolated ADC, and CAN interface.

Wrote DMA-based drivers for the LTC6811 chain and isolated ADC, then built Python and C++ validation tools around the firmware. My Python BMS Viewer displays all cell voltages and temperatures, pack state, faults, current, voltage, SOC, SOH, power limits, and CAN health while exposing controlled balancing, charging, and state-estimation commands.

BMS Viewer showing 144 cell readings, temperatures, faults, and CAN diagnostics
The BMS Viewer during pack validation. Open the image for the full diagnostic view.

The migrated system completed integration and ran on the car. The acceleration test below exercised the pack, sensing, safety logic, telemetry, and contactor control together.

On-car acceleration testing with the completed H7/FreeRTOS BMS.

Morphi (Top 7 of 226 HackVoyager Finalist, HackIllinois 2026)

React Native, Python, Modal, vLLM, YOLO Pose, LoRA, Qwen3-VL

Morphi turns a five-second video into coaching for sports, exercise, dance, or music practice. It finds mistakes in the user's motion, pauses playback at each one, draws the current and target joint positions, and narrates a specific correction. A score and session history show whether the next attempt improved.

Morphi's HackIllinois pitch and product demonstration.

I built the backend data and training pipeline. Distributed Modal jobs collected sports, yoga, and workout images, kept clear single-person poses with YOLO, and used Gemini 3 Flash to generate schema-validated corrections tied to detected joints. That process produced more than 2,300 labeled examples for LoRA fine-tuning Qwen3-VL-32B on eight H200 GPUs.

I served the adapted model with vLLM across four H200s and kept GPU containers warm to avoid repeated model startup. The complete path—from pose extraction through coaching JSON, overlays, and voice generation—fell from about three minutes to less than 24 seconds.

Custom CoreXY 3D Printer

Autodesk Inventor, C++, Klipper, Raspberry Pi

Designed the frame and motion system in Autodesk Inventor, fabricated the custom parts, and assembled the printer around salvaged Ender 3 electronics.

A speed test of the completed CoreXY motion system.

Configured Klipper on a Raspberry Pi 4 and tuned the motion system beyond 1,500 mm/s at 7,000 mm/s².

W.A.N.D.E.R. Autonomous Robot

C++, ESP32, Autodesk Inventor

Designed a 3D-printed maze robot and fused gyroscope, wheel-encoder, and distance-sensor data for localization.

The robot follows a programmed route between temporary maze walls.

Implemented mapping and pathfinding in C++ on an ESP32 so the robot could build and traverse an unknown maze without an external computer.