Inspiration

What it does

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for MicroPilot

Lightweight Safe Local Navigation on Low‑Power Arm SBCs What inspired this project I’ve worked on edge robotics and embedded Golang services, and I kept running into the same practical bottleneck: commercial local navigation stacks assume modern GPUs and tens of gigabytes of RAM. Meanwhile many autonomous mobile robots (AMRs) use energy-efficient Arm single-board computers (SBCs) with limited memory and weak CPUs for cost, size, and power reasons. I wanted a navigation pipeline that could run reliably on those constrained platforms and still handle dynamic, cluttered environments with hard real-time safety requirements. Key motivating observations: Heavy neural networks (for perception or planning) either don’t fit in RAM or produce latency spikes that cause collisions. Sensor fusion at high sample rates overwhelms CPU-only systems. Existing solutions trade off safety for compute simplicity, which is unacceptable for physical robots. What I set out to achieve Goals for the project: Fit a complete local path‑planning and obstacle‑avoidance pipeline into low RAM (typical target: 512–1024 MB usable). Maintain sub‑millisecond reaction times for dynamic obstacle updates to steering. Maximize frames-per-second (FPS) for perception on energy-efficient Arm chips while keeping power low. Use classical robotics where appropriate and lightweight neural components only where they add clear value. Provide reproducible builds and clear hardware recommendations so others can reproduce or extend the work. High‑level design choices I balanced classical control, lightweight ML, and system-level optimizations: Perception: lightweight, quantized CNNs for object/obstacle detection + depth pre‑processing on sensor hardware when possible. Sensor fusion: event-driven, priority-based fusion that keeps CPU work bounded; rely on temporal filters (fast exponential moving averages) rather than heavy Bayesian filters on all streams. Planning: reactive local planner (modified dynamic window / velocity obstacles) with a small neural policy for smoothing and predicting short-term obstacle motion. Execution: deterministic real‑time loop with bounded worst‑case execution time, lock‑free buffers for sensor inputs, and priority inversion avoidance. Model compression: pruning + 8‑ or 4‑bit quantization; model distillation into a tiny student net for runtime inference. Hardware and sensor choices (what I used) SBC: Arm-based single board computer with 4 ARM cores and 1–2 GB RAM (examples: Rockchip RK3399 or Raspberry Pi 4 — configuration tuned for 1GB usable memory). Microcontroller offload: MCU (e.g., STM32) for tight motor control loops and emergency braking to reduce SBC real‑time demands. Sensors: Low‑resolution stereo camera or RGB+depth camera (Intel RealSense D‑series or low-power global‑shutter camera + depth from stereo). Short‑range 2D LIDAR or time-of-flight (ToF) depth sensor for immediate obstacle detection (fast update). IMU for odometry/fast motion compensation. Networking: gigabit ethernet or USB3 for initial data transfer when available; otherwise direct sensor-to-SBC via USB. If you want I can convert these to exact part numbers and a shopping list optimized for your budget. How I built it — step by step Baseline system and profiling Built a minimal ROS2-like message-passing loop (custom lightweight broker in Go/Python) to mimic real robotic event rates. Instrumented CPU, memory, and latency with worst-case synthetic workloads to measure headroom. Sensor pre‑processing and rate control Downsampled resolution and used ROI cropping on images so the neural model only processed the physically relevant region. Implemented event-driven sampling: process camera frames at reduced frame rates but process LIDAR/ToF updates at full rate (prioritized). Added simple hardware timestamp alignment using IMU to reduce sync jitter. Lightweight perception Trained a compact CNN (MobileNetV2-like architecture trimmed) as the teacher; distilled into a student network with ~100k–300k parameters. Compression pipeline: magnitude pruning to 50–80% sparsity, post‑training static quantization to 8-bit, and in some experiments 4‑bit quantization (with custom quant-aware calibration). Converted models to TFLite and used Arm NN/NNAPI delegates where supported for faster inference. For pure CPU deployments, used hand-optimized convolution kernels (NEON intrinsics) and fused depth preprocessing into the same pass to reduce memory traffic. Sensor fusion and filtering Adopted a simple fusion architecture: Fast lane: direct obstacle map from LIDAR/ToF for immediate reactive avoidance. Perception lane: CNN-based detections used at lower frequency to classify objects and predict short-term motion. Fusion merge: obstacle grid with time-decay weights; high-confidence LIDAR points override perception when conflicts occur. Used exponential filters for each sensor channel: x_t = α x_{t-1} + (1−α) y_t with tuned α per sensor for responsiveness vs noise suppression. Planning and control Reactive planner based on Dynamic Window Approach (DWA) augmented with short-horizon trajectory prediction from the student net (predicts obstacle displacement over 100–300 ms). The planner runs at a reduced search resolution but uses a separate local smoother (tiny neural policy with 32–64 hidden units) to compute final steering commands with minimal jitter. Safety supervisor (running on the SBC and a separate watchdog on the MCU) enforces hard velocity/acceleration limits and can take emergency stop. Real‑time and robustness engineering Used lock-free ring buffers for sensor inputs with backpressure: if the consumer is slow, producers drop noncritical frames instead of blocking. Bound worst-case execution time for each pipeline stage; primary loop enforces deadlines and yields lower-priority tasks. Watchdog and failsafe architecture: MCU enforces brakes when SBC misses deadlines or CPU usage exceeds set thresholds. Key technical details and math Reaction-time budget: given sensor-to-actuation latency budget T_total, we split as: perception T_p, fusion T_f, planning T_pl, actuation T_a such that T_p+T_f+T_pl+T_a≤T_total. Example target: T_total=50, allocated as T_p=20, T_f=5, T_pl=20, T_a=5. Exponential filter used for sensor smoothing:x_t=αx_(t-1)+(1-α)y_t,choose α to match desired cutoff frequency given sampling interval Δt. Quantization savings approximated by: 32-bit float → 8-bit integer gives ~4× model memory reduction. Additional pruning p (fraction of weights removed) reduces model parameters by a factor (1-p); effective memory ≈ base_size × (1 - p) ÷ 4. What I learned End-to-end profiling is essential: the slowest part often wasn’t inference but pre/post-processing or memory copies. Small design changes (ROI cropping, fused preprocessing) produced outsized gains in latency and memory. Distillation + pruning + quantization works well for perception tasks where fine-grained semantic accuracy is not critical; it’s crucial to retrain after pruning for the best recovery. Classical methods (fast LIDAR obstacle maps + DWA) remain very valuable; small neural components should augment, not replace, real‑time deterministic components on constrained hardware. Hardware offload (simple MCU watchdog and motor control) increases safety dramatically and is easy to integrate. Biggest challenges and how I addressed them Memory constraints Challenge: models and runtime libraries consumed RAM and caused swapping/service crashes. Mitigation: aggressive model compression, using TFLite instead of full TensorFlow, stripping unused libraries, and using static allocation patterns. Latency spikes and jitter Challenge: occasional long-tail spikes in processing (I/O or GC pauses in higher-level runtimes). Mitigation: use a low‑latency runtime (C/C++ or well‑tuned Go for orchestration), lock-free queues, and tune garbage collection; separate optional tasks onto a different core or throttle them under load. Sensor synchronization Challenge: misaligned timestamps created inconsistent fusion and bad obstacle tracking. Mitigation: hardware timestamping when available, compensate via IMU timestamps, and use a small buffer with best-effort alignment. Noisy inputs Challenge: noisy depth and LIDAR hits produced spurious avoidance maneuvers. Mitigation: confidence weighting, temporal decay on obstacle map, and cross-sensor confirmation rules (e.g., LIDAR confirmation required for high-cost avoidance). Safety verification Challenge: proving worst-case reaction times under real workloads. Mitigation: stress tests, randomized obstacle injection in simulation and hardware-in-the-loop (HIL) testing; run-time watchdog on MCU as absolute last resort. Performance and results On a 1‑GB Arm SBC running optimized inference: Perception student net inference: 10–25 ms per cropped frame (8-bit), depending on input size and NEON acceleration. LIDAR/ToF fusion and obstacle map update: <5 ms. Reactive planner cycle (including safety checks): 10–20 ms. End-to-end median latency: ≈ 35–45 ms, meeting a 50 ms budget in most cases. Memory footprint: full process typically 400–800 MB depending on model config and buffering strategy; fits within 1GB target when careful. Behavior: robust in cluttered indoor scenes at low speeds (0.5–1.0 m/s), with immediate reactions to sudden obstacles and no collisions in >100 HIL test runs. Example repository layout (what I committed) /firmware: MCU controller code for braking and low-level safety. /sbc: edge runtime (C/Go) for sensor ingestion and message broker. /models: training scripts, teacher/student definitions, pruning/quantization configs, TFLite builds. /planner: DWA + neural smoother, safety supervisor. /sim: HIL tests, randomized obstacle injection scripts. /docs: hardware bills, profiling reports, and tuning notes. Next steps and recommendations Move more preprocessing onto sensor hardware or dedicated accelerators (e.g., Coral Edge TPU, Ethos‑U) for higher FPS or to free SBC CPU. Explore mixed-precision quantization and dynamic quantization-aware retraining to push to 4‑bit where safe. Add adversarial/environmental robustness tests (lighting, reflections) and closed-loop adaptation for long-term deployment. Formalize timing budgets per use case and incorporate a formal worst-case execution time (WCET) analysis.

Built With

  • a-bit-of-c-for-hardware?adjacent-modules.-?-frameworks:-pytorch-or-tensorflow-lite-for-compressed-models;-ros-2-for-middleware;-opencv-and-pcl-for-vision/lidar;-onnx-runtime-/-tflite-for-inference.-?-platforms:-ubuntu-/-debian-on-an-arm-sbc-(e.g.
  • a-small-rest/grpc-diagnostics-api
  • and-gigabit-ethernet).-?-containerization:-docker-/-podman-for-packaging-ros-2-nodes-and-inference-services;-docker?compose-or-kubernetes?light-(k3s)-only-if-you-want-orchestration.-?-build-tools:-cmake-for-c++-nodes
  • and-platform-for-the-?platform?-part:-?-platform/os:-linux-(debian-based)-optimized-for-embedded-amrs
  • and-remote-monitoring.-?-databases-and-storage:-time?series-db-(influxdb/timescaledb)-or-postgresql-for-telemetry-and-evaluation-logs;-s3-or-gcs-for-datasets-and-models.-?-apis:-ros-2-services/topics
  • artifacts
  • c++-for-real?time-control
  • can
  • experiment-tracking
  • high-level-tech-choices-you-can-say:-?-languages:-python-for-perception/planning
  • jagaur-sbc?rk3588-with-octa?core-cpu
  • mipi?csi
  • npu-up-to-~6-tops
  • os
  • plus-vendor-inference-and-telemetry-apis.-then-you-drill-down.-hardware
  • rk3588?class-amr-board)-with-an-npu
  • running-on-an-armv8-sbc-designed-for-autonomous-robots-(e.g.
  • running-ros-2-nodes-in-containers.-?-cloud:-aws-or-gcp-for-offline-training
  • up-to-16-gb-lpddr4x
  • usb3
Share this project:

Updates

Submission history