Omnidirectional Trajectory-Risk Learning for Agile Quadrotor Dynamic Avoidance
Yifan He†1 · Yang Liu†1,2 · Wenhao Zhao†1 · Hai Lin1 · Deping Zhang1 · Mingze Ma1 · Xin Zhou1
Fei Gao1,2 · Huan Yu*1,2 · Zipeng Dai*1 · Ziming Ding*1
1Differential Robotics · 2Zhejiang University †equal contribution · *corresponding
OmniRisk moves trajectory-risk evaluation offline. Onboard, one forward pass scores every candidate
maneuver around the drone, so planning cost does not grow with the number of obstacles.
Demos
Repeated trials
![]() Single-ball tests 30 trials, all collision-free |
![]() Multi-ball tests 4 trials, 12 balls in total, all collision-free |
Open vs. constrained space
![]() Open space top view · ×0.2 · nothing nearby, free to dodge in any direction |
![]() Constrained space top view · ×0.2 · obstacles on both sides, escape stays in the free corridor |
Dynamic + static obstacles

Crossing ball among rocks
dodges a ball thrown across its path while clearing rock-shaped obstacles
Different thrown objects
![]() Thrown ball motion trails show the ball's arc and the escape path |
![]() Tennis ball small and fast, only a few LiDAR returns |
![]() Dumbbell irregular rigid body, tumbling in flight |
![]() Plush toy soft, deforms mid-air |
Results
|
Planning latency on Jetson Orin NX (6 obstacles)
|
Zero-shot real-world success (n = 50 per cell)
|
Note
FAPP plans faster (~17 ms) but refines a single trajectory; with 6 obstacles at 10 m/s its success drops to 8% vs. 84% for OmniRisk.
Hardware
![]() |
|
Roadmap
- Training code, simulator & dataset generator
- ROS planner & real-world deployment guide
- Pretrained models
- Simulation demos
- Project page
Quick start
Tested on Ubuntu 20.04 + ROS Noetic + CUDA (x86) and Jetson Orin NX (JetPack 5.1.x).
Repository structure
OmniRisk/ learning-based planner: network, training and the ROS planning node
Simulator/ CUDA LiDAR / depth simulator and dataset generator
Controller/ SO(3) quadrotor dynamics and controller for simulation
ros_ws/ onboard stack: FAST-LIO, M-detector, px4ctrl, EKF, Livox driver
docker/ simulation (x86) and deployment (Jetson) images
scripts/ one-shot install and build
Installation
bash scripts/build.sh # install dependencies + build bash scripts/build.sh --build-only # rebuild only bash scripts/build.sh --no-sim # skip Controller / Simulator
Pretrained model
mkdir -p OmniRisk/saved/run_1 wget -O OmniRisk/saved/run_1/epoch60.pth \ https://github.com/VANdexj/OmniRisk/releases/download/v1.0/omnirisk_epoch60.pth
Then run with --trial 1 --epoch 60 (trt_transfer.py uses this checkpoint by default).
Simulation
# T1 Dynamics source Controller/devel/setup.bash roslaunch so3_quadrotor_simulator simulator_attitude_control.launch # T2 Environment + LiDAR source Simulator/devel/setup.bash rosrun sensor_simulator sensor_simulator_cuda # T3 M-detector source ros_ws/devel/setup.bash roslaunch m_detector detector_mid360.launch points_topic:=/lidar_points points_in_world_frame:=false odom_topic:=/sim/odom # T4 OmniRisk (add --flight_mode nav, then set the goal with RViz 2D Nav Goal) source ros_ws/devel/setup.bash && source omnirisk_env/bin/activate cd OmniRisk && python omnirisk_node.py --trial <n> --epoch <k> --odom_topic /sim/odom --lidar_topic /lidar_points # T5 RViz source ros_ws/devel/setup.bash rviz -d OmniRisk/omnirisk.rviz # T6 Joystick goal source ros_ws/devel/setup.bash cd OmniRisk && python3 rc_goal_teleop.py _odom_topic:=/sim/odom
Training
cd Simulator && source devel/setup.bash rosrun sensor_simulator dataset_generator # → dataset/ cd ../OmniRisk && source ../omnirisk_env/bin/activate python train.py # → saved/run_<n>/epoch<k>.pth tensorboard --logdir saved
TensorRT acceleration
cd OmniRisk python trt_transfer.py --trial <n> --epoch <k> # run on the deployment device python omnirisk_node.py --use_tensorrt 1
Real-world deployment
# In every terminal source ros_ws/devel/setup.bash # T1 MAVROS sudo chmod 666 /dev/ttyACM0 roslaunch mavros px4.launch fcu_url:=/dev/ttyACM0:57600 # After MAVROS connects: IMU / attitude at 200Hz rosrun mavros mavcmd long 511 105 5000 0 0 0 0 0 # HIGHRES_IMU rosrun mavros mavcmd long 511 31 5000 0 0 0 0 0 # ATTITUDE_QUATERNION rosrun mavros mavcmd long 511 83 5000 0 0 0 0 0 # ATTITUDE_TARGET # T2 MID360 + FAST-LIO + EKF roslaunch fast_lio fastlio_ekf.launch # T3 px4ctrl roslaunch px4ctrl run_ctrl.launch # T4 M-detector roslaunch m_detector detector_mid360.launch # T5 OmniRisk source omnirisk_env/bin/activate cd OmniRisk && python omnirisk_node.py --use_tensorrt 1 # T6 RViz rviz -d OmniRisk/omnirisk.rviz # T7 Joystick goal (_input_mode:=usb | mavros) cd OmniRisk && python3 rc_goal_teleop.py _input_mode:=usb # Takeoff / land rostopic pub -1 /px4ctrl/takeoff_land quadrotor_msgs/TakeoffLand "takeoff_land_cmd: 1" rostopic pub -1 /px4ctrl/takeoff_land quadrotor_msgs/TakeoffLand "takeoff_land_cmd: 2" # Checks rostopic hz /ekf_quat/ekf_odom # > 50Hz rostopic hz /mavros/setpoint_raw/attitude # > 100Hz rostopic hz /so3_control/pos_cmd
Citation
@article{he2026omnirisk, title = {OmniRisk: Omnidirectional Trajectory-Risk Learning for Agile Quadrotor Dynamic Avoidance}, author = {He, Yifan and Liu, Yang and Zhao, Wenhao and Lin, Hai and Zhang, Deping and Ma, Mingze and Zhou, Xin and Gao, Fei and Yu, Huan and Dai, Zipeng and Ding, Ziming}, journal = {arXiv preprint arXiv:2609.18191}, year = {2026} }
Acknowledgements
This work was carried out at Differential Robotics; we are especially grateful to Zipeng Dai for his invaluable mentorship.
License
Released under the MIT License.








