Project Page | Arxiv | Video

If you find this code useful in your research, please cite:
@inproceedings{
tevet2025closd,
title={{CL}o{SD}: Closing the Loop between Simulation and Diffusion for multi-task character control},
author={Guy Tevet and Sigal Raab and Setareh Cohan and Daniele Reda and Zhengyi Luo and Xue Bin Peng and Amit Haim Bermano and Michiel van de Panne},
booktitle={The Thirteenth International Conference on Learning Representations},
year={2025},
url={https://openreview.net/forum?id=pZISppZSTv}
}
Ubuntu 20.04.5 with Python 3.8.19.~4GB RAM and a monitor.~50GB RAM (monitor is not required).Setup env
conda create -n closd python=3.8
conda activate closd
pip install -r requirement.txt
python -m spacy download en_core_web_sm
conda activate closd
cd <ISSAC_GYM_DIR>/python
pip install -e .
Copyright notes
The code will automatically download cached versions of the following datasets and models. You must adhere to their terms of use!
Multi-task
python closd/run.py\
learning=im_big robot=smpl_humanoid\
epoch=-1 test=True no_virtual_display=True\
headless=False env.num_envs=9\
env=closd_multitask exp_name=CLoSD_multitask_finetune
Sequence of tasks
python closd/run.py\
learning=im_big robot=smpl_humanoid\
epoch=-1 test=True no_virtual_display=True\
headless=False env.num_envs=9\
env=closd_sequence exp_name=CLoSD_multitask_finetune
Text-to-motion
python closd/run.py\
learning=im_big robot=smpl_humanoid\
epoch=-1 test=True no_virtual_display=True\
headless=False env.num_envs=9\
env=closd_t2m exp_name=CLoSD_t2m_finetune
exp_name=CLoSD_no_finetuneheadless=TrueMulti-task success rate
python closd/run.py\
learning=im_big env=closd_multitask robot=smpl_humanoid\
exp_name=CLoSD_multitask_finetune\
epoch=-1\
env.episode_length=500\
env.dip.cfg_param=7.5\
env.num_envs=4096\
test=True\
no_virtual_display=True\
headless=True\
closd_eval=True
Text-to-motion
python -m closd.diffusion_planner.eval.eval_humanml --external_results_file closd/diffusion_planner/saved_motions/closd/CloSD.pkl --do_unique
--train_platform_type WandBPlatform --eval_name <wandb_exp_name>https://huggingface.co/guytevet/CLoSD/blob/main/evaluation/closd/eval.log, this code should reproduce it.external_results_file .pkl file), run:
python closd/run.py\
learning=im_big robot=smpl_humanoid\
epoch=-1 test=True no_virtual_display=True\
headless=True env.num_envs=4096\
env=closd_t2m exp_name=CLoSD_t2m_finetune \
env.episode_length=300 \
env.save_motion.save_hml_episodes=True \
env.save_motion.save_hml_episodes_dir=<target_folder_name>L to start/stop recording.output/states/Blender vizualization
First, setup the Blender interpreter with:
blender -b -P closd/blender/setup_blender.py
Then visualize with:
blender -b -P closd/blender/record2anim.py -- --record_path output/states/YOUR_RECORD_NAME.pkl
Extract SMPL parameters
To extract the SMPL parameters of the humanoid, first download SMPL and place it in closd/data/smpl.
Then run:
python closd/utils/extract_smpl.py --record_path output/states/YOUR_RECORD_NAME.pkl
The script will save the SMPL parameters that can be visualize with standard SMPL tools, for example those of MDM or PHC.
Tracking controller (PHC based)
python closd/run.py\
learning=im_big env=im_single_prim robot=smpl_humanoid\
env.cycle_motion=True epoch=-1\
exp_name=my_CLoSD_no_finetune
Fine-tune for Multi-task
python closd/run.py\
learning=im_big env=closd_multitask robot=smpl_humanoid\
learning.params.load_checkpoint=True\
learning.params.load_path=output/CLoSD/my_CLoSD_no_finetune/Humanoid.pth\
env.dip.cfg_param=2.5 env.num_envs=3072\
has_eval=False epoch=-1\
exp_name=my_CLoSD_multitask_finetune
Fine-tune for Text-to-motion
python closd/run.py\
learning=im_big env=closd_t2m robot=smpl_humanoid\
learning.params.load_checkpoint=True\
learning.params.load_path=output/CLoSD/my_CLoSD_no_finetune/Humanoid.pth\
env.dip.cfg_param=2.5 env.num_envs=3072\
has_eval=False epoch=-1\
exp_name=my_CLoSD_t2m_finetune
Train for 1K epochs
For debug run, use learning=im_toy and add no_log=True env.num_envs=4
Generate Motion with the Stand-alone DiP
Full autoregressive generation (without target):
python -m closd.diffusion_planner.sample.generate\
--model_path closd/diffusion_planner/save/DiP_no-target_10steps_context20_predict40/model000200000.pt\
--num_repetitions 1 --autoregressive
Prefix completion with target trajectory:
python -m closd.diffusion_planner.sample.generate\
--model_path closd/diffusion_planner/save/DiP_multi-target_10steps_context20_predict40/model000300000.pt\
--num_repetitions 1 --sampling_mode goal\
--target_joint_names "traj,heading" --target_joint_source data
--target_joint_source random--target_joint_names
[traj,heading|
pelvis,heading|
right_wrist,heading|
left_wrist,heading|
right_foot,heading|
left_foot,heading]
Stand-alone Evaluation
python -m closd.diffusion_planner.eval.eval_humanml\
--guidance_param 7.5\
--model_path closd/diffusion_planner/save/DiP_no-target_10steps_context20_predict40/model000600343.pt\
--autoregressive
Train your own DiP
The following will reproduce the DiP used in the paper:
python -m closd.diffusion_planner.train.train_mdm\
--save_dir closd/diffusion_planner/save/my_DiP\
--dataset humanml --arch trans_dec --text_encoder_type bert\
--diffusion_steps 10 --context_len 20 --pred_len 40\
--mask_frames --eval_during_training --gen_during_training --overwrite --use_ema --autoregressive --train_platform_type WandBPlatform
To train DiP without target conditioning, add --lambda_target_loc 0
This code is standing on the shoulders of giants. We want to thank the following contributors that our code is based on:
MDM, PHC, MotionCLIP, text-to-motion, actor, joints2smpl, MoDi.
This code is distributed under an MIT LICENSE.
$ claude mcp add CLoSD \
-- python -m otcore.mcp_server <graph>