SDPC Diffusion Policy for Quadrotor Corridor Navigation
Trained checkpoint for SDPC (Safe Diffusion Policy with Constraint), an image-(and goal-)conditioned trajectory diffusion policy for quadrotor obstacle avoidance, with hard constraints enforced at inference time via an SLSQP projection step. Developed as part of a master's thesis at Paderborn University.
Code: ashiqlathief/SDPC-imagepolicy
What this checkpoint is
A single trained run H8_K20_Dmodels.ImagePoseCondUNet1DTemporalCondModel_Evitp_L384, seed 7 i.e. the ImagePoseCondUNet1DTemporalCondModel denoiser (UNet + ViT-P image encoder, goal/pose
conditioned). It predicts an 8-step action-chunk trajectory (horizon=8) via a 20-step DDPM denoising process (n_diffusion_steps=20), conditioned on 1 past FPV observation (n_obs_steps=1)
and the relative goal vector.
The policy was trained on FPV-camera demonstrations of a quadrotor navigating a corridor around
static cylinder obstacles in NVIDIA Isaac Lab, collected with a cascaded-PID controller (see the
isaac/scripts/quadcopter.py data-collection script in the repo above). It is deployed either
open-loop (plain diffusion sampling) or with an in-the-loop SLSQP projection step that hard-enforces
obstacle avoidance and corridor bounds at every denoising step — see the repo's README ("How SDPC
works") for that mechanism.
Model architecture
| Component | Value |
|---|---|
| Denoiser | ImagePoseCondUNet1DTemporalCondModel (1D temporal UNet, dim=32, dim_mults=(1,2,4,8)) |
| Image encoder | ViT-P (vit_img_size=96, vit_patch_size=8, vit_width=512, vit_depth=6, vit_heads=8) |
| Image conditioning dim | 384 |
| Goal/pose conditioning dim | 64 (relative goal vector goal_rel) |
| Action horizon | 8 |
| Observation steps | 1 |
| Diffusion steps (train/inference) | 20 |
| Predicts | epsilon (noise), l2 loss |
| Classifier-free guidance | condition_dropout=0.25, condition_guidance_w=1.2 |
Training data
- Simulator: NVIDIA Isaac Lab (Isaac Sim)
- Task: navigate a straight corridor around 5 static cylindrical obstacles to a target position
- Observation: single FPV RGB image (96×96) + robot pose
- Action: relative position delta per control step
- Demonstrations: PID-controller autopilot trajectories, recorded via
isaac/scripts/quadcopter.py - Normalization:
LimitsNormalizer(min/max per-dimension), embedded in this checkpoint so it can be evaluated without the original dataset present
Training procedure
| Hyperparameter | Value |
|---|---|
| Batch size | 8 |
| Learning rate | 1e-4 (Adam) |
| Gradient accumulation | 2 |
| Training steps | 100,000 |
| EMA decay | 0.995 |
| Train/test split | 0.9 |
| Loss | L2 on predicted noise, action-weighted (action_weight=10) |
Files
| File | Purpose |
|---|---|
state_best.pt |
Model + EMA weights at the best validation checkpoint |
model_config.pkl |
Denoiser architecture config (diffuser.utils.Config) |
diffusion_config.pkl |
GaussianDiffusion wrapper config |
dataset_config.pkl |
Dataset/normalizer config used at train time |
trainer_config.pkl |
Optimizer/training-loop config |
losses.pkl |
Training loss curve |
How to use
This checkpoint is meant to be loaded with the training/eval code in ashiqlathief/SDPC-imagepolicy, not standalone and
model_config.pkl/diffusion_config.pkl reference model classes defined in that repo's diffuser/models/ package.
# from the dpcc-thesis1 repo root, with env_isaaclab active
hf download ashiqali98/SDPC_diffusionmodel \
--local-dir isaac/logs/avoiding-crazyflie/diffusion/H8_K20_Dmodels.ImagePoseCondUNet1DTemporalCondModel_Evitp_L384/7
python scripts/eval_craziefliepos.py # RUN_DIR already defaults to the path above
import diffuser.utils as utils
RUN_DIR = "isaac/logs/avoiding-crazyflie/diffusion/H8_K20_Dmodels.ImagePoseCondUNet1DTemporalCondModel_Evitp_L384/7"
diff_exp = utils.load_diffusion(RUN_DIR, epoch="best", device="cuda:0")
diffusion = diff_exp.diffusion.eval()