AMO (Adaptive Motion Optimization)是 UC San Diego 发表于 RSS 2025 的研究项目,用于超灵巧人形机器人全身控制。
它结合了强化学习(RL) 与轨迹优化(TO) ,实现实时自适应的全身运动控制,主要针对 Unitree G1 机器人(29自由度)进行验证。
开源地址:https://github.com/OpenTeleVision/AMO
论文地址:AMO: Adaptive Motion Optimization for Hyper-Dexterous Humanoid Whole-Body Control
示例效果1:

示例效果2:

1、获取代码
首先下载代码
bash
git clone https://github.com/OpenTeleVision/AMO.git
进入代码目录中
bash
cd AMO
2、搭建环境
依次执行下面三条指令:
bash
conda create -n amo python=3.8
conda activate amo
pip install -r requirements.txt
顺利的话,就成功啦~
【问题】新的显卡,需要CUDA版本更高
如果是比较新的显卡,比如50系列,需要安装CUDA版本比较新的才能正常使用,比如cuda12.8以上的版本
bash
pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
然后检查当前 PyTorch 版本,是否正常
bash
python -c "import torch; print(torch.__version__); print(torch.version.cuda)"
比如,成功输出:
2.11.0+cu128
12.8
3、运行推理
bash
python play_amo.py
看到可视化窗口:

【问题】torch.load 加载权重问题
问题是 torch.load 的 weights_only 参数默认值从 PyTorch 2.6 起改为 True,
而 adapter_norm_stats.pt 文件包含 numpy.core.multiarray._reconstruct 对象,不在默认安全列表中。
报错信息:
Traceback (most recent call last): File "/home/liguopu/lgp_dev/project/AMO/play_amo.py", line 350, in <module> env = HumanoidEnv(policy_jit=policy_jit, robot_type=robot, device=device) File "/home/liguopu/lgp_dev/project/AMO/play_amo.py", line 217, in init norm_stats = torch.load("adapter_norm_stats.pt") File "/home/liguopu/.holosoma_deps/miniconda3/envs/hsmujoco/lib/python3.10/site-packages/torch/serialization.py", line 1578, in load raise pickle.UnpicklingError(_get_wo_message(str(e))) from None _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint. (1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source. (2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message. WeightsUnpickler error: Unsupported global: GLOBAL numpy.core.multiarray._reconstruct was not an allowed global by default. Please use `torch.serialization.add_safe_globals(numpy.core.multiarray._reconstruct)` or the `torch.serialization.safe_globals(numpy.core.multiarray._reconstruct)` context manager to allowlist this global if you trust this class/function. Check the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html.
解决方案 :修改 play_amo.py
找到第 217 行:norm_stats = torch.load("adapter_norm_stats.pt")
改为:norm_stats = torch.load("adapter_norm_stats.pt", weights_only=False)
解决问题后,正常加载可视化,可以进行下面测试:
| 按键 | 控制量 | 范围 |
|---|---|---|
| W/S | 前进速度 Vx | -0.5, 0.5 |
| Q/E | 横向速度 Vy | -0.4, 0.4 |
| A/D | 偏航角速度 | - |
| Z/X | 躯干高度 | -0.5, 0.8 |
| J/U | 躯干偏航 | -1.57, 1.57 |
| K/I | 躯干俯仰 | -0.52, 1.57 |
| L/O | 躯干横滚 | -0.7, 0.7 |
| T | 切换手臂随机动作 | - |
示例 1
按下Z 键 (增加) 与X 键 (减少) 控制躯干高度(取值范围:-0.5, 0.8)


示例 2
按下J 键 (增加) 与U 键 (减少) 控制躯干偏航角(取值范围:-1.57, 1.57)


示例 3
按下K 键 (增加) 与I 键 (减少) 控制躯干俯仰角(取值范围:-0.52, 1.57)


示例 4
按下L 键 (增加) 与O 键 (减少) 控制躯干横滚角(取值范围:-0.7, 0.7)

示例 5
按下W 键 (增加) 与S 键 (减少) 控制X 方向速度(取值范围:-0.5, 0.5)


示例 6
按下Q 键 (增加) 与E 键 (减少) 控制Y 方向速度(取值范围:-0.4, 0.4)

示例 7
按下A 键 (增加) 与D 键 (减少) 控制偏航转动

示例 8
可以尝试各类指令组合,也可以使用超出分布范围的指令,全部由同一个模型执行。
还可以在此基础上叠加手臂动作 。(按下T 键开启 / 关闭手臂动作)

4、代码分析
代码结构,如下所示:
AMO/
├── play_amo.py # 主程序:交互式可视化与推理
├── requirements.txt # Python依赖
├── g1.xml # MuJoCo机器人模型文件
├── adapter_jit.pt # 适配器网络(TorchScript)
├── adapter_norm_stats.pt # 适配器归一化统计
├── amo_jit.pt # 主策略网络(TorchScript)
├── meshes/ # 机器人网格文件(STL等)
├── img/ # 文档图片资源
└── README.md # 项目说明
1. play_amo.py --- 主控程序
这是项目的核心入口,实现了交互式 MuJoCo 仿真环境,主要功能模块:
HumanoidEnv 类
-
初始化 :加载 G1 的 MuJoCo 模型 (
g1.xml),配置 23 个关节的 PD 控制参数(刚度、阻尼、力矩限制) -
键盘交互:通过 GLFW 捕获键盘输入,实时调整控制指令
-
观察空间构建:组合本体感知数据(角速度、关节位置/速度、历史动作)与高层指令
关键方法
| 方法 | 功能 |
|---|---|
extract_data() |
从 MuJoCo 数据中提取关节状态、IMU 数据 |
get_observation() |
构建策略网络输入:包含本体感知 + 适配器输出 + 历史缓冲区 |
run() |
主循环:每 10 个仿真步(sim_decimation=10)执行一次策略推理 |
控制指令映射(键盘)
| 按键 | 控制量 | 范围 |
|---|---|---|
| W/S | 前进速度 Vx | -0.5, 0.5 |
| Q/E | 横向速度 Vy | -0.4, 0.4 |
| A/D | 偏航角速度 | - |
| Z/X | 躯干高度 | -0.5, 0.8 |
| J/U | 躯干偏航 | -1.57, 1.57 |
| K/I | 躯干俯仰 | -0.52, 1.57 |
| L/O | 躯干横滚 | -0.7, 0.7 |
| T | 切换手臂随机动作 | - |
网络架构
python
# 主策略网络(RL训练得到)
policy_jit = torch.jit.load("amo_jit.pt") # 输入: obs + extra_hist
# 适配器网络(处理高层躯干指令)
adapter = torch.jit.load("adapter_jit.pt") # 输入: [height, yaw, pitch, roll] + arm_dof
PD 控制
python
torque = (pd_target - dof_pos) * stiffness - dof_vel * damping
torque = clip(torque, -torque_limits, torque_limits)
2. g1.xml --- MuJoCo 机器人模型
-
基于 MuJoCo Menagerie 的 Unitree G1 模型
-
定义了 23 自由度(不含手部)的机器人运动学/动力学
-
包含碰撞体、惯性属性、传感器(IMU、角速度)
-
引用
meshes/目录下的 STL 网格文件
3. 预训练模型文件
| 文件 | 说明 |
|---|---|
amo_jit.pt |
主 RL 策略网络(TorchScript),输入观察向量,输出 15 维动作 |
adapter_jit.pt |
适配器网络,将高层躯干指令映射为参考姿态 |
adapter_norm_stats.pt |
包含 input_mean/std 和 output_mean/std,用于标准化 |
分享完成~