Code and data from: milliWatt ultrasound for navigation in visually degraded environments on palm-sized aerial robots
Data files
Mar 11, 2026 version files 1.19 GB
-
dataset.zip
645.93 MB
-
README.md
8.90 KB
-
trained_model.zip
542.53 MB
Abstract
Tiny palm-sized aerial robots possess exceptional agility and cost-effectiveness in navigating confined and cluttered environments. However, their limited payload capacity directly constrains the sensing suite on board the robot, thereby limiting critical navigational tasks in GPS-denied wild scenes. Commonly used sensors for obstacle avoidance become ineffective in visually degraded conditions such as low visibility, dust, fog, or complete darkness. Inspired by bats, we propose Saranga, a low-power ultrasound-based perception stack that localizes obstacles using a dual sonar array. We present two key ideas to combat the low SNR: Physical noise reduction and a deep learning based denoising method. Firstly, we find an optimal and practical way to block propeller-induced noise. Secondly, we generate and train a neural network to denoise signals. For the first time ever, we enable a palm-sized aerial robot to navigate in visually degraded conditions with thin and transparent obstacles using only on-board sensing and computation. This repository contains the dataset and trained model for the Saranga neural network. The associated code is published as a linked Zenodo record. The contents are organized in chronological order of the pipeline: Dataset (Dryad) 1. Generated dataset used for training and evaluation. 2. Trained model checkpoints for the Saranga network.; Code (Zenodo): 1. Dataset generator script. 2. Training code for the Saranga network. 3. TensorFlow Lite quantization and Edge TPU compilation scripts for Saranga. 4. ROS2 Humble source codes for our onboard autonomy stack including drivers for ICU30201 ultrasonic sensors, perception and planning nodes, along with a MAVLink node for commanding the aerial robot. 5. Benchmark scripts to compare Saranga against classical methodologies. Detailed instructions are provided in the readme.md included in this repository.
Saranga is a neural network that detects obstacles in noisy ultrasonic sensor data. It denoises the input and estimates an impulse response corresponding to detected obstacles. We use this network to detect and dodge obstacles in visually degraded conditions on an aerial robot.
The network uses a UNet architecture with a four-layer encoder and four-layer decoder. It is designed to be lightweight and deployable on the Google Coral Mini onboard computer. We use this onboard computer to run Saranga as part of an obstacle avoidance pipeline for navigation in degraded conditions.
Repository Contents (in chronological order)
Please download the following files and extract them into the same directory:
Dryad
| # | File | Description |
|---|---|---|
| 1 | dataset.zip |
Training and testing datasets |
| 2 | trained_model.zip |
Trained model checkpoints |
Zenodo (code.zip)
| # | Folder | Description |
|---|---|---|
| 1 | dataset_generator/ |
Synthetic data generation pipeline |
| 2 | train/ |
Training code for Saranga |
| 3 | tpu_optimization/ |
Post-training quantization and Edge TPU compilation |
| 4 | visualize/ |
Lightweight script to visualize Saranga inference on the representative dataset |
| 5 | ros2_src/ |
ROS2 Humble source — drivers for the ICU30201 ultrasonic sensor, perception, and local planner pipeline |
| 6 | benchmark/ |
Benchmarking compute time of Saranga against classical techniques |
Initial Setup
For dataset generation, training and benchmarking:
conda create -n saranga python=3.11 -y
conda activate saranga
pip install tensorflow[and-cuda] keras wandb opencv-python \
numpy matplotlib scikit-image scipy Pillow tqdm ipdb keras-cv
wandb login
Both the quantization script (
tpu_optimization/) and the ROS2 pipeline (ros2_src/) require a ROS2 Humble environment (Ubuntu 22.04 recommended) — see the ROS2 Pipeline section below for setup. Instructions may also work on Ubuntu 24.04 with ROS2 Jazzy.
Dataset Generator
The generated dataset is already provided in
dataset.zipon Dryad. You only need to run this if you want to regenerate or customize the dataset.
cd dataset_generator/
- Open
generate4_wave.py— this is the entry point - Set
genOption = "test"(or"train") - Set the output folder
OUTPUT_DIR
python3 generate4_wave.py
Training
The trained model checkpoints are already provided in
trained_model.zipon Dryad. You only need to run this if you want to retrain the network.
cd train/
DS_PATH=../dataset OUT_PATH=/tmp/saranga_train/ N_FILTERS=8 IMG_WIDTH=512 LOSS_FUNCTION=mse LR=2e-4 python train.py
TFLite Quantization and Google Coral Edge TPU Compilation
You only need to run this if you want to recompile the TFLite models for the Edge TPU. The compiled outputs are already included in
code.zipundervisualize/mse_f8_a0428f_us_f8_w512/.
cd tpu_optimization/
After sourcing the ROS2 environment,
- Install
edgetpu_compiler: https://coral.ai/docs/edgetpu/compiler#download - Open
tfLiteConverter.pyand set:-
TRAIN_FOLDERto point to the extractedtrained_model.zipfolder (e.g.TRAIN_FOLDER = "../trained_model/") -
Checkpoint to convert (default is
ckpt-60, the checkpoint used in the paper):RESTORE_CHECKPOINT = os.path.join(TRAIN_PATH, "checkpoint/ckpt-60")
-
- Output will go to
OUT_DIRas defined intfLiteConverter.py
Post-training quantization requires a representative dataset, which is provided in the
./representative_dataset/folder. The script is already configured to use it. Generated tflite outputs are in./mse_f8_a0428f_us_f8_w512.
Visualize Saranga Inference
To quickly visualize Saranga inference on the representative dataset, run visualize.py from the visualize/ folder. It is already configured to load the tflite model and representative dataset from the current folder:
conda create -n saranga_viz python=3.11 -y
conda activate saranga_viz
pip install tflite-runtime "numpy<2" matplotlib
cd visualize/
python3 visualize.py
Change FRAME_INDEX in visualize.py to visualize a different frame.
Deployed ROS2 Obstacle Avoidance Pipeline
This step requires a ROS2 Humble setup: https://docs.ros.org/en/humble/Installation.html
We compiled ROS2 Humble from the official source and ported a minimal version onto the Google Coral Mini. The codebase is Linux-compliant and should work with any other desktop or embedded Linux distributions (Ubuntu, Debian, etc.).
Creating the ROS2 Workspace
The ros2_src/ folder is the src directory of a ROS2 workspace. To build it:
mkdir -p ~/ros2_ws/src
cp -r ros2_src/* ~/ros2_ws/src/
cd ~/ros2_ws
source /opt/ros/humble/setup.bash
colcon build
source install/setup.bash
See ros2_src/run_all.sh and ros2_src/run_cron.sh for the commands to launch our ROS2 nodes. Run the Python files from their respective folders.
ROS2 Nodes for Real-Time Autonomy / Obstacle Avoidance
| Node | Description |
|---|---|
teensy_pubsub |
ROS2 driver for the ultrasonic sensor. Reads over serial and publishes ICU30201 sensor data as icu_interfaces/msg/Icupkt. Teensy firmware is in ros2_src/teensy_pubsub/Arduino/icu30201_to_coral/ |
stacking_node.py |
Combines data from multiple ICU30201 sensors for the last N time steps into a single time-synced packet |
edge_detection.py |
Runs inference using Saranga on the Edge TPU |
proc.py |
Runs perception and planning algorithms |
icuAndMavLink.py |
Sends velocity commands to the ArduPilot autopilot over MAVLink |
batdeck.py |
Classical baseline algorithm used for comparison against Saranga |
Benchmark
These benchmarks run on the Google Coral Mini compute board. Setup instructions for the board are available at https://gweb-coral-full.uc.r.appspot.com/.
cd benchmark/
This folder contains scripts for benchmarking the compute time of Saranga against classical obstacle detection techniques on the same input size (32 × 512).
| Script | Method |
|---|---|
saranga.py |
Saranga (UNet on Edge TPU) |
classical_blur_sobel.py |
Gaussian blur + Sobel |
tv1_sobel.py |
Total variation denoising + Sobel |
tv1_golay_sobel.py |
Total variation + Savitzky-Golay + Sobel |
tdlms_sobel.py |
Two Dimensional LMS filter + Sobel |
saranga.py requires the compiled Edge TPU model at ./mse_f8_a0428f_us_f8_w512/model_int8_edgetpu.tflite.
Acknowledgements
- CRC16 checksum implementation uses CRC++ by Daniel Bahr (BSD license).
