7.将L21灵巧手移植到开源项目Bi-DexHands上
·
开源代码结构框架
Bi-DexHands/
├── assets/ # [关键] 存放机器人和物体的模型文件 (URDF, MJCF, Meshes)
├── bidexhands/
│ ├── algorithms/ # 存放RL/MARL算法的实现 (如 ma_ppo, happo 等)
│ ├── tasks/ # [核心] 环境定义的源代码
│ │ ├── shadow_hand_over.py # 具体任务:例如双手交接
│ │ ├── shadow_hand_catch.py # 具体任务:例如接球
│ │ ├── base/ # 基础类,定义了通用的仿真接口
│ │ └── ...
│ └── utils/ # 工具脚本 (解析配置、处理数据等)
├── cfg/ # [关键] 配置文件目录
│ ├── config.yaml # 总入口配置
│ ├── task/ # 环境的具体参数 (重力、物理参数、奖励权重)
│ │ ├── ShadowHandOver.yaml
│ │ └── ...
│ └── train/ # 训练算法的超参数 (学习率、Batch size等)
│ ├── ShadowHandOverPPO.yaml
│ └── ...
├── train.py # 训练入口脚本
└── ...
任务注册
代码路径配置
1.复制task下的任务文件shalow_hand_over.py,改成自己的名称l21_hand_over.py
然后把类改成自己的名字
class L21HandOver(BaseTask)
2.复制cfg文件夹下的.yaml文件,改成自己的yaml文件
# 1. 这里添加任务名称,必须与 --task 参数一致
name: L21HandOver
env:
# 2. 修改环境名称,用于日志记录
env_name: "l21_hand_over"
3.去任务表里面添加自己的任务名
在Util文件夹下的config.py中添加"L21HandOver"任务(找到自己任务应该对应的位置)
def retrieve_cfg(args, use_rlg_config=False):
if args.task in ["ShadowHandOver", "L21HandOver","ShadowHandCatchUnderarm", "ShadowHandTwoCatchUnderarm", "ShadowHandCatchAbreast", "ShadowHandReOrientation",
"ShadowHandCatchOver2Underarm", "ShadowHandBottleCap", "ShadowHandDoorCloseInward", "ShadowHandDoorCloseOutward",
"ShadowHandDoorOpenInward", "ShadowHandDoorOpenOutward", "ShadowHandKettle", "ShadowHandPen", "ShadowHandSwitch",
"ShadowHandPushBlock", "ShadowHandSwingCup", "ShadowHandGraspAndPlace", "ShadowHandScissors", "AllegroHandOver", "AllegroHandCatchUnderarm"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/config.yaml".format(args.algo), "cfg/{}.yaml".format(args.task)
elif args.task in ["ShadowHandLiftUnderarm"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/lift_config.yaml".format(args.algo), "cfg/{}.yaml".format(args.task)
elif args.task in ["ShadowHandBlockStack"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/stack_block_config.yaml".format(args.algo), "cfg/{}.yaml".format(args.task)
elif args.task in ["ShadowHand", "ShadowHandReOrientation"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/config.yaml".format(args.algo), "cfg/{}.yaml".format(args.task)
elif args.task in ["ShadowHandMetaMT4", "ShadowHandMetaMT1"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/config.yaml".format(args.algo), "cfg/meta_env_cfg/{}.yaml".format(args.task)
elif args.task in ["ShadowHandMetaMT1"]:
return os.path.join(args.logdir, "{}/{}/{}".format(args.task, args.algo, args.algo)), "cfg/{}/config.yaml".format(args.algo), "cfg/meta_env_cfg/{}.yaml".format(args.task)
else:
warn_task_name()
4.在Util文件夹下的config.py中添加
# 1. 在文件顶部的 import 区域,添加这一行:
from bidexhands.tasks.l21_hand_over import L21HandOver
5.运行训练代码
python train.py --task=L21HandOver --algo=ppo
如果代码可以正常跑通,代表任务注册成功
添加自己的模型
在asset文件夹下,添加自己的模型文件
将URDF文件导入进去,找到 _create_envs 函数。我们需要把 ShadowHand 的 MJCF 文件替换成你的 URDF 文件。
asset_root = "../../assets"
# 这里填入你的URDF相对路径
shadow_hand_asset_file = "urdf/linkhand/L21right/linkerhand_l21_right.urdf"
# 暂时两个手都用同一个模型(之后你可以做一个左手的URDF或者在代码里旋转这个手)
shadow_hand_another_asset_file = "urdf/linkhand/L21right/linkerhand_l21_right.urdf"
L21灵巧手16个自由度,修改奖励函数的指尖名称:
# 根据URDF文件结构提取的末端 Link 名称
# 注意:除大拇指外,其他手指在 URDF 中只定义到了 index_middle 这一级
self.fingertips = [
"index_middle", # 食指末端
"middle_middle", # 中指末端
"ring_middle", # 无名指末端
"pinky_middle", # 小指末端
"thumb_distal" # 大拇指末端
]
# 如果第二只手用的是同一个 URDF,名字是一样的
self.a_fingertips = self.fingertips
修改手掌中心:
# 用于计算手和物体的整体距离
self.hand_center = ["hand_base_link"]
手的模型显示如下:

URDF 中定义的 type="revolute"(可旋转)关节如下:
Index (食指): index_mcp_roll, index_mcp_pitch, index_pip (3个)
Middle (中指): middle_mcp_roll, middle_mcp_pitch, middle_pip (3个)
Ring (无名指): ring_mcp_roll, ring_mcp_pitch, ring_pip (3个)
Pinky (小指): pinky_mcp_roll, pinky_mcp_pitch, pinky_pip (3个)
Thumb (大拇指): thumb_cmc_roll, thumb_cmc_yaw, thumb_cmc_pitch, thumb_mcp, thumb_ip (5个)
这里的URDF文件中写着有17个可旋转关节,我查看了具体的参数,也是16个,代表着16个自由度,有一个关节不可动。
修改yaml文件
修改路径
asset:
assetRoot: "../assets"
# [修改] 保持与 Python 代码一致,指向你的 L21 URDF
# 虽然 Python 代码会覆盖这个值,但改了更清晰
assetFileName: "urdf/linkhand/L21right/linkerhand_l21_right.urdf"
还有修改关节限位等等,之后再根据任务进行调整
运行代码
python train.py --task=L21HandOver --algo=ppo
看到手已经可以成功导入到里面了,说明移植基本成功了

接下来就是修改环境和修改奖励函数了
修改isaccgym环境
调整手的位置和角度
找到 _create_envs 函数中定义 shadow_hand_start_pose 的部分
# 设置初始位姿
shadow_hand_start_pose = gymapi.Transform()
shadow_hand_start_pose.p = gymapi.Vec3(*get_axis_params(0.5, self.up_axis_idx))
shadow_another_hand_start_pose = gymapi.Transform()
shadow_another_hand_start_pose.p = gymapi.Vec3(0, -1, 0.5)
shadow_another_hand_start_pose.r = gymapi.Quat().from_euler_zyx(0, 0, 3.1415)
修改为
# 设置手和物体的初始位置和姿态
shadow_hand_start_pose = gymapi.Transform()
# [修改位置] x, y, z (单位: 米)
# 例如:放在原点上方 0.5 米处
shadow_hand_start_pose.p = gymapi.Vec3(0.0, 0.0, 0.5)
# [修改角度] 欧拉角 (弧度制)。
# 0 表示不转。1.57 ≈ 90度,3.14 ≈ 180度。
# 例如:绕 Z 轴旋转 90 度,让手掌换个朝向
shadow_hand_start_pose.r = gymapi.Quat.from_euler_zyx(0.0, 0.0, 1.57)
shadow_another_hand_start_pose = gymapi.Transform()
# [修改位置] 比如拉近一点,设为 -0.6
shadow_another_hand_start_pose.p = gymapi.Vec3(0.0, -0.6, 0.5)
# [修改角度] 保持面对面 (绕 Z 轴 180 度)
shadow_another_hand_start_pose.r = gymapi.Quat.from_euler_zyx(0.0, 0.0, 3.14159)
修改物体位置
找到下面代码段
object_start_pose = gymapi.Transform()
object_start_pose.p = gymapi.Vec3()
object_start_pose.p.x = shadow_hand_start_pose.p.x
# 关键参数在这里!
pose_dy, pose_dz = -0.39, 0.04
object_start_pose.p.y = shadow_hand_start_pose.p.y + pose_dy
object_start_pose.p.z = shadow_hand_start_pose.p.z + pose_dz
改成以下
# 修改偏移量
pose_dx = 0.0 # 新增 X 轴偏移
pose_dy = -0.05 # Y 轴偏移 (根据你的手掌中心调整,原代码 -0.39 可能是针对 ShadowHand 的手腕长度)
pose_dz = 0.15 # Z 轴高度 (给它一点高度让它落下)
object_start_pose.p.x = shadow_hand_start_pose.p.x + pose_dx
object_start_pose.p.y = shadow_hand_start_pose.p.y + pose_dy
object_start_pose.p.z = shadow_hand_start_pose.p.z + pose_dz
# [修改物体角度] 如果你想让物体斜着生成
object_start_pose.r = gymapi.Quat.from_euler_zyx(0.0, 0.5, 0.0)
还要记得修改目标位置(后面更新)
然后看着页面调整

看着是不是和官网的历程很像了

奖励函数修改(目前还不太知道要怎么改,学学PPO之后再改)
之后继续更新
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)