navdp¶
NavDP (Cai et al., ICRA 2026, arXiv 2505.08712)
behind the arena_planners bridge, with X-NavDP (Yang et al., CoRL
2026, arXiv 2607.28560) as a second variant. NavDP is a 10-step diffusion policy over 24 waypoints, conditioned on the
last 8 RGB frames (Depth Anything V2 ViT-S tokens), the current depth frame and a 2D point goal, with a critic that
ranks its candidate trajectories. X-NavDP is the same network after RL post-training on wheeled, quadruped and
humanoid robots, with an embodiment embedding and a temporal-consistency guidance term. The planner drives toward
the goal pose from the front RGB-D camera and returns a 24-point waypoint path, one checkpoint per config.variant.
arena feature planners add navdp
arena launch sim:=gazebo robot:=jackal[camera=vln_rgbd] robot.planner:=navdp
arena launch sim:=gazebo robot:=jackal[camera=vln_rgbd] robot.planner:=navdp robot.mobile.config.variant:=x-navdp
robot.planner:=navdp selects robot.mobile:=vla. The planner accepts the goal pose only (goal_inputs: [pose]),
instructions never reach it. The robot needs an image and a depth sensor in model_params.yaml.
Inputs¶
| Datasource | Jackal topic (vln_rgbd) |
Model input |
|---|---|---|
rgb (image sensor) |
vln_camera/image, 224x224 rgb8 |
resized to 224 on the long side, zero-padded to 224x224, scaled to [0, 1], ImageNet-normalized by the network, the last 8 frames |
depth (depth sensor) |
vln_camera/depth_image, 256x256 32FC1 meters (16UC1 millimeters accepted) |
same letterbox, non-returns and values outside [0.1, 5] m set to 0, the current frame only |
robot_pose |
TF map to base_link |
the subgoal turned into [forward, left] meters in the robot frame |
subgoal |
plan from the nav2 planner server, global_costmap/costmap |
the farthest point up to 6 m along the plan whose straight chord from the robot stays clear of the costmap, used in place of the goal pose, the goal pose itself until a plan arrives |
depends.global_plan: true makes the adapter start a nav2 planner server (robot.mobile.global_planner, default
nav2/navfn) that replans to the goal every second, and the SubgoalGenerator datasource turns the plan into
subgoal. The model steers at that point, so it only ever sees a goal in line of sight. A goal pose without a route
left the robot stuck behind walls, see Notes.
Upstream trains with a camera randomized between 0.25 and 1.25 m height and 0 to 30 degrees downward pitch, at 69 or
110 degrees HFOV, and evaluates in simulation on a Dingo with a 640x360 camera of 68 degrees HFOV about 0.3 m above the
base (X-NavDP: a RealSense D455 model, 640x360, 0.63 m up, with a downward pitch). The jackal vln_rgbd camera
(224x224 RGB, 256x256 depth, 90 degrees HFOV, level, 0.98 m above the floor) lies inside the training height range
but between the two training HFOVs, and its square frames skip the letterbox padding upstream applies to 16:9 frames.
The model drops depth beyond 5 m, which leaves the sensor's 10 m range unused.
The goal vector is the pose datasource's offset to the subgoal in the robot frame: NavDP clips it to x in [0, 10] m and y in [-10, 10] m, X-NavDP scales it down to 25 m. Goal orientation is ignored. A subgoal behind the robot, as at the start of a route that leads backwards, would clip onto the robot's side and near the robot into candidates under 0.5 m, which hold still, so NavDP turns in place toward the subgoal's side until it lies ahead. X-NavDP keeps the goal as upstream does.
Actions¶
Each tick the policy denoises 16 (NavDP) or 8 (X-NavDP) candidate trajectories of 24 cumulative waypoints in the robot frame of the observation (x forward, y left) and returns the one with the best critic value (NavDP) or the best mean of the twin Q heads (X-NavDP). The bridge follows it with pure pursuit (lookahead 0.3 m, 0.5 m/s, the desired and maximum speed of upstream's MPC) for 0.2 s, then asks again. Upstream replans whenever inference and a 0.1 s sleep have passed (about 7 Hz with the latencies below) while an MPC tracks the last path, which the 5 Hz tick approximates.
NavDP: when every candidate scores below stop_threshold the path becomes a turn in place toward the side the best
candidates lean to, like the upstream server. Candidates shorter than 0.5 m are zeroed by the network and hold the
robot still.
X-NavDP: the previous path is transformed into the current robot frame and pulls the denoising toward it (RTC
guidance, off while the robot is stuck). Stuck means five consecutive observations within 0.25 m. While stuck the
planner executes a random candidate, and when that candidate reverses the committed direction it re-emits the
committed path for flip_pause_s before predicting again, where the upstream server sleeps.
Config¶
Set in planner.yaml > config, override per launch with robot.mobile.config.<key>:=<value>.
| Key | Default | Effect |
|---|---|---|
variant |
navdp |
navdp or x-navdp, the checkpoint and inference recipe. |
device |
auto |
Torch device, auto picks CUDA when available. |
seed |
0 |
Torch and numpy seed applied at every reset, which makes an episode replay identically. |
stop_threshold |
-3.0 |
NavDP only: the critic value under which no candidate is driven (upstream's evaluation default). |
embodiment |
wheeled |
X-NavDP only: wheeled, quadruped or humanoid, the embodiment embedding. |
flip_pause_s |
1.5 |
X-NavDP only: how long the committed path is kept after a direction flip while stuck. |
Weights and license¶
arena feature planners add navdp fetches model/navdp_pretrain.ckpt (543 MB) and model/x-navdp_posttrain.ckpt
(873 MB) from https://huggingface.co/InternRobotics/X-NavDP (revision 7cee38a, ungated), pinned by sha256. The first
is the NavDP checkpoint X-NavDP post-trains from and holds the original NavDP tensors. The NavDP README distributes
its own latest checkpoint through a Google form, which this planner does not use.
The NavDP code is CC BY-NC-SA 4.0 (stated in the upstream README, non-commercial use only), the X-NavDP code is MIT and
the vendored Depth Anything V2 code is Apache-2.0. Because the model card states no license for the weights beyond the
code terms, the checkpoints are not mirrored and weights.yaml points at the upstream repository. See LICENSE and
ATTRIBUTION.md. Cite both papers when using this planner:
@inproceedings{cai2026navdp,
title={NavDP: Learning Sim-to-Real Navigation Diffusion Policy with Privileged Information Guidance},
author={Cai, Wenzhe and Peng, Jiaqi and Yang, Yuqiang and Zhang, Yujian and Wei, Meng and Wang, Hanqing and Chen, Yilun and Wang, Tai and Pang, Jiangmiao},
booktitle={IEEE International Conference on Robotics and Automation (ICRA)},
year={2026}
}
@inproceedings{yang2026xnavdp,
title={X-NavDP: Generalizing Navigation Diffusion Policy to Novel Behavior and Embodiments with Group Q-score Reweighted Matching},
author={Yang, Tianyu and Zeng, Yiming and Cai, Wenzhe and Yang, Yuqiang and Peng, Jiaqi and Cheng, Hui and Pang, Jiangmiao and Wang, Tai},
booktitle={Conference on Robot Learning (CoRL)},
year={2026}
}
Notes¶
- Measured on an RTX PRO 6000 Blackwell with torch 2.14.1+cu130 and diffusers 0.33.1, one model per process: NavDP loads in 0.9 s with 0.51 GiB allocated and peaks at 0.59 GiB, 48 to 49 ms per step after a first step of 274 ms. X-NavDP loads in 0.9 s with 0.65 GiB allocated and peaks at 1.08 GiB, 89 to 99 ms per step after a first step of 275 ms.
- The route decides whether a goal behind walls is reached. On ten start and goal pairs of hospital_1 (the five
hospital_complexstages and five more from shifted seeds, 4 to 24 m apart, 2 to 8 pedestrians, 100 s and one episode per pair) NavDP reached 6 goals steering by the subgoal and 3 steering by the goal pose, X-NavDP 8 and 2. tests/test_model.pyneeds the weights and a CUDA device and checks documented invariants on a synthetic floor scene (the goal side decides the turn, the critic prefers the open floor over a wall at 0.6 m, an episode replays). The other tests run on CPU without weights,tests/test_network.pyon randomly initialized two-layer networks.