mhsnar's picture
Add files using upload-large-folder tool
f8faa82 verified
|
Raw History Blame Contribute Delete
5.25 kB

Avoiding: regenerating everything

Everything needed to reproduce the D3IL avoiding-v0 results of appendix A.2.2.1: the ten baselines, the table and the figure. Self-contained apart from the conda environment.

avoiding/
  baselines/      DiRecT's released d3il code, plus the 96-demo dataset
  checkpoints/    the trained diffusion model, normalizer and dynamics fit
  ours/           our planner, the twelve modules the avoiding pipeline imports
  scripts/        the sweep, the table builder, the summary collector
  env/            conda environment export

1. Environment

conda env create -f env/direct-d3il.yml -n direct-d3il
conda activate direct-d3il

Python 3.10.20, torch 2.11.0+cu128, numpy 2.2.6, mujoco 2.3.7, gym 0.23.1, qpth 0.0.18 (SafeDiffuser's QP), casadi 3.7.2 and scipy 1.13.1.

Two things the export cannot capture.

CUDA. The pin is the cu128 wheel. On a host with an older driver install the matching build instead; the CUDA 13 build of this release needs driver

= 580 and silently fails to load below it. Everything here also runs on CPU, roughly 3x slower.

MuJoCo. gym==0.23.1 is pre-Gymnasium and warns loudly on import. Harmless. A headless host needs MUJOCO_GL=osmesa or egl.

2. Put the checkpoint where the code looks for it

The eval script reads checkpoints from logs/ under the code directory:

mkdir -p baselines/logs
cp -r checkpoints/avoiding-v0 baselines/logs/

model_ema_10.pth is the checkpoint behind every reported number. Do not substitute another: the table was produced from this one, shared by all ten methods.

3. Constraint set

The twelve-constraint setting is opt-in, gated on one environment variable, so the default reproduces DiRecT's published nine-constraint numbers.

export D3IL_HARD=1     # 10 discs + 2 half-planes   <- what A.2.2.1 reports
unset  D3IL_HARD       #  7 discs + 2 half-planes   <- DiRecT's own setting

The gate lives in two places and they must agree: baselines/obstacles.py (NOVEL_CIRCULAR_HARD) and ours/d3il_tasks.py (AV_CIRCLES_HARD). Check with:

D3IL_HARD=1 python -c "import obstacles as o; print(o.count_constraints('novel'))"   # 12

4. Regenerate the baselines

export AVOIDING_ROOT=$PWD
bash scripts/run_hard_sweep.sh          # ~10 h on one GPU, sequential

Resumable: a stage whose summary.json exists is skipped, so a kill costs only the stage in flight. Per-stage wall clock ranges from 3 min (Classifier Guidance) to 2.5 h (SafeDiffuser-RoS). No retraining happens; the constraints act at sampling time only, which is why a new constraint set costs one evaluation pass.

DiRecT itself is not in the sweep script. Run it with:

cd baselines && D3IL_HARD=1 python eval.py \
  --diffusion-exp-name x0pred --diffusion-cp 10 \
  --guidance-method direct --constraints --no-early-stop \
  --n-sampling-steps 32 --random-repeat 100 \
  --exp-name direct_hard_12c --seed 0 --device cuda:0

5. Table and figure

python scripts/collect_hard.py          # control vs hard, side by side
python scripts/build_hard_table.py      # the LaTeX rows of Table 8
python ours/make_d3il_grid.py --out d3il_grid.png

make_d3il_grid.py must see the same D3IL_HARD value as the runs it draws, or the scene will not match the trajectories.

6. Our own row

Not yet measured on the twelve-constraint setting; the figure keeps an empty panel for it. To run it:

cd ours && D3IL_HARD=1 python run_d3il_pair.py \
  --task avoiding --n-goals 10 --seeds 5 --out avoiding_hard.pkl

10 goals x 5 seeds = 50 instances, of which 45 are feasible: the goal band linspace(0.395, 0.615, 10) puts its last goal 0.6 mm outside the half-planes, so those five are infeasible by construction and are excluded rather than scored as failures.

7. Numbers to check against

Safety rate at twelve constraints, 100 episodes per method:

method SR method SR
Diffuser 0.01 Augmented Lagrangian 0.00
Classifier Guidance 0.00 SafeDiffuser-RoS 0.06
Gradient Guidance 0.24 SafeDiffuser-ReS 0.24
Projected Diffusion 0.45 SafeDiffuser-TVS 0.02
Primal-Dual 0.05 DiRecT 0.87

Primal-Dual and Augmented Lagrangian need --guidance-last-steps 50; at the default they crash the simulator. The sweep script already passes it.

A sanity check before trusting a sweep: at nine constraints DiRecT scores 1.00/1.00 with avg_steps 64.95 and avg_ipopt_iters 8.569290303738319. That last figure reproduces bit-for-bit and is the quickest way to confirm the checkpoint and flags are right.

8. Known traps

Our solver is not deterministic across runs. Identical code and seeds gave 42/45 on one day and 41/45 on another, one instance flipping at the second-tightest goal. Treat a single run as a sample.

avg_steps and the IPOPT counts are the fingerprints. A rate alone will not tell you whether the configuration matches; those two will.

The three extra keep-outs are virtual. They have no MuJoCo body and never can: 53 of the 96 demonstrations pass through where they sit, so making them physical would invalidate the training data for every baseline.