commit 0b727785c67473c093cd5dfa7530b9828a4dba0c Author: sunxianghui Date: Mon Jul 27 14:13:00 2026 +0800 Add LinkerHand Isaac Sim bridge and G20 assets. Includes G20 PLAN/cmd_u8 bridge, joint mapping, dual-hand sim scripts, and G20/L20/O6 URDF with USD payloads for Isaac Sim integration. Co-authored-by: Cursor diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3b31bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.pyc +*.pyo +.DS_Store diff --git a/docs/G20_Isaac_实现说明.md b/docs/G20_Isaac_实现说明.md new file mode 100644 index 0000000..0352451 --- /dev/null +++ b/docs/G20_Isaac_实现说明.md @@ -0,0 +1,328 @@ +# G20 左手 · Isaac Sim 仿真实现说明 + +本文记录 **Isaac G20 PLAN 名义弧度桥** 从 URDF 到 USD、再到可跑仿真的完整实现过程,以及相对原始 URDF / 自动转换结果的全部具体改动。 + +- **函数调用与逐步逻辑**:见 [`G20_Isaac_技术详解.md`](./G20_Isaac_技术详解.md)(推荐先读此文理解代码) +- **MuJoCo 对照**:`/home/lxqs/linker_hand_mujoco_ros2/docs/G20_MuJoCo_实现说明.md` / `G20_MuJoCo_技术详解.md` + +--- + +## 1. 目标与数据流 + +### 1.1 目标 + +- 在 Isaac Sim / PhysX 中仿真 LinkerHand G20 **左手**。 +- 默认兼容真机 SDK 话题:`/g20/cb_left_hand_control_cmd`(0~255)。 +- 可选 PLAN 名义弧度话题(按关节名)。 +- 关节名、映射、mimic、拇指上限 **1.47**、对比视角与 MuJoCo 桥对齐。 +- 默认 **位置硬写**(`set_dof_positions`),可选 `--pd-drive`。 + +### 1.2 端到端数据流 + +```text +/g20/cb_left_hand_control_cmd (默认,0~255) + 或 /retarget/g20/left/joint_target_nominal (--plan-nominal) + 或 /cb_left_hand_control_cmd (--legacy-sdk,旧无前缀) + │ + ▼ + joint_mapping.py + · range_to_arc / sdk_range_to_*(hand="G20", side="left") + · SDK15:thumb_mcp = arc/1.02 + · SDK16..19:*_pip = arc/0.89 + · complete_g20_mimic_positions + │ + ▼ + isaac_g20_plan_bridge.py + · Articulation 硬写 set_dof_positions(默认) + 或 set_dof_position_targets(--pd-drive) + · 每 render 帧内 phys_per_render 次物理步进(默认 16) + │ + ▼ + /sim/isaac/g20/left/joint_state + + Omniverse 透视相机(COMPARE_*) +``` + +--- + +## 2. 关键文件路径 + +| 角色 | 绝对路径 | +|------|----------| +| 启动脚本 | `/home/lxqs/isaacsim/linkerhand/run_g20_plan.sh` | +| 桥主程序 | `/home/lxqs/isaacsim/linkerhand/isaac_g20_plan_bridge.py` | +| 关节映射 | `/home/lxqs/isaacsim/linkerhand/joint_mapping.py` | +| 源 URDF | `/home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left.urdf` | +| 网格 | `/home/lxqs/isaacsim/linkerhand/urdf/g20/left/meshes/*.STL` | +| 默认 USD 根 | `/home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/linkerhand_g20_left.usda` | +| Isaac Python | `$ISAAC_SIM_DIR/python.sh`(默认 `/home/lxqs/isaacsim/_build/linux-x86_64/release/python.sh`) | + +**旁路(非 PLAN 桥,勿混淆):** + +- `linker_hand_dual_sim.py` + `run_sim.sh`:另一套双端/稳定性仿真,默认 PD 参数不同。 + +--- + +## 3. 从 URDF 到 USD + +### 3.1 URDF 来源 + +- SolidWorks → URDF Exporter 导出的 G20 左手。 +- 与 MuJoCo 仓内 URDF/网格同源;网格与 MuJoCo 侧 **MD5 一致**。 +- 当前仅有 **左手** USD;无 G20 右手资产。 + +### 3.2 URDF 上我们改过什么 + +| 改动项 | 具体内容 | +|--------|----------| +| `thumb_cmc_roll` 上限 | `upper="1.47"`(rad);注释/映射写明相对原 **1.4** 试调 | +| mimic(URDF 内保留) | `thumb_ip` ← `thumb_mcp` × **1.02**;四指 `*_dip` ← `*_pip` × **0.89** | +| 其余限位 | 与 MuJoCo 侧同一套(见 MuJoCo 文档关节表) | + +Isaac 侧 Physics USD 中对应角度上限: + +- `physics:upperLimit = 84.22480`(度)= **1.47 rad**(`payloads/Physics/physics.usda` 中 `thumb_cmc_roll`)。 + +### 3.3 转换方式(重要) + +**运行时不导入 URDF。** + +桥内 `_load_g20()` 使用: + +```text +stage_utils.add_reference_to_stage(usd_path=默认 .usda) +``` + +挂的是 **预烘焙 USD**。根层标注: + +```text +creator = "URDF USD Converter v0.1.3" +``` + +即离线用 Isaac / URDF→USD 转换器生成,再经手改 Physics / 碰撞实例后定稿。 + +### 3.4 USD 资源树(转换产物结构) + +```text +linkerhand_g20_left.usda # 根;默认 Physics variant = "physx" + └── payloads/ + base.usda + robot.usda + geometries.usd / materials.usda + instances.usda # 碰撞实例(convexHull + 选择性开关) + Physics/ + physics.usda # 关节限位等 + physx.usda # PhysX articulation / 自碰等 + mujoco.usda # 转换器附带的 Mjc 层(桥走 physx) + hand_body_limits.usda # 刚体线/角速度与阻尼限制 +``` + +桥启动时显式:`set_prim_variants(..., [("Physics", "physx")])`。 + +### 3.5 相对「纯 URDF→USD」我们改过的 Physics / 碰撞 + +#### A. 自碰与求解器(`physx.usda`) + +| 项 | 值 | +|----|-----| +| `physxArticulation:enabledSelfCollisions` | **1**(开) | +| solver 位置/速度迭代 | **32 / 4** | +| `sleepThreshold` | **0.005** | +| 关节 `maxJointVelocity` | **171.887** | +| 关节 `armature` | **0.05** | + +#### B. 刚体限速(`hand_body_limits.usda`) + +各 link 大致: + +- `maxLinearVelocity = 3.0` +- `maxAngularVelocity = 360.0` +- linear/angular damping **6.0** + +目的:降低 PD 握拳等场景下爆炸/乱飞。 + +#### C. 选择性碰撞(`instances.usda`)——核心手改 + +碰撞近似:`physics:approximation = "convexHull"`,`purpose = "guide"`。 +注释写明策略:**掌心 + 指尖开碰撞;近端/中节多数关掉**,避免张开姿态假嵌入、以及 PD 握拳末端爆炸。 + +| 碰撞 | 典型 link(`physics:collisionEnabled`) | +|------|------------------------------------------| +| **ON (=1)** | `hand_base_link`(掌心)、`thumb_distal`、`index_distal`、`middle_distal`、`pinky_distal`(`ring_distal` 复用 index 远端实例,同样 ON) | +| **OFF (=0)** | CMC/掌骨近端、四指 `proximal`/`middle`、拇指 shaft 等 | + +接触偏移示例:`contactOffset = 0.001`,`restOffset = -0.0005`。 + +说明:这与 MuJoCo 的「胶囊 + exclude + 投影」是 **不同手段**;Isaac 默认硬写时 PhysX 接触 **不能** 像 MuJoCo `collision_project` 那样在写位置前把姿态投影回去,硬写仍可能视觉穿模。 + +#### D. 运行时补丁(桥代码,非 USD 文件) + +| 函数/常量 | 具体行为 | +|-----------|----------| +| `_patch_joint_max_forces` | RevoluteJoint angular drive `maxForce` 若 **< 8.0** 则抬到 **8.0** | +| `_fix_base_to_world` | 钉住 `hand_base_link`(改 `root_joint` 或建 `WorldFixedJoint`) | +| 安装位姿 | `/World/G20Hand` 位置 **`[0.0, 0.45, 0.70]`**(`HAND_MOUNT_Y/Z`) | +| 自碰 API | 默认跟随 USD 开自碰;`--no-self-collision` 时 `set_enabled_self_collisions(False)` | + +--- + +## 4. 关节映射 `joint_mapping.py` + +与 MuJoCo `g20_joints.py` 的 G20 左手数值 **一致**(同一套 SDK 表 / MIN/MAX/DIR / OPEN / mimic / SDK15–19 规则)。 + +### 4.1 SDK → 关节 + +| SDK | 关节 | +|-----|------| +| 0 | `thumb_cmc_pitch` | +| 1–4 | `index/middle/ring/pinky_mcp_pitch` | +| 5 | `thumb_cmc_roll` | +| 6–9 | `index/middle/ring/pinky_mcp_roll` | +| 10 | `thumb_cmc_yaw` | +| 11–14 | 预留 | +| 15 | `thumb_mcp` ← 写入 `arc/1.02` | +| 16–19 | `*_pip` ← 写入 `arc/0.89` | + +### 4.2 我们写入/试调过的表项 + +```text +# 通道5 注释:试调 1.47(原 1.4) +G20_L_MAX[5] = 1.47 + +# 左手侧摆 6..9:与 L20_L_DIR 不同,强制为 +1 +G20_L_DIR = [-1×6, 1,1,1,1, -1, 0×4, -1×5] + +DIP_MIMIC_MULTIPLIER = 0.89 +THUMB_IP_MIMIC_MULTIPLIER = 1.02 +``` + +张开预设 `G20_OPEN_CMD` 与 MuJoCo 相同: + +```text +[255×6, 193, 148, 105, 42, 245, 255×4, 255×5] +``` + +主动 16 关节 / 从动 5 关节(mimic)划分与 MuJoCo 一致。 + +--- + +## 5. 桥节点 `isaac_g20_plan_bridge.py` 做了哪些事 + +### 5.1 话题 + +| 模式 | 订阅 | 发布 | +|------|------|------| +| 默认 | `/g20/cb_left_hand_control_cmd` | `/sim/isaac/g20/left/joint_state` | +| `--plan-nominal` | `/retarget/g20/left/joint_target_nominal` | 同上 | +| `--legacy-sdk` | `/cb_left_hand_control_cmd` | 同上 | + +- 消息类型:`sensor_msgs/JointState`。 +- cmd:优先按 `name` 映射到 SDK 索引;否则按下标。 +- 发布:仿真 DOF 名 + 弧度(及 velocity)。 +- `TOPIC_LEGACY_STATE = /cb_left_hand_state` 已定义,但当前 **未实际发布**(`legacy_pub` 恒为 `None`)。 + +ROS2 节点名:`isaac_g20_plan_bridge`;启用扩展:`isaacsim.ros2.bridge`。 + +### 5.2 写关节方式 + +| 模式 | API | 细节 | +|------|-----|------| +| **默认硬写** | `set_dof_positions` + `set_dof_velocities(0)` | 写 **全关节含 mimic**;gains 全 0,避免与硬写冲突;物理步进后常再钉一次 | +| **`--pd-drive`** | `set_dof_position_targets` | **仅主动关节**;mimic gains=0;拇指四关节 stiff/damp/effort ≈ **10/3/6**,其余 ≈ **15/2.5/8** | + +其它: + +- 物理 `dt = 1/120`;默认 `phys_per_render = 16`。 +- slew:`--slew-rad`,单位是 **rad / 物理步**,默认 **`0.0`(瞬达)**(与 MuJoCo 的 rad/s 不同)。 +- 限位边距:`LIMIT_MARGIN_RAD = 0.05`。 +- `--hand-gravity`:仅 PD 模式下有意义。 +- 检测到 NaN/Inf → 复位到张开位姿。 + +### 5.3 对比视角(与 MuJoCo 对齐) + +| 常量 | 值 | +|------|-----| +| `COMPARE_LOOKAT_LOCAL` | `(0.04, -0.04, 0.12)` | +| `COMPARE_DISTANCE` | `0.50` | +| `COMPARE_ELEVATION_DEG` | `-12.0` | +| 方位 | 相机从 **+X** 看向 lookat(等价 MuJoCo `azimuth=180`) | +| 手世界原点 | `(0, HAND_MOUNT_Y, HAND_MOUNT_Z) = (0, 0.45, 0.70)` | +| 相机 prim | `/OmniverseKit_Persp` | + +### 5.4 CLI 开关一览 + +`--headless`、`--g20-usd`、`--plan-nominal`、`--legacy-sdk`、`--pd-drive`、`--hand-gravity`、`--no-self-collision`、`--slew-rad`、`--phys-per-render`、`--track-test`、`--cmd-topic`、`--nominal-topic`、`--sim-state-topic`、`--max-steps` + +**没有** MuJoCo 那套 `--no-collision-project`(Isaac 侧无同款投影算法)。 + +### 5.5 相对「只加载 URDF 默认导入」桥层额外保证 + +1. 固定使用预烘焙 USD + PhysX variant。 +2. 基座钉世界,手抬离地面安装。 +3. 驱动 maxForce 下限补丁。 +4. 默认硬写零增益;PD 模式单独设拇指/四指增益。 +5. 自碰默认 ON,可用 CLI 关。 +6. ROS2 话题与 MuJoCo/真机协议对齐(状态话题前缀不同:`/sim/isaac/...`)。 + +--- + +## 6. 如何启动 + +```bash +/home/lxqs/isaacsim/linkerhand/run_g20_plan.sh +``` + +脚本等价于: + +```bash +"$ISAAC_SIM_DIR/python.sh" /home/lxqs/isaacsim/linkerhand/isaac_g20_plan_bridge.py "$@" +``` + +常用: + +```bash +./run_g20_plan.sh --plan-nominal +./run_g20_plan.sh --pd-drive +./run_g20_plan.sh --no-self-collision +./run_g20_plan.sh --headless --track-test +./run_g20_plan.sh --slew-rad 0.02 --phys-per-render 8 +``` + +--- + +## 7. 与 MuJoCo 实现的差异(必须分清) + +| 项 | Isaac(本文) | MuJoCo | +|----|---------------|--------| +| 模型 | 预烘焙 **USD** | **MJCF** | +| 运行时是否读 URDF | **否** | 否(读 MJCF;MJCF 由 URDF 转出) | +| 状态话题 | `/sim/isaac/g20/left/joint_state` | `/sim/mujoco/g20/left/joint_state` | +| 默认驱动 | `set_dof_positions` 硬写 | `qpos` 硬写 + `mj_forward` | +| 可选 PD | PhysX angular drive | MJCF `` + `mj_step` | +| **collision project** | **无** | **有**(默认开) | +| 防穿模资产手段 | `instances.usda` 选择性 collider + 自碰 | visual/capsule 分层 + 28 条 exclude | +| slew | rad/**物理步**,默认 0 | rad/**秒**,默认 5.0;另有墙钟 `speed=1.35` | +| 手位姿 | 世界 `(0, 0.45, 0.70)` | 世界原点 | +| 映射 | `joint_mapping.py` | `g20_joints.py`(G20 left 同数值) | + +--- + +## 8. 改动 chronologically(便于对照) + +1. URDF + meshes 入库;离线 **URDF USD Converter v0.1.3** → `linkerhand_g20_left.usda`。 +2. 手改 Physics:自碰、求解器、armature、body limits。 +3. 手改 `instances.usda`:只开掌心 + 指尖等 collider。 +4. `thumb_cmc_roll` 上限改为 **1.47**(URDF + Physics 度制上限 + `G20_L_MAX`)。 +5. 实现 `isaac_g20_plan_bridge.py`:硬写默认、可选 PD、钉基座、maxForce 补丁、安装偏置。 +6. 话题对齐 `/g20/cb_left_hand_control_cmd`;状态发 `/sim/isaac/...`。 +7. 视角 `COMPARE_*` 与 MuJoCo 对齐(+X 看掌心)。 +8. SDK15–19 除 mimic 与 MuJoCo/真机语义对齐(写进 `joint_mapping.py`)。 + +--- + +## 9. 已知限制 + +1. 默认硬写下,PhysX 接触 **推不开** 被写死的 DOF;穿模缓解主要靠选择性碰撞几何,**没有** MuJoCo 式投影。 +2. 近端/中节碰撞多为 OFF:邻指中段穿模可能检不出。 +3. 凸包近似与视觉 mesh 非凸外形不一致。 +4. 仅左手 G20 USD。 +5. `dual_sim` 与 PLAN 桥参数不同,联调时不要混用入口脚本。 diff --git a/docs/G20_Isaac_技术详解.md b/docs/G20_Isaac_技术详解.md new file mode 100644 index 0000000..c32ef6d --- /dev/null +++ b/docs/G20_Isaac_技术详解.md @@ -0,0 +1,499 @@ +# G20 左手 · Isaac Sim 技术详解 + +本文面向**读代码、改逻辑、排查问题**:按「程序从哪进、函数怎么调、数据怎么流」写清楚实现细节。 +资产路径、URDF→USD 改动清单见 [`G20_Isaac_实现说明.md`](./G20_Isaac_实现说明.md)。 +MuJoCo 对照:[`G20_MuJoCo_技术详解.md`](../../linker_hand_mujoco_ros2/docs/G20_MuJoCo_技术详解.md)(若在 mujoco 仓的 `docs/` 下阅读,则为同目录链接)。 + +主文件: + +| 角色 | 路径 | +|------|------| +| 桥主程序 | `/home/lxqs/isaacsim/linkerhand/isaac_g20_plan_bridge.py` | +| 关节映射 | `/home/lxqs/isaacsim/linkerhand/joint_mapping.py` | +| 启动脚本 | `/home/lxqs/isaacsim/linkerhand/run_g20_plan.sh` | +| 默认 USD | `.../urdf/g20/left/linkerhand_g20_left/linkerhand_g20_left.usda` | + +--- + +## 1. 总体结构:单线程循环(与 MuJoCo 不同) + +Isaac 桥**没有**单独的 ROS daemon 线程,也**没有** `threading.Lock`。 +主循环里每个物理步先 `rclpy.spin_once`,再写关节、再 `SimulationManager.step()`。 + +```text +┌─────────────────────────────────────────────────────────────┐ +│ 模块加载期(import 顶层) │ +│ parse_args() │ +│ SimulationApp(...) # 必须最早启动 Isaac │ +│ enable_extension(ros2.bridge) │ +│ import joint_mapping / rclpy │ +├─────────────────────────────────────────────────────────────┤ +│ main() 初始化 │ +│ create_new_stage / GroundPlane / DistantLight │ +│ _load_g20(usd) → Articulation │ +│ _fix_base_to_world / set_dof_gains / 自碰 │ +│ G20PlanBridge(...) │ +│ apply_targets() 初始 snap 到 open │ +├─────────────────────────────────────────────────────────────┤ +│ 主循环(每 render 帧内跑 phys_per_render 次物理步) │ +│ for _ in range(phys_per_render): │ +│ rclpy.spin_once(node) # 处理回调 → 改 goal │ +│ bridge.apply_targets() # slew → 写 Articulation │ +│ SimulationManager.step() # PhysX 一步 │ +│ recover_if_invalid() │ +│ bridge.publish_state() │ +│ if 位置硬写: apply_targets() 再钉一次 │ +│ RenderingManager.render() │ +│ simulation_app.update() │ +└─────────────────────────────────────────────────────────────┘ +``` + +**核心状态变量(`G20PlanBridge`):** + +| 变量 | 类型 | 含义 | +|------|------|------| +| `goal` | `dict[str, float]` | 最新目标关节角(弧度,含 mimic) | +| `applied` | `dict[str, float]` | 本步实际写入的角(slew 后) | +| `targets` | 同 `applied` | 别名,历史兼容 | +| `track_nominal` | `dict[str, float] \| None` | 主动关节目标,供 `tracking_error()` | +| `dof_index` | `dict[str, int]` | 关节名 → Articulation DOF 下标 | +| `use_physics_drive` | `bool` | True=`--pd-drive`;False=位置硬写 | + +**与 MuJoCo 的关键差异:** + +| 项 | Isaac | MuJoCo | +|----|-------|--------| +| 线程模型 | 单线程 `spin_once` + 物理循环 | ROS daemon + 主仿真线程 + Lock | +| 防穿模 | USD 选择性 collider + 自碰 | `collision_project` + `mj_forward` | +| slew 单位 | **rad / 物理步**,默认 **0**(瞬达) | **rad / 秒**,默认 **5.0** | +| 写关节 API | `set_dof_positions` / `set_dof_position_targets` | `data.qpos` + `mj_forward` | +| 物理步进 | 每 render 默认 16 次 `SimulationManager.step` | 硬写模式不 `mj_step` | + +--- + +## 2. 程序入口与加载顺序(很重要) + +入口:`./run_g20_plan.sh` → `$ISAAC_SIM_DIR/python.sh isaac_g20_plan_bridge.py`。 + +### 2.1 为何 `parse_args` + `SimulationApp` 在顶层? + +```text +# 文件顶层执行顺序(main 之前) +parse_args() # ① 先解析,因为 SimulationApp 要 headless +SimulationApp({"headless": ...}) # ② 启动 Omniverse / PhysX 运行时 +... import isaacsim.* ... +from joint_mapping import ... +enable_extension("isaacsim.ros2.bridge") +simulation_app.update() +import rclpy ... +``` + +Isaac 要求:**先有 `SimulationApp`,才能 import 多数 isaacsim 模块**。 +因此参数解析不能放在 `main()` 里才做;顶层 `args = parse_args()` 是刻意的。 + +`_normalize_argv`:把 `-pd-drive` 这类单横杠改成 `--pd-drive`,避免被 argparse 拆成 `-p -d ...`。 + +### 2.2 `main()` 调用链 + +```text +main() +├── stage_utils.create_new_stage() +├── GroundPlane / DistantLight +├── _compare_camera_eye_target() → set_camera_view(...) +├── hand_path = _load_g20(args.g20_usd) +│ ├── define_prim("/World/G20Hand") +│ ├── XformPrim(..., positions=[[0, 0.45, 0.70]]) +│ ├── add_reference_to_stage(usd → .../hand) +│ ├── set_prim_variants(Physics=physx) +│ └── _patch_joint_max_forces(hand_path) +├── SimulationManager.set_physics_dt(1/120) +├── play → update → _fix_base_to_world → stop → play +├── art = Articulation(hand_path) +├── art.set_enabled_self_collisions(...) +├── art.set_link_enabled_gravities(...) +├── set_dof_gains / set_dof_max_efforts # 见 §5 +├── rclpy.init(); Node("isaac_g20_plan_bridge") +├── G20PlanBridge(...) +├── slew=0; apply_targets(); 恢复 slew # 初始 snap open +└── while simulation_app.is_running(): + for _ in range(phys_per_render): # 默认 16 + spin_once → apply_targets → step → publish → [再钉] + render + update +``` + +--- + +## 3. 场景加载相关函数 + +### 3.1 `_load_g20(usd_path) → hand_path` + +```python +mount = "/World/G20Hand" +stage_utils.define_prim(mount, "Xform") +XformPrim(mount, positions=[[0.0, HAND_MOUNT_Y, HAND_MOUNT_Z]], ...) +hand_path = f"{mount}/hand" +stage_utils.add_reference_to_stage(usd_path=..., path=hand_path) +prim_utils.set_prim_variants(hand_path, variants=[("Physics", "physx")]) +_patch_joint_max_forces(hand_path) +return hand_path +``` + +要点: + +1. **运行时不读 URDF**,只挂预烘焙 USD。 +2. 手装在世界坐标 `(0, 0.45, 0.70)`,离地,避免和地面穿插。 +3. Physics variant 强制 `physx`(USD 里还有 mujoco/newton 等层)。 + +### 3.2 `_patch_joint_max_forces(hand_path, max_force=8.0)` + +遍历手下面所有 `UsdPhysics.RevoluteJoint`,取 angular DriveAPI: + +```python +if maxForce < 8.0: + attr.Set(8.0) +``` + +防止某些关节 drive 力矩上限太小,PD 跟不上。 + +### 3.3 `_fix_base_to_world(hand_path)` + +钉住掌心,手不会掉下去: + +1. 在手 prim 树里找 `hand_base_link`(或 `base_link` / `palm`)RigidBody。 +2. 若已有合法 `root_joint`:改 `LocalPos0/Rot0` 对齐当前世界位姿,Body1=base,Body0=世界。 +3. 否则新建 `{hand_path}/WorldFixedJoint`(`UsdPhysics.FixedJoint`)。 + +调用时机:`play → update → fix → stop → play`,让 PhysX 在重建 articulation 前把固定关节写进 stage。 + +### 3.4 `_compare_camera_eye_target()` + +与 MuJoCo `COMPARE_*` 对齐: + +```python +target = hand_origin + COMPARE_LOOKAT_LOCAL # (0.04,-0.04,0.12) 相对手 +eye.x = target.x + distance * cos(elev) # 从 +X 看 +eye.z = target.z - distance * sin(elev) # elev=-12° 略俯视 +``` + +`set_camera_view(eye, target, "/OmniverseKit_Persp")`;play/stop 后会再设一次,防止 viewport 被重置。 + +--- + +## 4. 映射层:`joint_mapping.py` 函数说明 + +与 MuJoCo `g20_joints.py` **数值一致**,但 API 多了 `hand`/`side` 参数(同一文件还服务 O6/L20)。 + +### 4.1 Legacy 0~255 调用链 + +```text +_on_cmd_u8(msg) + vals = [255]*20 + 优先按 msg.name → L20_SDK_TO_URDF 反查 SDK 索引填 vals + 否则按下标填 vals[:20] + sdk_range_to_full_urdf_positions(vals, "G20", "left") + ├── sdk_range_to_urdf_positions(...) + │ ├── range_to_arc(vals, "G20", "left") + │ └── SDK15: thumb_mcp = arc/1.02 + │ SDK16..19: *_pip = arc/0.89 + └── 补全 dip/ip(函数内部直接写,不等价于再调 complete_*,结果相同) + set_nominal_targets(full) + └── goal = complete_g20_mimic_positions(positions) +``` + +### 4.2 `range_to_arc(values, hand, side)` + +```python +j_min, j_max, j_dir = _tables("G20", "left") # → G20_L_MIN/MAX/DIR +for i in 0..19: + if 11 <= i <= 14: continue + if j_dir[i] == -1: + arcs[i] = lerp(val, 0, 255, j_max[i], j_min[i]) + else: + arcs[i] = lerp(val, 0, 255, j_min[i], j_max[i]) # 侧摆 6..9 +``` + +### 4.3 `sdk_range_to_urdf_positions` vs `sdk_range_to_full_urdf_positions` + +| 函数 | 输出 | +|------|------| +| `sdk_range_to_urdf_positions` | 仅主动 16 关节(已做 SDK15/16~19 除 mimic) | +| `sdk_range_to_full_urdf_positions` | 主动 + 软件解析的 `thumb_ip` / `*_dip` | + +Isaac **硬写模式**写全关节(含 mimic);**PD 模式**只写主动关节,mimic 交给 PhysX USD mimic。 + +### 4.4 `complete_g20_mimic_positions` + +与 MuJoCo 相同:`thumb_ip = thumb_mcp * 1.02`,`*_dip = *_pip * 0.89`;已有 mimic 值不覆盖。 + +### 4.5 `open_hand_command("G20")` + +返回 `G20_OPEN_CMD`(float 列表),与 MuJoCo `G20_OPEN_CMD` 同值。 + +### 4.6 PLAN 名义路径 + +```text +_on_nominal(msg) + incoming = {name: position} + 缺主动关节 → 与旧 goal 合并 + goal = complete_g20_mimic_positions(merged) + track_nominal = {主动关节: goal[...]} +``` + +注意:Isaac 回调里**直接改 `self.goal`**,没有 MuJoCo 的 `_set_goal_only` + Lock;因为主循环同线程 `spin_once`,不存在并发写 Articulation。 + +--- + +## 5. 驱动模式:`set_dof_gains` 与 `apply_targets` + +### 5.1 初始化时增益怎么设(`main` 里) + +**默认位置硬写:** + +```python +art.set_dof_gains(stiffnesses=zeros(n), dampings=zeros(n)) +``` + +零增益,避免 PD 与 `set_dof_positions` 抢控制。 + +**`--pd-drive`:** + +```python +# 主动关节 +拇指四关节: stiff/damp/effort = 10 / 3 / 6 +其余主动: stiff/damp/effort = 15 / 2.5 / 8 +art.set_dof_gains(...); art.set_dof_max_efforts(...) + +# mimic 关节强制 0 增益 —— 否则与 PhysX mimic 冲突 → Invalid PhysX transform +art.set_dof_gains(0, 0, dof_indices=mimic_idx) +``` + +`--hand-gravity` 仅在 PD 下生效:`set_link_enabled_gravities(True)`。 + +### 5.2 `apply_targets()` — 每物理步的核心 + +```python +def apply_targets(self): + self._slew_applied_toward_goal() # goal → applied + + if use_physics_drive: + name_iter = (n for n in applied if n in actuated) # 只主动 + else: + name_iter = applied.keys() # 含 mimic + + positions = [...] + if use_physics_drive: + art.set_dof_position_targets(positions, dof_indices=indices) + else: + art.set_dof_positions(positions, dof_indices=indices) + art.set_dof_velocities(zeros(...), dof_indices=indices) +``` + +| 模式 | API | 写哪些关节 | +|------|-----|------------| +| 位置硬写(默认) | `set_dof_positions` + `set_dof_velocities(0)` | 全部(含软件算好的 mimic) | +| PD | `set_dof_position_targets` | 仅主动 16 个 | + +### 5.3 `_slew_applied_toward_goal()` + +```python +max_step = self.slew_rad # 默认 0 → 每步直达 goal +margin = LIMIT_MARGIN_RAD # 0.05,离限位留边 +for name, g in goal.items(): + g = clip(g, lo+margin, hi-margin) + if max_step <= 0: + applied[name] = g + else: + applied[name] = a ± min(|g-a|, max_step) +applied = complete_g20_mimic_positions(applied) +``` + +单位是 **每物理步弧度**,不是每秒。 +物理 dt=1/120,默认每 render 16 步 → 墙钟约 16/120 ≈ 0.133 s 一帧渲染。 + +### 5.4 为何硬写后还要「再钉一次」? + +主循环: + +```python +bridge.apply_targets() +SimulationManager.step() # PhysX 可能轻微挪动 DOF +bridge.publish_state() +if not use_pd: + bridge.apply_targets() # 再钉回 applied +``` + +接触/积分会让硬写姿态漂移;步进后再写一遍,保证跟指令贴。 + +--- + +## 6. 异常恢复与状态发布 + +### 6.1 `recover_if_invalid()` + +```python +pos = art.get_dof_positions() +if not all finite: + goal = applied = open_full + set_dof_positions(open) + return True +``` + +PD 爆炸或数值坏掉时复位张开姿态。 + +### 6.2 `publish_state()` + +每物理步调用(不是独立 50Hz 定时器): + +```python +pos = art.get_dof_positions() +vel = art.get_dof_velocities() # 失败则填 0 +pub → /sim/isaac/g20/left/joint_state +``` + +`legacy_pub` 恒为 `None`,不会发 `/cb_left_hand_state`; +`urdf_positions_to_sdk_range` 已实现,预留反算 0~255。 + +### 6.3 `tracking_error()` + +对 `track_nominal` 里每个主动关节:`|q_sim - q_nominal|`,返回 `(max, mean)`。 + +--- + +## 7. 自碰与防穿模(Isaac 怎么做) + +**没有** MuJoCo 的 `collision_project`。手段是: + +1. **USD `instances.usda`**:选择性开碰撞(掌心 + 指尖 ON,近端/中节多数 OFF)。 +2. **`physx.usda`**:`enabledSelfCollisions = 1`。 +3. **运行时**:`art.set_enabled_self_collisions([True])`(`--no-self-collision` 关)。 + +因此: + +- 硬写时 PhysX **推不开** 被写死的 DOF → 仍可能视觉穿模。 +- PD 模式下接触力可挡一部分,但跟手变差。 +- 这与 MuJoCo「硬写前投影」是不同哲学。 + +--- + +## 8. 完整时序例子:收到半握命令后的一物理步 + +假设默认硬写、`slew_rad=0`。 + +```text +1. rclpy.spin_once + → _on_cmd_u8 → sdk_range_to_full_urdf_positions + → set_nominal_targets → goal = 半握全关节弧度 + +2. apply_targets() + → _slew_applied_toward_goal: applied = goal(瞬达) + → set_dof_positions(全部关节含 mimic) + → set_dof_velocities(0) + +3. SimulationManager.step() + → PhysX 积分(硬写下姿态应贴近刚写的值) + +4. recover_if_invalid() # 通常 False + +5. publish_state() + → 读 get_dof_positions → 发 /sim/isaac/... + +6. apply_targets() 再钉一次(硬写模式) +``` + +若 `slew_rad=0.02`:每物理步每个关节最多走 0.02 rad,需多步才到 goal。 + +--- + +## 9. `--track-test` 路径 + +```text +max_steps 默认 480(若未指定) +每 160 物理步切换一次目标: + phase 偶: open_hand_command("G20") + phase 奇: [80.0]*20 + set_nominal_targets(sdk_range_to_full_urdf_positions(...)) + +循环结束后再 settle 240 步: + apply_targets + SimulationManager.step + +tracking_error() → max <= 0.02 → PASS,否则 exit 2 +``` + +与 MuJoCo track-test(open→半握、关投影、slew=0)流程类似,但步进计数和切换方式不同。 + +--- + +## 10. 常用 Isaac / PhysX API 速查(本工程用到的) + +| API | 用途 | +|-----|------| +| `SimulationApp` | 启动 Isaac 运行时 | +| `stage_utils.add_reference_to_stage` | 挂 USD | +| `prim_utils.set_prim_variants` | 选 Physics=physx | +| `Articulation(path)` | 包装手的 DOF | +| `set_dof_positions` / `set_dof_position_targets` | 硬写 / PD 目标 | +| `set_dof_gains` / `set_dof_max_efforts` | PD 参数 | +| `set_enabled_self_collisions` | 自碰开关 | +| `get_dof_positions` / `get_dof_velocities` / `get_dof_limits` | 读状态 | +| `SimulationManager.set_physics_dt` / `step` | 物理节拍 | +| `RenderingManager.render` | 渲染一帧 | +| `set_camera_view` | 对比视角 | + +--- + +## 11. CLI 模式对照 + +| 参数 | 效果 | +|------|------| +| (默认) | 订 `/g20/cb_left_hand_control_cmd`,位置硬写,slew=0,自碰 ON | +| `--plan-nominal` | 订名义弧度话题,`use_cmd_u8=False` | +| `--legacy-sdk` | 订 `/cb_left_hand_control_cmd` | +| `--pd-drive` | `set_dof_position_targets` + 主动关节增益 | +| `--hand-gravity` | 仅 PD 下开手部重力 | +| `--no-self-collision` | 关自碰(会穿模) | +| `--slew-rad N` | 每物理步最多转 N rad | +| `--phys-per-render N` | 每渲染帧物理步数(默认 16) | +| `--track-test` | 内置跟踪验收 | + +--- + +## 12. 改代码时最常动的位置 + +| 需求 | 改哪里 | +|------|--------| +| SDK→弧度、mimic、OPEN_CMD | `joint_mapping.py` | +| 默认硬写/PD 增益、拇指特殊增益 | `isaac_g20_plan_bridge.py` 顶部常量 + `main` 里 `set_dof_gains` | +| slew / 物理步 / 安装高度 | `DEFAULT_SLEW_RAD` / `DEFAULT_PHYS_PER_RENDER` / `HAND_MOUNT_*` | +| 相机 | `COMPARE_*` + `_compare_camera_eye_target` | +| 碰撞谁开谁关 | USD `payloads/instances.usda` | +| 自碰/求解器 | USD `payloads/Physics/physx.usda` | +| 话题名 | `TOPIC_*` 或 CLI | + +--- + +## 13. 与 MuJoCo 技术详解的对照表 + +| 概念 | Isaac 函数/位置 | MuJoCo 函数/位置 | +|------|-----------------|------------------| +| 映射入口 | `joint_mapping.sdk_range_to_full_urdf_positions` | `g20_joints.sdk_range_to_full_urdf_positions` | +| 收命令 | `_on_cmd_u8` / `_on_nominal` | `_on_legacy_cmd` / `_on_nominal` | +| 更新目标 | `set_nominal_targets` / 直接改 `goal` | `_set_goal_only`(持锁) | +| 限速 | `_slew_applied_toward_goal`(rad/步) | `_slew_applied_unlocked`(rad/s) | +| 写入仿真 | `apply_targets` → `set_dof_*` | `_hard_write_pose_unlocked` → `mj_forward` | +| 防穿模 | USD collider + 自碰(无投影) | `_project_applied_no_penetration_unlocked` | +| 物理步进 | `SimulationManager.step` | 硬写不 step;PD 用 `mj_step` | +| 发状态 | 每物理步 `publish_state` | 50Hz timer `_publish_state` | +| 状态话题 | `/sim/isaac/g20/left/joint_state` | `/sim/mujoco/g20/left/joint_state` | + +--- + +## 14. 读代码建议顺序 + +1. `run_g20_plan.sh` → 确认用的是哪份 `python.sh` +2. 文件顶层:`parse_args` → `SimulationApp` → import +3. `main()` 前半:`_load_g20` → `_fix_base` → gains +4. `G20PlanBridge.__init__` + `_on_cmd_u8` +5. `apply_targets` + 主循环里「写→step→再钉」 +6. 需要改防穿模时去看 USD `instances.usda`,而不是在桥里找 project 函数 + +资产与改动清单仍见 [`G20_Isaac_实现说明.md`](./G20_Isaac_实现说明.md)。 diff --git a/hand_control_ui.py b/hand_control_ui.py new file mode 100755 index 0000000..a73b5ab --- /dev/null +++ b/hand_control_ui.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""LinkerHand O6 / G20 简易关节控制 UI。 + +向 Isaac Sim 桥接话题发布 sensor_msgs/JointState(position 为 SDK 0~255)。 +依赖系统 ROS2 + tkinter(不要用 Isaac 的 python.sh 启动)。 + +用法: + source /opt/ros/jazzy/setup.bash + python3 linkerhand/hand_control_ui.py + # 或 + bash linkerhand/run_ui.sh +""" + +from __future__ import annotations + +import threading +import time +import tkinter as tk +from tkinter import ttk + +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import JointState + +# --------------------------------------------------------------------------- +# 手型配置(与仿真话题 / SDK 一致) +# --------------------------------------------------------------------------- +HANDS = { + "O6": { + "cmd": "/o6/cb_left_hand_control_cmd", + "state": "/o6/cb_left_hand_state", + "labels": [ + "大拇指弯曲", + "大拇指横摆", + "食指弯曲", + "中指弯曲", + "无名指弯曲", + "小拇指弯曲", + ], + "init": [250, 250, 250, 250, 250, 250], + "presets": { + "张开": [250, 250, 250, 250, 250, 250], + "握拳": [102, 18, 0, 0, 0, 0], + "点赞": [250, 79, 0, 0, 0, 0], + "OK": [139, 91, 103, 250, 250, 250], + }, + }, + "G20": { + "cmd": "/cb_left_hand_control_cmd", + "state": "/cb_left_hand_state", + "labels": [ + "拇指根部", + "食指根部", + "中指根部", + "无名指根部", + "小指根部", + "拇指侧摆", + "食指侧摆", + "中指侧摆", + "无名指侧摆", + "小指侧摆", + "拇指横摆", + "预留11", + "预留12", + "预留13", + "预留14", + "拇指尖部", + "食指末端", + "中指末端", + "无名指末端", + "小指末端", + ], + "init": [255, 255, 255, 255, 255, 255, 193, 148, 105, 42, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255], + "presets": { + "张开": [255, 255, 255, 255, 255, 255, 193, 148, 105, 42, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255], + "握拳": [96, 0, 0, 0, 0, 0, 193, 158, 128, 91, 132, 255, 255, 255, 255, 144, 0, 0, 0, 0], + "点赞": [255, 0, 0, 0, 0, 255, 162, 162, 144, 100, 210, 255, 255, 255, 255, 255, 0, 0, 0, 0], + "OK": [148, 110, 255, 255, 255, 44, 164, 100, 114, 127, 178, 255, 255, 255, 255, 94, 71, 255, 255, 255], + }, + # 预留电机不可控 + "disabled": {11, 12, 13, 14}, + }, +} + +PUBLISH_HZ = 20.0 + + +class HandControlNode(Node): + def __init__(self) -> None: + super().__init__("linker_hand_control_ui") + self._pubs = { + name: self.create_publisher(JointState, cfg["cmd"], 10) for name, cfg in HANDS.items() + } + self._latest_cmd: dict[str, list[float]] = { + name: list(cfg["init"]) for name, cfg in HANDS.items() + } + self._latest_state: dict[str, list[float]] = { + name: list(cfg["init"]) for name, cfg in HANDS.items() + } + for name, cfg in HANDS.items(): + self.create_subscription( + JointState, + cfg["state"], + lambda msg, n=name: self._on_state(n, msg), + 10, + ) + self.create_timer(1.0 / PUBLISH_HZ, self._publish_all) + + def _on_state(self, hand: str, msg: JointState) -> None: + if not msg.position: + return + n = len(self._latest_state[hand]) + self._latest_state[hand] = [float(v) for v in msg.position[:n]] + if len(msg.position) < n: + self._latest_state[hand].extend([0.0] * (n - len(msg.position))) + + def set_cmd(self, hand: str, values: list[float]) -> None: + n = len(self._latest_cmd[hand]) + self._latest_cmd[hand] = [float(max(0, min(255, v))) for v in values[:n]] + + def set_joint(self, hand: str, index: int, value: float) -> None: + if 0 <= index < len(self._latest_cmd[hand]): + self._latest_cmd[hand][index] = float(max(0, min(255, value))) + + def get_state(self, hand: str) -> list[float]: + return list(self._latest_state[hand]) + + def _publish_all(self) -> None: + now = self.get_clock().now().to_msg() + for name, pub in self._pubs.items(): + msg = JointState() + msg.header.stamp = now + msg.name = [f"motor_{i}" for i in range(len(self._latest_cmd[name]))] + msg.position = list(self._latest_cmd[name]) + pub.publish(msg) + + +class HandTab(ttk.Frame): + def __init__(self, master: tk.Misc, hand: str, cfg: dict, node: HandControlNode) -> None: + super().__init__(master) + self.hand = hand + self.cfg = cfg + self.node = node + self.vars: list[tk.IntVar] = [] + self.value_labels: list[ttk.Label] = [] + self.state_labels: list[ttk.Label] = [] + self._building = True + + top = ttk.Frame(self) + top.pack(fill=tk.X, padx=8, pady=6) + ttk.Label(top, text=f"话题: {cfg['cmd']}", font=("Sans", 9)).pack(side=tk.LEFT) + self.status = ttk.Label(top, text="状态: —", foreground="#555") + self.status.pack(side=tk.RIGHT) + + preset_row = ttk.Frame(self) + preset_row.pack(fill=tk.X, padx=8, pady=4) + ttk.Label(preset_row, text="预设:").pack(side=tk.LEFT) + for name, pose in cfg.get("presets", {}).items(): + ttk.Button(preset_row, text=name, command=lambda p=pose: self.apply_preset(p)).pack( + side=tk.LEFT, padx=3 + ) + + canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0) + scroll = ttk.Scrollbar(self, orient=tk.VERTICAL, command=canvas.yview) + inner = ttk.Frame(canvas) + inner.bind("", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) + canvas.create_window((0, 0), window=inner, anchor="nw") + canvas.configure(yscrollcommand=scroll.set) + canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(8, 0), pady=4) + scroll.pack(side=tk.RIGHT, fill=tk.Y, padx=(0, 8), pady=4) + + disabled = cfg.get("disabled", set()) + header = ttk.Frame(inner) + header.pack(fill=tk.X, pady=(0, 4)) + ttk.Label(header, text="关节", width=14).pack(side=tk.LEFT) + ttk.Label(header, text="指令", width=6).pack(side=tk.LEFT) + ttk.Label(header, text="反馈", width=6).pack(side=tk.LEFT) + + for i, label in enumerate(cfg["labels"]): + row = ttk.Frame(inner) + row.pack(fill=tk.X, pady=1) + ttk.Label(row, text=f"{i:02d} {label}", width=14).pack(side=tk.LEFT) + var = tk.IntVar(value=int(cfg["init"][i])) + self.vars.append(var) + val_lbl = ttk.Label(row, text=f"{var.get():3d}", width=4) + val_lbl.pack(side=tk.LEFT) + self.value_labels.append(val_lbl) + state_lbl = ttk.Label(row, text="—", width=4, foreground="#06c") + state_lbl.pack(side=tk.LEFT) + self.state_labels.append(state_lbl) + scale = ttk.Scale( + row, + from_=0, + to=255, + orient=tk.HORIZONTAL, + variable=var, + command=lambda _v, idx=i: self._on_slide(idx), + ) + scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=4) + if i in disabled: + scale.state(["disabled"]) + val_lbl.configure(foreground="#999") + + self._building = False + self.after(200, self._refresh_state) + + def _on_slide(self, index: int) -> None: + if self._building: + return + value = int(self.vars[index].get()) + self.value_labels[index].configure(text=f"{value:3d}") + self.node.set_joint(self.hand, index, value) + + def apply_preset(self, pose: list[int]) -> None: + self._building = True + for i, v in enumerate(pose): + if i >= len(self.vars): + break + if i in self.cfg.get("disabled", set()): + continue + self.vars[i].set(int(v)) + self.value_labels[i].configure(text=f"{int(v):3d}") + self._building = False + self.node.set_cmd(self.hand, [float(v.get()) for v in self.vars]) + + def _refresh_state(self) -> None: + state = self.node.get_state(self.hand) + for i, lbl in enumerate(self.state_labels): + if i < len(state): + lbl.configure(text=f"{int(round(state[i])):3d}") + self.status.configure(text=f"状态: 已收 {len(state)} DOF @ {PUBLISH_HZ:.0f}Hz") + self.after(200, self._refresh_state) + + +class App(tk.Tk): + def __init__(self, node: HandControlNode) -> None: + super().__init__() + self.node = node + self.title("LinkerHand 关节控制 (默认 G20)") + self.geometry("720x780") + self.minsize(560, 480) + + nb = ttk.Notebook(self) + nb.pack(fill=tk.BOTH, expand=True, padx=6, pady=6) + # 默认只展示 G20;需要 O6 时可改 HANDS 顺序或加回 O6 + for hand in ("G20",): + tab = HandTab(nb, hand, HANDS[hand], node) + nb.add(tab, text=hand) + + tip = ttk.Label( + self, + text="先启动仿真: bash linkerhand/run_sim.sh\n" + "(默认位置驱动:稳,拇指可达;可见轻微穿模属正常)\n" + "拖动滑条即发布;0≈弯曲,255≈张开", + justify=tk.LEFT, + foreground="#444", + ) + tip.pack(fill=tk.X, padx=10, pady=(0, 8)) + + self.protocol("WM_DELETE_WINDOW", self._on_close) + + def _on_close(self) -> None: + self.destroy() + + +def main() -> None: + rclpy.init() + node = HandControlNode() + spin_thread = threading.Thread(target=lambda: rclpy.spin(node), daemon=True) + spin_thread.start() + + app = App(node) + try: + app.mainloop() + finally: + node.destroy_node() + if rclpy.ok(): + rclpy.shutdown() + + +if __name__ == "__main__": + main() diff --git a/isaac_g20_plan_bridge.py b/isaac_g20_plan_bridge.py new file mode 100755 index 0000000..d6cdf01 --- /dev/null +++ b/isaac_g20_plan_bridge.py @@ -0,0 +1,724 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Isaac Sim G20 实机命令桥。 + +默认: + 订阅 /g20/cb_left_hand_control_cmd JointState(与真机相同的 0~255 cmd) + 发布 /sim/isaac/g20/left/joint_state JointState(仿真 DOF 弧度) + +按关节名匹配;0~255 经 joint_mapping 转为 URDF 弧度。 +默认位置硬写以跟真机;``--pd-drive`` 可选。 + +PLAN 名义弧度:``--plan-nominal`` 订阅 /retarget/g20/left/joint_target_nominal。 +""" + +from __future__ import annotations + +import argparse +import sys +import time +from pathlib import Path + +LINKERHAND_ROOT = Path(__file__).resolve().parent +URDF_ROOT = LINKERHAND_ROOT / "urdf" +DEFAULT_G20_USD = URDF_ROOT / "g20/left/linkerhand_g20_left/linkerhand_g20_left.usda" + +TOPIC_NOMINAL = "/retarget/g20/left/joint_target_nominal" +TOPIC_SIM_STATE = "/sim/isaac/g20/left/joint_state" +TOPIC_G20_CMD = "/g20/cb_left_hand_control_cmd" +TOPIC_LEGACY_CMD = "/cb_left_hand_control_cmd" # 无命名空间旧话题 +TOPIC_LEGACY_STATE = "/cb_left_hand_state" + +HAND_MOUNT_Y = 0.45 +HAND_MOUNT_Z = 0.70 +TRACK_TOL_RAD = 0.02 +WARN_INTERVAL_S = 2.0 +# 跟真机:默认不限速(0=每步直达 goal);需要柔顺时用 --slew-rad +DEFAULT_SLEW_RAD = 0.0 +DEFAULT_PHYS_PER_RENDER = 16 +PD_STIFFNESS = 15.0 +PD_DAMPING = 2.5 + +# 与 MuJoCo G20 共用的对比视角:正对掌心(法向约 -X)、手指朝上(+Z) +# lookat 相对手本地原点;相机从 +X 看向 -X(与 MuJoCo azimuth=180 一致) +COMPARE_LOOKAT_LOCAL = (0.04, -0.04, 0.12) +COMPARE_DISTANCE = 0.50 +COMPARE_ELEVATION_DEG = -12.0 +PD_MAX_EFFORT = 8.0 +LIMIT_MARGIN_RAD = 0.05 +THUMB_PD_STIFFNESS = 10.0 +THUMB_PD_DAMPING = 3.0 +THUMB_PD_MAX_EFFORT = 6.0 +THUMB_ACTUATED = frozenset( + {"thumb_cmc_roll", "thumb_cmc_yaw", "thumb_cmc_pitch", "thumb_mcp"} +) + + +def _normalize_argv(argv: list[str]) -> list[str]: + """把常见单横杠长选项改成双横杠,避免 ``-hand-gravity`` 被拆成 ``-h`` 等短选项。""" + aliases = { + "-hand-gravity": "--hand-gravity", + "-pd-drive": "--pd-drive", + "-legacy-sdk": "--legacy-sdk", + "-plan-nominal": "--plan-nominal", + "-track-test": "--track-test", + "-headless": "--headless", + "-no-self-collision": "--no-self-collision", + } + out: list[str] = [] + for a in argv: + out.append(aliases.get(a, a)) + return out + + +def parse_args() -> argparse.Namespace: + p = argparse.ArgumentParser(description="Isaac G20 bridge (default: /g20/cb_left_hand_control_cmd)") + p.add_argument("--headless", action="store_true") + p.add_argument("--g20-usd", type=Path, default=DEFAULT_G20_USD) + p.add_argument("--max-steps", type=int, default=0, help=">0 时跑满步数退出") + p.add_argument( + "--plan-nominal", + action="store_true", + help="订阅 PLAN 名义弧度 /retarget/g20/left/joint_target_nominal", + ) + p.add_argument( + "--legacy-sdk", + action="store_true", + help="订阅旧话题 /cb_left_hand_control_cmd(无 /g20 前缀)", + ) + p.add_argument( + "--pd-drive", + action="store_true", + help="PD 动力学(默认位置硬写;大跳指令仍靠 --slew-rad 限速)", + ) + p.add_argument( + "--hand-gravity", + action="store_true", + help="手部重力(仅 --pd-drive 下生效)", + ) + p.add_argument( + "--no-self-collision", + action="store_true", + help="关闭自碰(会穿模;默认跟随 USD 开启自碰)", + ) + p.add_argument( + "--slew-rad", + type=float, + default=DEFAULT_SLEW_RAD, + help="每物理步最大目标变化(rad);0=瞬跳跟真机。默认 0", + ) + p.add_argument( + "--phys-per-render", + type=int, + default=DEFAULT_PHYS_PER_RENDER, + help="每次渲染前进的物理步数(默认 16)", + ) + p.add_argument( + "--track-test", + action="store_true", + help="内置 open→半握,验收主动关节跟踪 ≤0.02rad", + ) + p.add_argument("--cmd-topic", default=TOPIC_G20_CMD, help="0~255 命令话题") + p.add_argument("--nominal-topic", default=TOPIC_NOMINAL) + p.add_argument("--sim-state-topic", default=TOPIC_SIM_STATE) + args, unknown = p.parse_known_args(_normalize_argv(sys.argv[1:])) + if unknown: + print(f"[args] ignoring unknown argv: {unknown}") + sys.argv = [sys.argv[0]] + return args + + +args = parse_args() + +from isaacsim import SimulationApp + +simulation_app = SimulationApp({"headless": args.headless}) + +import numpy as np + +import isaacsim.core.experimental.utils.app as app_utils +import isaacsim.core.experimental.utils.prim as prim_utils +import isaacsim.core.experimental.utils.stage as stage_utils +from isaacsim.core.experimental.objects import DistantLight, GroundPlane +from isaacsim.core.experimental.prims import Articulation, XformPrim +from isaacsim.core.rendering_manager import RenderingManager +from isaacsim.core.simulation_manager import SimulationManager +from isaacsim.core.utils.viewports import set_camera_view + +sys.path.insert(0, str(LINKERHAND_ROOT)) +from joint_mapping import ( + L20_SDK_TO_URDF, + complete_g20_mimic_positions, + g20_actuated_joint_names, + g20_required_joint_names, + open_hand_command, + sdk_range_to_full_urdf_positions, + urdf_positions_to_sdk_range, +) + +app_utils.enable_extension("isaacsim.ros2.bridge") +simulation_app.update() + +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import JointState + + +def _fix_base_to_world(hand_path: str) -> None: + from pxr import Gf, Usd, UsdGeom, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + + base = None + first = None + for prim in Usd.PrimRange(hand_prim): + if not prim.HasAPI(UsdPhysics.RigidBodyAPI): + continue + if first is None: + first = prim + if prim.GetName() in ("hand_base_link", "base_link", "palm"): + base = prim + break + base = base or first + if base is None: + print(f"[anchor] no RigidBody under {hand_path}") + return + + xf = UsdGeom.Xformable(base).ComputeLocalToWorldTransform(Usd.TimeCode.Default()) + pos = xf.ExtractTranslation() + quat = xf.ExtractRotationQuat() + pos_f = Gf.Vec3f(float(pos[0]), float(pos[1]), float(pos[2])) + rot_f = Gf.Quatf(float(quat.GetReal()), *[float(v) for v in quat.GetImaginary()]) + + for prim in Usd.PrimRange(hand_prim): + if prim.GetName() != "root_joint" or not prim.IsA(UsdPhysics.Joint): + continue + joint = UsdPhysics.Joint(prim) + b1 = [str(t) for t in (joint.GetBody1Rel().GetTargets() or [])] + b0 = [str(t) for t in (joint.GetBody0Rel().GetTargets() or [])] + if str(base.GetPath()) not in b1 or len(b0) != 0: + prim.SetActive(False) + print(f"[anchor] disabled invalid {prim.GetPath()}") + continue + if not prim.IsActive(): + prim.SetActive(True) + joint.CreateLocalPos0Attr().Set(pos_f) + joint.CreateLocalRot0Attr().Set(rot_f) + joint.CreateLocalPos1Attr().Set(Gf.Vec3f(0.0, 0.0, 0.0)) + joint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, 0.0, 0.0, 0.0)) + print( + f"[anchor] USD root_joint -> {base.GetPath()} @ " + f"({float(pos[0]):.3f},{float(pos[1]):.3f},{float(pos[2]):.3f})" + ) + return + + joint_path = f"{hand_path}/WorldFixedJoint" + if stage.GetPrimAtPath(joint_path).IsValid(): + stage.RemovePrim(joint_path) + joint = UsdPhysics.FixedJoint.Define(stage, joint_path) + joint.CreateBody0Rel().SetTargets([]) + joint.CreateBody1Rel().SetTargets([base.GetPath()]) + joint.CreateLocalPos0Attr().Set(pos_f) + joint.CreateLocalRot0Attr().Set(rot_f) + joint.CreateLocalPos1Attr().Set(Gf.Vec3f(0.0, 0.0, 0.0)) + joint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, 0.0, 0.0, 0.0)) + joint.CreateExcludeFromArticulationAttr().Set(False) + print(f"[anchor] WorldFixedJoint {joint_path}") + + +def _patch_joint_max_forces(hand_path: str, max_force: float = 8.0) -> None: + from pxr import Usd, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + for prim in Usd.PrimRange(hand_prim): + if not prim.IsA(UsdPhysics.RevoluteJoint): + continue + drive = UsdPhysics.DriveAPI.Get(prim, "angular") + if not drive: + continue + attr = drive.GetMaxForceAttr() + if attr and float(attr.Get() or 0.0) < max_force: + attr.Set(float(max_force)) + + +def _load_g20(usd_path: Path) -> str: + if not usd_path.is_file(): + raise FileNotFoundError(f"USD 不存在: {usd_path}") + mount = "/World/G20Hand" + stage_utils.define_prim(mount, "Xform") + XformPrim(mount, positions=[[0.0, HAND_MOUNT_Y, HAND_MOUNT_Z]], reset_xform_op_properties=True) + hand_path = f"{mount}/hand" + stage_utils.add_reference_to_stage(usd_path=str(usd_path), path=hand_path) + prim_utils.set_prim_variants(hand_path, variants=[("Physics", "physx")]) + _patch_joint_max_forces(hand_path) + return hand_path + + +def validate_g20_dof_names(dof_names: list[str]) -> None: + have = set(dof_names) + required = g20_required_joint_names() + missing = sorted(required - have) + if missing: + raise RuntimeError( + "G20 Articulation 关节名与 PLAN/URDF 规范不匹配,缺失: " + + ", ".join(missing) + + f" | have={sorted(have)}" + ) + + +class G20PlanBridge: + """订阅 cmd_u8 / PLAN 名义弧度,驱动 Articulation 并发布仿真状态。""" + + def __init__( + self, + node: Node, + art: Articulation, + *, + use_cmd_u8: bool, + cmd_topic: str, + use_physics_drive: bool, + nominal_topic: str, + sim_state_topic: str, + slew_rad: float = DEFAULT_SLEW_RAD, + ) -> None: + self.node = node + self.art = art + self.use_cmd_u8 = use_cmd_u8 + self.use_physics_drive = use_physics_drive + self.slew_rad = max(0.0, float(slew_rad)) + self.dof_names = list(art.dof_names) + validate_g20_dof_names(self.dof_names) + self.dof_index = {n: i for i, n in enumerate(self.dof_names)} + self.actuated = g20_actuated_joint_names() + self.actuated_indices = [self.dof_index[n] for n in sorted(self.actuated) if n in self.dof_index] + + lower, upper = art.get_dof_limits() + self._lo = lower.numpy().flatten() + self._hi = upper.numpy().flatten() + + open_full = sdk_range_to_full_urdf_positions(open_hand_command("G20"), "G20", "left") + open_full = complete_g20_mimic_positions(open_full) + self.goal: dict[str, float] = dict(open_full) + self.applied: dict[str, float] = dict(open_full) + self.targets = self.applied + self._last_warn_missing = 0.0 + self._last_warn_unknown = 0.0 + self.track_nominal: dict[str, float] | None = None + + if use_cmd_u8: + self.sub = node.create_subscription(JointState, cmd_topic, self._on_cmd_u8, 10) + self.legacy_pub = None + node.get_logger().info(f"G20 cmd_u8: sub {cmd_topic} (0~255 → URDF rad)") + else: + self.sub = node.create_subscription(JointState, nominal_topic, self._on_nominal, 10) + self.legacy_pub = None + node.get_logger().info(f"G20 PLAN: sub {nominal_topic} (by name, rad)") + + self.pub = node.create_publisher(JointState, sim_state_topic, 10) + node.get_logger().info( + f"G20: pub {sim_state_topic}, actuated={len(self.actuated_indices)}, " + f"drive={'PD' if use_physics_drive else 'position'}, " + f"slew_rad={self.slew_rad}" + ) + + def set_nominal_targets(self, positions: dict[str, float]) -> None: + self.goal = complete_g20_mimic_positions(positions) + self.track_nominal = {n: float(self.goal[n]) for n in self.actuated if n in self.goal} + + def _on_nominal(self, msg: JointState) -> None: + if not msg.name: + self._warn_missing("empty name[]") + return + n = min(len(msg.name), len(msg.position)) + incoming = {str(msg.name[i]): float(msg.position[i]) for i in range(n)} + unknown = [k for k in incoming if k not in self.dof_index] + if unknown: + self._warn_unknown(unknown) + missing_act = sorted(self.actuated - set(incoming.keys())) + if missing_act: + self._warn_missing(f"missing actuated: {missing_act}") + merged = dict(self.goal) + for k, v in incoming.items(): + if k in self.dof_index: + merged[k] = v + self.goal = complete_g20_mimic_positions(merged) + else: + merged = {k: v for k, v in incoming.items() if k in self.dof_index} + self.goal = complete_g20_mimic_positions(merged) + self.track_nominal = {n: float(self.goal[n]) for n in self.actuated if n in self.goal} + + def _on_cmd_u8(self, msg: JointState) -> None: + """接收与真机相同的 0~255 JointState(优先按 name,否则按下标)。""" + vals = [255.0] * 20 + name_to_sdk = {name: idx for idx, name in L20_SDK_TO_URDF.items()} + if msg.name: + n = min(len(msg.name), len(msg.position)) + for i in range(n): + key = str(msg.name[i]) + pos = float(msg.position[i]) + if key in name_to_sdk: + vals[name_to_sdk[key]] = pos + elif key.startswith("reserved_"): + try: + vals[int(key.split("_", 1)[1])] = pos + except ValueError: + pass + elif i < 20: + vals[i] = pos + else: + for i, x in enumerate(msg.position[:20]): + vals[i] = float(x) + full = sdk_range_to_full_urdf_positions(vals, "G20", "left") + self.set_nominal_targets(full) + + def _warn_missing(self, detail: str) -> None: + now = time.monotonic() + if now - self._last_warn_missing < WARN_INTERVAL_S: + return + self._last_warn_missing = now + self.node.get_logger().warn(f"nominal cmd incomplete, holding last targets ({detail})") + + def _warn_unknown(self, names: list[str]) -> None: + now = time.monotonic() + if now - self._last_warn_unknown < WARN_INTERVAL_S: + return + self._last_warn_unknown = now + self.node.get_logger().warn(f"unknown joint names ignored: {names[:8]}") + + def _slew_applied_toward_goal(self) -> None: + """每步把 applied 向 goal 限速逼近,产生中间运动过程。""" + max_step = self.slew_rad + margin = LIMIT_MARGIN_RAD + for name, g in self.goal.items(): + idx = self.dof_index.get(name) + if idx is None: + continue + lo = float(self._lo[idx]) + margin + hi = float(self._hi[idx]) - margin + if lo > hi: + lo = float(self._lo[idx]) + hi = float(self._hi[idx]) + g = float(np.clip(g, lo, hi)) + a = float(self.applied.get(name, g)) + if max_step <= 0.0: + a = g + else: + delta = g - a + if abs(delta) > max_step: + a = a + float(np.sign(delta) * max_step) + else: + a = g + self.applied[name] = float(np.clip(a, lo, hi)) + self.applied = complete_g20_mimic_positions(self.applied) + self.targets = self.applied + + def apply_targets(self) -> None: + self._slew_applied_toward_goal() + # PD:绝不能驱动 mimic(与 PhysX mimic 冲突 → Invalid PhysX transform) + # 位置硬写:写全关节(含已解析 mimic) + if self.use_physics_drive: + name_iter = (n for n in self.applied if n in self.actuated) + else: + name_iter = self.applied.keys() + + names = [] + vals = [] + for name in name_iter: + rad = self.applied[name] + idx = self.dof_index.get(name) + if idx is None: + continue + names.append(name) + vals.append(float(rad)) + if not names: + return + indices = [self.dof_index[n] for n in names] + positions = np.asarray(vals, dtype=np.float64) + if self.use_physics_drive: + self.art.set_dof_position_targets(positions, dof_indices=indices) + else: + self.art.set_dof_positions(positions, dof_indices=indices) + try: + self.art.set_dof_velocities( + np.zeros(len(indices), dtype=np.float64), dof_indices=indices + ) + except Exception: + pass + + def recover_if_invalid(self) -> bool: + """若出现 NaN/Inf,复位到张开名义位姿。""" + pos = self.art.get_dof_positions().numpy().flatten() + if np.isfinite(pos).all(): + return False + self.node.get_logger().warn("invalid dof state (NaN/Inf) → reset to open pose") + open_full = complete_g20_mimic_positions( + sdk_range_to_full_urdf_positions(open_hand_command("G20"), "G20", "left") + ) + self.goal = dict(open_full) + self.applied = dict(open_full) + self.targets = self.applied + self.track_nominal = {n: float(open_full[n]) for n in self.actuated if n in open_full} + names = [] + vals = [] + for name, rad in open_full.items(): + idx = self.dof_index.get(name) + if idx is None: + continue + names.append(name) + vals.append(float(np.clip(rad, float(self._lo[idx]), float(self._hi[idx])))) + if names: + indices = [self.dof_index[n] for n in names] + self.art.set_dof_positions(np.asarray(vals, dtype=np.float64), dof_indices=indices) + try: + self.art.set_dof_velocities( + np.zeros(len(indices), dtype=np.float64), dof_indices=indices + ) + except Exception: + pass + return True + + def publish_state(self) -> None: + pos = self.art.get_dof_positions().numpy().flatten() + try: + vel = self.art.get_dof_velocities().numpy().flatten() + except Exception: + vel = np.zeros_like(pos) + msg = JointState() + msg.header.stamp = self.node.get_clock().now().to_msg() + msg.name = list(self.dof_names) + msg.position = [float(x) for x in pos] + msg.velocity = [float(x) for x in vel] + self.pub.publish(msg) + if self.legacy_pub is not None: + by_name = {n: float(pos[i]) for i, n in enumerate(self.dof_names)} + sdk = urdf_positions_to_sdk_range(by_name, "G20", "left") + leg = JointState() + leg.header = msg.header + leg.name = [f"joint_{i}" for i in range(20)] + leg.position = [float(v) for v in sdk] + self.legacy_pub.publish(leg) + + def tracking_error(self) -> tuple[float, float]: + """Return (max_abs, mean_abs) over actuated joints vs track_nominal.""" + if not self.track_nominal: + return 0.0, 0.0 + pos = self.art.get_dof_positions().numpy().flatten() + errs = [] + for name, tgt in self.track_nominal.items(): + idx = self.dof_index.get(name) + if idx is None: + continue + errs.append(abs(float(pos[idx]) - float(tgt))) + if not errs: + return 0.0, 0.0 + return float(max(errs)), float(sum(errs) / len(errs)) + + +def _compare_camera_eye_target() -> tuple[list[float], list[float]]: + """正对掌心的 eye/target(世界系),与 MuJoCo COMPARE_* 一致(从 +X 看)。""" + import math + + ox, oy, oz = 0.0, HAND_MOUNT_Y, HAND_MOUNT_Z + lx, ly, lz = COMPARE_LOOKAT_LOCAL + target = [ox + lx, oy + ly, oz + lz] + elev = math.radians(COMPARE_ELEVATION_DEG) + # 从 +X 看向 lookat,略俯视(与 MuJoCo azimuth=180 同向) + eye = [ + target[0] + COMPARE_DISTANCE * math.cos(elev), + target[1], + target[2] - COMPARE_DISTANCE * math.sin(elev), + ] + return eye, target + + +def main() -> int: + stage_utils.create_new_stage() + stage_utils.set_stage_units(meters_per_unit=1.0) + GroundPlane("/World/GroundPlane", positions=[0.0, 0.0, 0.0]) + DistantLight("/World/DistantLight").set_intensities(300.0) + eye, target = _compare_camera_eye_target() + set_camera_view(eye=eye, target=target, camera_prim_path="/OmniverseKit_Persp") + + hand_path = _load_g20(args.g20_usd) + SimulationManager.set_physics_dt(1.0 / 120.0) + + app_utils.play() + simulation_app.update() + _fix_base_to_world(hand_path) + app_utils.stop() + simulation_app.update() + app_utils.play() + simulation_app.update() + # play/stop 后重设,避免 viewport 被重置 + eye, target = _compare_camera_eye_target() + set_camera_view(eye=eye, target=target, camera_prim_path="/OmniverseKit_Persp") + + art = Articulation(hand_path) + use_pd = bool(args.pd_drive) + if args.hand_gravity and not use_pd: + print("[warn] --hand-gravity ignored without --pd-drive (PLAN default is position drive)") + # 默认跟随 USD:自碰开启(防穿模);仅 --no-self-collision 关闭。 + enable_self_col = not bool(args.no_self_collision) + try: + art.set_enabled_self_collisions([enable_self_col]) + except Exception as exc: + print(f"[stabilize] self_collision set failed: {exc}") + print(f"[stabilize] self_collision={'ON' if enable_self_col else 'OFF'} (USD selective colliders)") + art.set_link_enabled_gravities(bool(args.hand_gravity) and use_pd) + if use_pd: + act = [ + i + for i, n in enumerate(art.dof_names) + if n in g20_actuated_joint_names() + ] + stiff = np.array( + [ + THUMB_PD_STIFFNESS if art.dof_names[i] in THUMB_ACTUATED else PD_STIFFNESS + for i in act + ], + dtype=float, + ) + damp = np.array( + [ + THUMB_PD_DAMPING if art.dof_names[i] in THUMB_ACTUATED else PD_DAMPING + for i in act + ], + dtype=float, + ) + effort = np.array( + [ + THUMB_PD_MAX_EFFORT if art.dof_names[i] in THUMB_ACTUATED else PD_MAX_EFFORT + for i in act + ], + dtype=float, + ) + art.set_dof_gains(stiffnesses=stiff, dampings=damp, dof_indices=act) + art.set_dof_max_efforts(effort, dof_indices=act) + # mimic 零增益,避免与 PhysX mimic 冲突 + mimic_idx = [ + i + for i, n in enumerate(art.dof_names) + if n not in g20_actuated_joint_names() + ] + if mimic_idx: + art.set_dof_gains( + stiffnesses=np.zeros(len(mimic_idx)), + dampings=np.zeros(len(mimic_idx)), + dof_indices=mimic_idx, + ) + else: + # 位置硬写:零增益避免与 set_dof_positions 冲突 + n = len(art.dof_names) + art.set_dof_gains(stiffnesses=np.zeros(n), dampings=np.zeros(n)) + + if not rclpy.ok(): + rclpy.init() + node = Node("isaac_g20_plan_bridge") + try: + use_cmd_u8 = not bool(args.plan_nominal) + cmd_topic = TOPIC_LEGACY_CMD if args.legacy_sdk else str(args.cmd_topic) + bridge = G20PlanBridge( + node, + art, + use_cmd_u8=use_cmd_u8, + cmd_topic=cmd_topic, + use_physics_drive=use_pd, + nominal_topic=args.nominal_topic, + sim_state_topic=args.sim_state_topic, + slew_rad=float(args.slew_rad), + ) + except RuntimeError as exc: + node.get_logger().error(str(exc)) + node.destroy_node() + rclpy.shutdown() + simulation_app.close() + return 1 + + # 初始 snap 到 open(跳过 slew) + old_slew = bridge.slew_rad + bridge.slew_rad = 0.0 + bridge.apply_targets() + bridge.slew_rad = old_slew + for _ in range(10): + SimulationManager.step() + simulation_app.update() + + if args.plan_nominal: + mode = "PLAN nominal" + elif args.legacy_sdk: + mode = f"cmd_u8:{TOPIC_LEGACY_CMD}" + else: + mode = f"cmd_u8:{args.cmd_topic}" + drive = "PD" if use_pd else "position" + node.get_logger().info( + f"仿真就绪 [{mode}, drive={drive}, slew={args.slew_rad} rad/step, " + f"phys/render={max(1, int(args.phys_per_render))}] pub={args.sim_state_topic}" + ) + + track_phase = 0 + track_ok = True + max_steps = int(args.max_steps) + if args.track_test and max_steps <= 0: + max_steps = 480 + phys_per_render = max(1, int(args.phys_per_render)) + + step = 0 + try: + while simulation_app.is_running(): + for _ in range(phys_per_render): + rclpy.spin_once(node, timeout_sec=0.0) + if args.track_test and step % 160 == 0: + if track_phase % 2 == 0: + cmd = open_hand_command("G20") + else: + cmd = [80.0] * 20 + bridge.set_nominal_targets( + sdk_range_to_full_urdf_positions(cmd, "G20", "left") + ) + track_phase += 1 + bridge.apply_targets() + SimulationManager.step() + if bridge.recover_if_invalid(): + bridge.apply_targets() + SimulationManager.step() + bridge.publish_state() + # 位置驱动:物理步进后再钉一次 + if not use_pd: + bridge.apply_targets() + step += 1 + if max_steps > 0 and step >= max_steps: + break + RenderingManager.render() + simulation_app.update() + if max_steps > 0 and step >= max_steps: + break + finally: + if args.track_test: + # settle:给够 slew 走完 + for _ in range(240): + bridge.apply_targets() + SimulationManager.step() + simulation_app.update() + mx, mean = bridge.tracking_error() + print( + f"[track-test] actuated max_abs={mx:.4f} rad mean_abs={mean:.4f} rad " + f"tol={TRACK_TOL_RAD}" + ) + track_ok = mx <= TRACK_TOL_RAD + print("[track-test] RESULT:", "PASS" if track_ok else "FAIL") + node.destroy_node() + if rclpy.ok(): + rclpy.shutdown() + simulation_app.close() + + return 0 if track_ok else 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/joint_mapping.py b/joint_mapping.py new file mode 100644 index 0000000..f56356c --- /dev/null +++ b/joint_mapping.py @@ -0,0 +1,282 @@ +# SPDX-License-Identifier: Apache-2.0 +"""LinkerHand SDK (0~255) ↔ URDF 关节弧度映射。逻辑与 ROS2 SDK mapping.py 一致。""" + +from __future__ import annotations + +# O6 +O6_L_MIN = [0, 0, 0, 0, 0, 0] +O6_L_MAX = [0.58, 1.36, 1.6, 1.6, 1.6, 1.6] +O6_L_DIR = [-1, -1, -1, -1, -1, -1] +O6_R_MIN = O6_L_MIN +O6_R_MAX = O6_L_MAX +O6_R_DIR = O6_L_DIR + +# G20(新 linkerhand_g20_left.urdf)限位;SDK 索引语义与 L20 相同 +L20_L_MIN = [0, 0, 0, 0, 0, 0.0, -0.23, -0.23, -0.23, -0.23, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +# 通道5 thumb_cmc_roll max:试调 1.47(原 1.4) +L20_L_MAX = [0.84, 1.22, 1.22, 1.22, 1.22, 1.47, 0.23, 0.23, 0.23, 0.23, 1.57, 0, 0, 0, 0, 1.29, 1.55, 1.55, 1.55, 1.55] +L20_L_DIR = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1] +L20_R_MIN = [0, 0, 0, 0, 0, 0.0, -0.23, -0.23, -0.23, -0.23, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +L20_R_MAX = [0.84, 1.22, 1.22, 1.22, 1.22, 1.47, 0.23, 0.23, 0.23, 0.23, 1.57, 0, 0, 0, 0, 1.29, 1.55, 1.55, 1.55, 1.55] +L20_R_DIR = [-1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1] + +# 左手 G20:四指侧摆 (SDK 6..9) 与弯曲方向相反 —— SDK0→下限、255→上限(见 g20_mapping) +G20_L_MIN = L20_L_MIN +G20_L_MAX = L20_L_MAX +G20_L_DIR = [-1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1] +G20_R_MIN = L20_R_MIN +G20_R_MAX = L20_R_MAX +G20_R_DIR = L20_R_DIR + +O6_SDK_JOINTS = [ + "thumb_cmc_pitch", + "thumb_cmc_yaw", + "index_mcp_pitch", + "middle_mcp_pitch", + "ring_mcp_pitch", + "pinky_mcp_pitch", +] + +# SDK 索引 → URDF 关节名(不含 lh_/rh_ 前缀) +L20_SDK_TO_URDF = { + 0: "thumb_cmc_pitch", + 1: "index_mcp_pitch", + 2: "middle_mcp_pitch", + 3: "ring_mcp_pitch", + 4: "pinky_mcp_pitch", + 5: "thumb_cmc_roll", + 6: "index_mcp_roll", + 7: "middle_mcp_roll", + 8: "ring_mcp_roll", + 9: "pinky_mcp_roll", + 10: "thumb_cmc_yaw", + 15: "thumb_mcp", + 16: "index_pip", + 17: "middle_pip", + 18: "ring_pip", + 19: "pinky_pip", +} + +# URDF dip 关节 mimic pip:dip = pip * multiplier(G20 URDF) +DIP_MIMIC_MULTIPLIER = 0.89 +THUMB_IP_MIMIC_MULTIPLIER = 1.02 + + +def scale_value(original_value: float, a_min: float, a_max: float, b_min: float, b_max: float) -> float: + if a_max == a_min: + return b_min + return (original_value - a_min) * (b_max - b_min) / (a_max - a_min) + b_min + + +def clamp(value: float, low: float, high: float) -> float: + return max(low, min(high, value)) + + +def _tables(hand: str, side: str) -> tuple[list[float], list[float], list[int]]: + if hand == "O6": + if side == "left": + return O6_L_MIN, O6_L_MAX, O6_L_DIR + return O6_R_MIN, O6_R_MAX, O6_R_DIR + if hand == "G20": + if side == "left": + return G20_L_MIN, G20_L_MAX, G20_L_DIR + return G20_R_MIN, G20_R_MAX, G20_R_DIR + if side == "left": + return L20_L_MIN, L20_L_MAX, L20_L_DIR + return L20_R_MIN, L20_R_MAX, L20_R_DIR + + +def range_to_arc(values: list[float], hand: str, side: str) -> list[float]: + """SDK 0~255 → 弧度(每 DOF 一条)。""" + j_min, j_max, j_dir = _tables(hand, side) + num = 6 if hand == "O6" else 20 + arcs = [0.0] * num + for i in range(num): + if hand in ("L20", "G20") and 11 <= i <= 14: + continue + val = clamp(values[i] if i < len(values) else 0.0, 0.0, 255.0) + if j_dir[i] == -1: + arcs[i] = scale_value(val, 0.0, 255.0, j_max[i], j_min[i]) + else: + arcs[i] = scale_value(val, 0.0, 255.0, j_min[i], j_max[i]) + return arcs + + +def arc_to_range(arcs: list[float], hand: str, side: str) -> list[int]: + """弧度 → SDK 0~255。""" + j_min, j_max, j_dir = _tables(hand, side) + num = 6 if hand == "O6" else 20 + ranges = [0] * num + for i in range(num): + if hand in ("L20", "G20") and 11 <= i <= 14: + ranges[i] = 255 + continue + val = clamp(arcs[i] if i < len(arcs) else 0.0, j_min[i], j_max[i]) + if j_dir[i] == -1: + ranges[i] = int(round(scale_value(val, j_min[i], j_max[i], 255.0, 0.0))) + else: + ranges[i] = int(round(scale_value(val, j_min[i], j_max[i], 0.0, 255.0))) + return ranges + + +def mimic_joint_names(hand: str, side: str) -> set[str]: + """PhysX/Newton mimic 从动关节,不可施加 position drive。""" + if hand == "O6": + prefix = "lh_" if side == "left" else "rh_" + return { + f"{prefix}thumb_ip", + f"{prefix}index_dip", + f"{prefix}middle_dip", + f"{prefix}ring_dip", + f"{prefix}pinky_dip", + } + return {"pinky_dip", "ring_dip", "middle_dip", "index_dip", "thumb_ip"} + + +# G20 URDF / Isaac USD 规范关节名(PLAN 名义弧度桥按名匹配) +G20_ACTUATED_JOINT_NAMES: tuple[str, ...] = tuple( + sorted({name for name in L20_SDK_TO_URDF.values()}) +) +G20_MIMIC_JOINT_NAMES: tuple[str, ...] = ( + "thumb_ip", + "index_dip", + "middle_dip", + "ring_dip", + "pinky_dip", +) +G20_ALL_JOINT_NAMES: tuple[str, ...] = tuple( + sorted(set(G20_ACTUATED_JOINT_NAMES) | set(G20_MIMIC_JOINT_NAMES)) +) + +# mimic 从动 ← (主动, 倍率);与 G20 URDF / Physics mimic 一致 +G20_MIMIC_OF: dict[str, tuple[str, float]] = { + "thumb_ip": ("thumb_mcp", THUMB_IP_MIMIC_MULTIPLIER), + "index_dip": ("index_pip", DIP_MIMIC_MULTIPLIER), + "middle_dip": ("middle_pip", DIP_MIMIC_MULTIPLIER), + "ring_dip": ("ring_pip", DIP_MIMIC_MULTIPLIER), + "pinky_dip": ("pinky_pip", DIP_MIMIC_MULTIPLIER), +} + + +def g20_required_joint_names() -> frozenset[str]: + """启动校验:Articulation 必须包含的全部 G20 关节名。""" + return frozenset(G20_ALL_JOINT_NAMES) + + +def g20_actuated_joint_names() -> frozenset[str]: + return frozenset(G20_ACTUATED_JOINT_NAMES) + + +def complete_g20_mimic_positions(positions: dict[str, float]) -> dict[str, float]: + """补全缺失的 mimic 关节;已给出的 mimic 值优先保留。""" + out = dict(positions) + for mimic, (master, ratio) in G20_MIMIC_OF.items(): + if mimic in out: + continue + if master in out: + out[mimic] = float(out[master]) * float(ratio) + return out + + +# SDK 张开预设(与 gui_control/config/constants.py 一致) +L20_OPEN_CMD = [ + 255, 255, 255, 255, 255, 255, 10, 100, 180, 240, 245, + 255, 255, 255, 255, 255, 255, 255, 255, 255, +] +G20_OPEN_CMD = [ + 255, 255, 255, 255, 255, 255, 193, 148, 105, 42, 245, + 255, 255, 255, 255, 255, 255, 255, 255, 255, +] + + +def open_hand_command(hand: str) -> list[float]: + if hand == "O6": + return [255.0] * 6 + if hand == "G20": + return [float(v) for v in G20_OPEN_CMD] + return [float(v) for v in L20_OPEN_CMD] + + +def _joint_prefix(side: str, hand: str) -> str: + if hand == "O6": + return "lh_" if side == "left" else "rh_" + return "" + + +O6_MIMIC_OF = { + "thumb_ip": ("thumb_cmc_pitch", 2.29), + "index_dip": ("index_mcp_pitch", 0.89), + "middle_dip": ("middle_mcp_pitch", 0.89), + "ring_dip": ("ring_mcp_pitch", 0.89), + "pinky_dip": ("pinky_mcp_pitch", 0.89), +} + + +def sdk_range_to_urdf_positions(values: list[float], hand: str, side: str) -> dict[str, float]: + """将 SDK 指令转为 URDF 关节名 → 弧度。USD 中 mimic 关节由物理引擎跟随。""" + arcs = range_to_arc(values, hand, side) + prefix = _joint_prefix(side, hand) + out: dict[str, float] = {} + + if hand == "O6": + for sdk_idx, short_name in enumerate(O6_SDK_JOINTS): + out[f"{prefix}{short_name}"] = arcs[sdk_idx] + return out + + for sdk_idx, short_name in L20_SDK_TO_URDF.items(): + arc = arcs[sdk_idx] + if sdk_idx == 15: + # SDK 控制指尖弧度;thumb_ip mimic thumb_mcp + out["thumb_mcp"] = arc / THUMB_IP_MIMIC_MULTIPLIER + elif sdk_idx in (16, 17, 18, 19): + # SDK 控制 DIP 电机弧度;URDF 中 dip mimic pip + out[short_name] = arc / DIP_MIMIC_MULTIPLIER + else: + out[short_name] = arc + return out + + +def sdk_range_to_full_urdf_positions(values: list[float], hand: str, side: str) -> dict[str, float]: + """主动关节 + 解析 mimic 从动关节,供运动学逐帧写入。""" + out = sdk_range_to_urdf_positions(values, hand, side) + prefix = _joint_prefix(side, hand) + + if hand == "O6": + for mimic_suffix, (master_suffix, ratio) in O6_MIMIC_OF.items(): + master = out.get(f"{prefix}{master_suffix}") + if master is not None: + out[f"{prefix}{mimic_suffix}"] = master * ratio + return out + + for finger in ("index", "middle", "ring", "pinky"): + pip = out.get(f"{finger}_pip") + if pip is not None: + out[f"{finger}_dip"] = pip * DIP_MIMIC_MULTIPLIER + thumb_mcp = out.get("thumb_mcp") + if thumb_mcp is not None: + out["thumb_ip"] = thumb_mcp * THUMB_IP_MIMIC_MULTIPLIER + return out + + +def urdf_positions_to_sdk_range(joint_positions: dict[str, float], hand: str, side: str) -> list[int]: + """从 URDF 主动关节读数反算 SDK 0~255 反馈(不读 mimic 从动关节)。""" + mapping_hand = hand if hand in ("O6", "G20", "L20") else "L20" + prefix = _joint_prefix(side, mapping_hand) + arcs = [0.0] * (6 if mapping_hand == "O6" else 20) + + if mapping_hand == "O6": + for sdk_idx, short_name in enumerate(O6_SDK_JOINTS): + key = f"{prefix}{short_name}" + arcs[sdk_idx] = joint_positions.get(key, 0.0) + return arc_to_range(arcs, mapping_hand, side) + + for sdk_idx, short_name in L20_SDK_TO_URDF.items(): + if sdk_idx == 15: + thumb_mcp = joint_positions.get("thumb_mcp", 0.0) + arcs[sdk_idx] = thumb_mcp * THUMB_IP_MIMIC_MULTIPLIER + elif sdk_idx in (16, 17, 18, 19): + pip = joint_positions.get(short_name, 0.0) + arcs[sdk_idx] = pip * DIP_MIMIC_MULTIPLIER + else: + arcs[sdk_idx] = joint_positions.get(short_name, 0.0) + return arc_to_range(arcs, mapping_hand, side) diff --git a/linker_hand_dual_sim.py b/linker_hand_dual_sim.py new file mode 100644 index 0000000..6fd02f2 --- /dev/null +++ b/linker_hand_dual_sim.py @@ -0,0 +1,1162 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""在 Isaac Sim 中加载 LinkerHand G20 灵巧手,并通过 ROS2 话题控制。 + +默认仅加载 G20(``linkerhand_g20_left`` USD)。 +默认 PD 动力学,以体现交付 USD 中的自碰/掌心接触垫; +``--position-drive`` 硬写关节(UI 跟手,但会穿模); +``--hand-gravity`` 开手部重力。 +""" + +from __future__ import annotations + +import argparse +import sys +from pathlib import Path + +LINKERHAND_ROOT = Path(__file__).resolve().parent +URDF_ROOT = LINKERHAND_ROOT / "urdf" + +DEFAULT_ASSETS = { + ("O6", "left"): URDF_ROOT / "o6/left/linkerhand_o6_left/linkerhand_o6_left.usda", + ("G20", "left"): URDF_ROOT / "g20/left/linkerhand_g20_left/linkerhand_g20_left.usda", +} + +TOPICS = { + "O6": { + "cmd": "/o6/cb_left_hand_control_cmd", + "state": "/o6/cb_left_hand_state", + }, + "G20": { + "cmd": "/cb_left_hand_control_cmd", + "state": "/cb_left_hand_state", + }, +} + +# 默认 PD:交付 USD 的自碰/掌心垫才会生效。硬写位置用 --position-drive(可穿模)。 +DEFAULT_DRIVE_STIFFNESS = 80.0 +DEFAULT_DRIVE_DAMPING = 25.0 +G20_DRIVE_STIFFNESS = 25.0 +G20_DRIVE_DAMPING = 40.0 +GRAVITY_STIFFNESS_SCALE = 1.0 +GRAVITY_DAMPING_SCALE = 1.2 +DEFAULT_ACTUATED_MAX_EFFORT = 8.0 +# 每物理步最大目标变化(rad) +MAX_TARGET_STEP_RAD = 0.006 +CMD_SMOOTH_ALPHA = 0.08 +CMD_SETTLE_EPS = 0.5 +# 手掌安装高度(米)——抬高避免手指触地冲飞 +HAND_MOUNT_Z = 0.70 +HAND_MOUNT_Y = 0.45 +# 根节点偏离安装位超过该距离视为爆炸并复位 +ROOT_EXPLODE_DIST_M = 0.50 +# 接触尖峰可达上千 rad/s;硬复位只会更抖。真正爆炸只看 NaN/根漂移。 +DOF_VEL_SOFT_CLAMP = 30.0 +DOF_VEL_HARD_LIMIT = 1.0e9 + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="LinkerHand O6 + G20 dual-hand Isaac Sim ROS2 bridge") + parser.add_argument("--headless", action="store_true", help="无 GUI 运行") + parser.add_argument("--kinematic", action="store_true", help="运动学驱动(无物理,不适合测摩擦)") + parser.add_argument( + "--hand-gravity", + action="store_true", + help="启用手部连杆重力(PD 下生效;硬写位置驱动会忽略)", + ) + parser.add_argument( + "--pd-drive", + action="store_true", + help="PD 动力学驱动(默认已开启;与 --position-drive 互斥时以位置驱动为准)", + ) + parser.add_argument( + "--self-collision", + action="store_true", + help="强制走 PD 以便体现 USD 自碰(默认 PD 下已启用 USD 自碰)", + ) + parser.add_argument( + "--anti-penetration", + action="store_true", + help="兼容旧参数:碰撞/自碰已烘焙进 USD,无需再开", + ) + parser.add_argument( + "--no-collision", + action="store_true", + help="关闭全部碰撞几何(调试用)", + ) + parser.add_argument( + "--position-drive", + action="store_true", + help="硬写关节位置(UI 跟手,但会穿模;忽略 USD 自碰)", + ) + parser.add_argument("--drive-stiffness", type=float, default=DEFAULT_DRIVE_STIFFNESS) + parser.add_argument("--drive-damping", type=float, default=DEFAULT_DRIVE_DAMPING) + parser.add_argument("--g20-drive-stiffness", type=float, default=G20_DRIVE_STIFFNESS) + parser.add_argument("--g20-drive-damping", type=float, default=G20_DRIVE_DAMPING) + parser.add_argument("--cmd-smooth", type=float, default=CMD_SMOOTH_ALPHA, help="指令低通 0~1,越大越跟手") + parser.add_argument("--o6-usd", type=Path, default=DEFAULT_ASSETS[("O6", "left")]) + parser.add_argument("--g20-usd", type=Path, default=DEFAULT_ASSETS[("G20", "left")]) + parser.add_argument("--l20-usd", type=Path, dest="g20_usd", help=argparse.SUPPRESS) + parser.add_argument("--o6-side", choices=["left", "right"], default="left") + parser.add_argument("--g20-side", choices=["left", "right"], default="left") + parser.add_argument("--o6-only", action="store_true", help="仅加载 O6") + parser.add_argument("--g20-only", action="store_true", help="仅加载 G20") + parser.add_argument("--both", action="store_true", help="同时加载 O6 + G20") + parser.add_argument("--l20-side", choices=["left", "right"], dest="g20_side", help=argparse.SUPPRESS) + parser.add_argument("--max-steps", type=int, default=0, help="运行指定步数后退出,0 表示持续运行") + parser.add_argument( + "--hold-open", + action="store_true", + help="忽略外部 control_cmd,始终保持 SDK 张开姿态(排查漂移/外部节点干扰)", + ) + parser.add_argument( + "--stability-test", + action="store_true", + help="跑固定步数并打印 G20 状态漂移统计后退出(自动 hold-open)", + ) + parser.add_argument( + "--motion-test", + action="store_true", + help="开合循环压力测试(内部切指令,不依赖外部 ROS pub)", + ) + return parser.parse_args() + + +args = parse_args() + +from isaacsim import SimulationApp + +simulation_app = SimulationApp({"headless": args.headless}) + +import numpy as np + +import isaacsim.core.experimental.utils.app as app_utils +import isaacsim.core.experimental.utils.prim as prim_utils +import isaacsim.core.experimental.utils.stage as stage_utils +from isaacsim.core.experimental.objects import DistantLight, GroundPlane +from isaacsim.core.experimental.prims import Articulation, XformPrim +from isaacsim.core.rendering_manager import RenderingManager +from isaacsim.core.simulation_manager import SimulationManager +from isaacsim.core.utils.viewports import set_camera_view + +sys.path.insert(0, str(LINKERHAND_ROOT)) +from joint_mapping import ( + G20_OPEN_CMD, + O6_SDK_JOINTS, + mimic_joint_names, + open_hand_command, + sdk_range_to_full_urdf_positions, + sdk_range_to_urdf_positions, + urdf_positions_to_sdk_range, +) + +app_utils.enable_extension("isaacsim.ros2.bridge") +simulation_app.update() + +import rclpy +from rclpy.node import Node +from sensor_msgs.msg import JointState + + +class HandBridge: + """单只手的 ROS2 ↔ Articulation 桥。""" + + def __init__( + self, + node: Node, + articulation: Articulation, + hand: str, + side: str, + cmd_topic: str, + state_topic: str, + *, + kinematic: bool, + cmd_smooth: float, + hold_open: bool = False, + use_physics_drive: bool = False, + ) -> None: + self.node = node + self.art = articulation + self.hand = hand + self.mapping_hand = hand if hand in ("O6", "G20", "L20") else "L20" + self.side = side + self.kinematic = kinematic + self.hold_open = hold_open + self.use_physics_drive = use_physics_drive + self.cmd_smooth = float(np.clip(cmd_smooth, 0.0, 1.0)) + self.dof_count = 6 if hand == "O6" else 20 + open_cmd = open_hand_command(hand) + self.cmd_values = list(open_cmd) + self.smoothed_cmd = list(open_cmd) + self._last_applied_key: tuple[float, ...] | None = None + self._slew_targets: dict[int, float] = {} + self._mount_position = None # set by main after load + self.dof_names = list(articulation.dof_names) + self.dof_index = {name: i for i, name in enumerate(self.dof_names)} + self.mimic_dofs = mimic_joint_names(self.mapping_hand, side) + self.actuated_dof_indices = [ + i for i, name in enumerate(self.dof_names) if name not in self.mimic_dofs + ] + self._actuated_names = {self.dof_names[i] for i in self.actuated_dof_indices} + + lower, upper = articulation.get_dof_limits() + self._limit_lo = lower.numpy().flatten() + self._limit_hi = upper.numpy().flatten() + + if not hold_open: + self.sub = node.create_subscription(JointState, cmd_topic, self._on_cmd, 10) + self.pub = node.create_publisher(JointState, state_topic, 10) + self._recover_cooldown = 0 + self.explode_count = 0 + self.max_root_drift = 0.0 + mode = "kinematic" if kinematic else "dynamic(PD)" + hold_note = ", hold-open" if hold_open else "" + drive_note = "PD" if use_physics_drive else "position" + node.get_logger().info( + f"{hand} ({side}) [{mode}{hold_note}, drive={drive_note}]: sub {cmd_topic}, " + f"actuated={len(self.actuated_dof_indices)} mimic={len(self.mimic_dofs)}" + ) + + def set_sdk_command(self, values: list[float]) -> None: + """内部压力测试:直接写 SDK 指令(绕过 ROS)。""" + n = min(len(values), self.dof_count) + self.cmd_values[:n] = [float(v) for v in values[:n]] + + def _on_cmd(self, msg: JointState) -> None: + if self.hold_open or not msg.position: + return + n = min(len(msg.position), self.dof_count) + incoming = [float(v) for v in msg.position[:n]] + if all(abs(incoming[i] - self.cmd_values[i]) < CMD_SETTLE_EPS for i in range(n)): + return + self.cmd_values[:n] = incoming + + def _smooth_commands(self) -> None: + if self.hold_open: + self.cmd_values = list(open_hand_command(self.hand)) + self.smoothed_cmd = list(self.cmd_values) + return + a = self.cmd_smooth + if a <= 0.0: + self.smoothed_cmd = list(self.cmd_values) + return + for i in range(self.dof_count): + self.smoothed_cmd[i] = (1.0 - a) * self.smoothed_cmd[i] + a * self.cmd_values[i] + if max(abs(self.smoothed_cmd[i] - self.cmd_values[i]) for i in range(self.dof_count)) < CMD_SETTLE_EPS: + self.smoothed_cmd = list(self.cmd_values) + + def _resolve_targets(self) -> dict[str, float]: + # 位置驱动/运动学:写全关节(含 mimic,比率需与 URDF 一致) + if self.kinematic or not self.use_physics_drive: + return sdk_range_to_full_urdf_positions(self.smoothed_cmd, self.mapping_hand, self.side) + return sdk_range_to_urdf_positions(self.smoothed_cmd, self.mapping_hand, self.side) + + def _targets_to_dof_lists(self, targets: dict[str, float]) -> tuple[list[int], list[float]]: + dof_indices: list[int] = [] + positions: list[float] = [] + for joint_name, rad in targets.items(): + idx = self._resolve_dof_index(joint_name) + if idx is None: + continue + lo = float(self._limit_lo[idx]) + hi = float(self._limit_hi[idx]) + if hi > lo: + rad = float(np.clip(rad, lo, hi)) + # 斜坡限制:相对上一帧已下发目标,避免大跳 + prev = self._slew_targets.get(idx, rad) + delta = rad - prev + if abs(delta) > MAX_TARGET_STEP_RAD: + rad = prev + float(np.sign(delta) * MAX_TARGET_STEP_RAD) + if hi > lo: + rad = float(np.clip(rad, lo, hi)) + self._slew_targets[idx] = rad + dof_indices.append(idx) + positions.append(rad) + return dof_indices, positions + + def _is_exploded(self) -> tuple[bool, str]: + """返回 (是否需硬复位, 原因)。速度尖峰单独处理,不触发张开复位。""" + try: + root = self.art.get_world_poses()[0] + root = root.numpy().flatten() if hasattr(root, "numpy") else np.asarray(root).flatten() + if np.isnan(root).any() or np.isinf(root).any(): + return True, "root_nan" + if self._mount_position is not None: + mount = np.asarray(self._mount_position, dtype=float) + drift = float(np.linalg.norm(root[:3] - mount)) + self.max_root_drift = max(self.max_root_drift, drift) + limit = ROOT_EXPLODE_DIST_M if self.use_physics_drive else 5.0 + if drift > limit: + return True, f"root_drift={drift:.3f}m" + elif float(np.max(np.abs(root))) > 5.0: + return True, "root_far" + + pos = self.art.get_dof_positions() + pos = pos.numpy().flatten() if hasattr(pos, "numpy") else np.asarray(pos).flatten() + if np.isnan(pos).any() or np.isinf(pos).any(): + return True, "dof_pos_nan" + + if self.use_physics_drive: + try: + vel = self.art.get_dof_velocities() + vel = vel.numpy().flatten() if hasattr(vel, "numpy") else np.asarray(vel).flatten() + if np.isnan(vel).any() or np.isinf(vel).any(): + return True, "dof_vel_nan" + max_abs = float(np.max(np.abs(vel))) if len(vel) else 0.0 + if max_abs > DOF_VEL_HARD_LIMIT: + return True, f"dof_vel={max_abs:.1f}" + if max_abs > DOF_VEL_SOFT_CLAMP: + # 自碰接触尖峰:只清速度,不当成爆炸 + try: + self.art.set_dof_velocities([0.0] * len(vel)) + except Exception: + pass + return False, f"vel_spike={max_abs:.1f}_clamped" + except Exception: + pass + except Exception as exc: + return True, f"exception:{exc}" + return False, "" + + def _pin_root(self) -> None: + """把掌根钉回安装位(仅硬写位置驱动备份;PD+WorldFixedJoint 时不要调)。""" + if self._mount_position is None or self.use_physics_drive: + return + try: + self.art.set_world_poses( + positions=[self._mount_position], + orientations=[[1.0, 0.0, 0.0, 0.0]], + ) + if hasattr(self.art, "set_velocities"): + self.art.set_velocities( + linear_velocities=[[0.0, 0.0, 0.0]], + angular_velocities=[[0.0, 0.0, 0.0]], + ) + except Exception as exc: + self.node.get_logger().warn(f"{self.hand}: _pin_root failed: {exc}") + + def recover_if_exploded(self) -> bool: + """物理爆炸后复位到张开姿态。返回是否发生了硬复位。""" + if getattr(self, "_recover_cooldown", 0) > 0: + self._recover_cooldown -= 1 + if not self.use_physics_drive: + self._pin_root() + # PD 下若仍 NaN,必须再 snap 一次,否则冷却期结束后会立刻再爆 + try: + pos = self.art.get_dof_positions() + pos = pos.numpy().flatten() if hasattr(pos, "numpy") else np.asarray(pos).flatten() + if np.isnan(pos).any() or np.isinf(pos).any(): + self.initialize_pose() + self.art.set_dof_velocities([0.0] * int(self.art.num_dofs)) + except Exception: + try: + self.initialize_pose() + except Exception: + pass + return True + exploded, reason = self._is_exploded() + if not exploded: + return False + try: + root = self.art.get_world_poses()[0] + root = root.numpy().flatten() if hasattr(root, "numpy") else np.asarray(root).flatten() + root_txt = [round(float(x), 3) for x in root[:3]] + except Exception: + root_txt = ["?"] + self.node.get_logger().warn( + f"{self.hand}: 物理爆炸复位 reason={reason} root={root_txt}" + ) + self.explode_count += 1 + self.cmd_values = list(open_hand_command(self.hand)) + self.smoothed_cmd = list(self.cmd_values) + self._slew_targets.clear() + self._last_applied_key = None + self._pin_root() + try: + n = self.art.num_dofs + if n > 0: + self.art.set_dof_velocities([0.0] * n) + except Exception: + pass + self.initialize_pose() + self._pin_root() + self._recover_cooldown = 30 + return True + + def apply_targets(self) -> None: + if self.recover_if_exploded(): + return + # 位置驱动:每帧钉掌根(O6 无 WorldFixedJoint;G20 作备份) + if not self.use_physics_drive: + self._pin_root() + self._smooth_commands() + targets = self._resolve_targets() + dof_indices, positions = self._targets_to_dof_lists(targets) + if not dof_indices: + return + apply_key = tuple(round(p, 5) for p in positions) + self._last_applied_key = apply_key + if self.kinematic or not self.use_physics_drive: + self.art.set_dof_positions(positions, dof_indices=dof_indices) + else: + self.art.set_dof_position_targets(positions, dof_indices=dof_indices) + + def _read_sdk_state(self) -> list[float]: + dof_pos = self.art.get_dof_positions() + if hasattr(dof_pos, "numpy"): + pos_array = dof_pos.numpy().flatten() + else: + pos_array = np.asarray(dof_pos).flatten() + + joint_pos_map: dict[str, float] = {} + for name in self._actuated_names: + idx = self.dof_index.get(name) + if idx is not None and idx < len(pos_array): + joint_pos_map[name] = float(pos_array[idx]) + return [float(v) for v in urdf_positions_to_sdk_range(joint_pos_map, self.hand, self.side)] + + def publish_state(self) -> None: + sdk_range = self._read_sdk_state() + msg = JointState() + msg.header.stamp = self.node.get_clock().now().to_msg() + if self.hand == "O6": + msg.name = list(O6_SDK_JOINTS) + else: + msg.name = [f"motor_{i}" for i in range(20)] + msg.position = sdk_range + self.pub.publish(msg) + + def _resolve_dof_index(self, joint_name: str) -> int | None: + if joint_name in self.dof_index: + return self.dof_index[joint_name] + for name, idx in self.dof_index.items(): + if name.endswith(joint_name) or name.split("/")[-1] == joint_name: + return idx + return None + + def snap_pose(self) -> None: + """强制写入关节角与 PD 目标(初始化/复位)。""" + if self.hold_open: + self.smoothed_cmd = list(open_hand_command(self.hand)) + self.cmd_values = list(self.smoothed_cmd) + # snap 时跳过斜坡,直接到位 + self._slew_targets.clear() + targets = self._resolve_targets() + # 直接限幅,不走斜坡字典预填 + dof_indices: list[int] = [] + positions: list[float] = [] + for joint_name, rad in targets.items(): + idx = self._resolve_dof_index(joint_name) + if idx is None: + continue + lo = float(self._limit_lo[idx]) + hi = float(self._limit_hi[idx]) + if hi > lo: + rad = float(np.clip(rad, lo, hi)) + self._slew_targets[idx] = rad + dof_indices.append(idx) + positions.append(rad) + if not dof_indices: + return + self.art.set_dof_positions(positions, dof_indices=dof_indices) + if not self.kinematic and self.use_physics_drive: + self.art.set_dof_position_targets(positions, dof_indices=dof_indices) + self._last_applied_key = tuple(round(p, 5) for p in positions) + + def initialize_pose(self) -> None: + self.snap_pose() + if not self.kinematic and self.use_physics_drive and self.actuated_dof_indices: + self.art.set_dof_velocities( + [0.0] * len(self.actuated_dof_indices), + dof_indices=self.actuated_dof_indices, + ) + + +def _configure_drives( + articulation: Articulation, + hand: str, + side: str, + *, + kinematic: bool, + stiffness: float, + damping: float, + max_effort: float = DEFAULT_ACTUATED_MAX_EFFORT, +) -> None: + mapping_hand = "O6" if hand == "O6" else "L20" + mimics = mimic_joint_names(mapping_hand, side) + actuated: list[int] = [] + mimic_indices: list[int] = [] + for i, name in enumerate(articulation.dof_names): + (mimic_indices if name in mimics else actuated).append(i) + + if kinematic: + n = articulation.num_dofs + if n > 0: + articulation.set_dof_gains(stiffnesses=[0.0] * n, dampings=[0.0] * n) + return + + # 位置驱动遥操作:增益必须为 0,否则 PD 与 set_dof_positions 硬刚导致爆炸 + if stiffness <= 0.0 and damping <= 0.0: + n = articulation.num_dofs + if n > 0: + articulation.set_dof_gains(stiffnesses=[0.0] * n, dampings=[0.0] * n) + return + + if actuated: + articulation.set_dof_gains( + stiffnesses=[stiffness] * len(actuated), + dampings=[damping] * len(actuated), + dof_indices=actuated, + ) + articulation.set_dof_max_efforts( + [max_effort] * len(actuated), + dof_indices=actuated, + ) + if mimic_indices: + # 不要把 mimic 的 stiffness 设为 0:部分后端会破坏 mimic 约束,连带整手塌陷 + articulation.set_dof_max_efforts( + [max_effort] * len(mimic_indices), + dof_indices=mimic_indices, + ) + + +def _author_self_collisions(hand_path: str, enabled: bool) -> None: + """在 ArticulationRoot 上写入 PhysX/Newton 自碰,并配置碰撞体。 + + enabled=True 时:关掉掌心/CMC 肥凸包,只保留手指段碰撞,降低自碰爆炸概率。 + """ + from pxr import Sdf, Usd, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + + try: + from pxr import PhysxSchema + + has_physx_schema = True + except ImportError: + has_physx_schema = False + + # 这些碰撞体与拇指运动包络严重重叠,开自碰必顶死/NaN + disable_col_names = { + "hand_base_link", + "thumb_metacarpals_base1", + "thumb_metacarpals_base2", + "thumb_metacarpals", + "index_metacarpals", + "middle_metacarpals", + "ring_metacarpals", + "pinky_metacarpals", + } + + predicate = Usd.TraverseInstanceProxies(Usd.PrimAllPrimsPredicate) + n_roots = 0 + n_col_on = 0 + n_col_off = 0 + for prim in Usd.PrimRange(hand_prim, predicate): + if prim.HasAPI(UsdPhysics.ArticulationRootAPI) or prim.HasAPI("PhysicsArticulationRootAPI"): + if has_physx_schema: + PhysxSchema.PhysxArticulationAPI.Apply(prim) + attr = prim.GetAttribute("physxArticulation:enabledSelfCollisions") + if not attr: + attr = prim.CreateAttribute( + "physxArticulation:enabledSelfCollisions", Sdf.ValueTypeNames.Bool + ) + attr.Set(bool(enabled)) + nattr = prim.GetAttribute("newton:selfCollisionEnabled") + if not nattr: + nattr = prim.CreateAttribute("newton:selfCollisionEnabled", Sdf.ValueTypeNames.Bool) + nattr.Set(bool(enabled)) + n_roots += 1 + if ( + prim.HasAPI(UsdPhysics.CollisionAPI) + or prim.HasAPI("PhysicsCollisionAPI") + or prim.HasAPI("PhysicsMeshCollisionAPI") + ): + name = prim.GetName() + col_on = True + if enabled and name in disable_col_names: + col_on = False + try: + if prim.HasAPI(UsdPhysics.CollisionAPI): + UsdPhysics.CollisionAPI(prim).CreateCollisionEnabledAttr().Set(col_on) + else: + attr = prim.GetAttribute("physics:collisionEnabled") + if not attr: + attr = prim.CreateAttribute( + "physics:collisionEnabled", Sdf.ValueTypeNames.Bool + ) + attr.Set(col_on) + if col_on: + n_col_on += 1 + else: + n_col_off += 1 + except Exception: + pass + print( + f"[stabilize] authored self_collision={enabled} roots={n_roots} " + f"col_on={n_col_on} col_off={n_col_off} under {hand_path}" + ) + if enabled: + _filter_thumb_palm_collisions(hand_path) + + +def _filter_thumb_palm_collisions(hand_path: str) -> None: + """拇指链与掌根凸包在 CMC 处天然重叠;PhysX 只自动忽略父子连杆。 + + 不过滤时自碰会顶住拇指。处理: + 1) 关掉 CMC 中间连杆 + 掌根碰撞体(显示 mesh 仍在;物理不互顶) + 2) palm↔拇指 FilteredPairs + 四指之间自碰仍保留,用来减轻拇指穿其它指。 + """ + from pxr import Usd, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + + predicate = Usd.TraverseInstanceProxies(Usd.PrimAllPrimsPredicate) + palm = None + thumb_links: list = [] + cmc_disabled = 0 + palm_col_off = 0 + for prim in Usd.PrimRange(hand_prim, predicate): + name = prim.GetName() + if prim.HasAPI(UsdPhysics.CollisionAPI) and name in ( + "thumb_metacarpals_base1", + "thumb_metacarpals_base2", + "hand_base_link", + ): + try: + UsdPhysics.CollisionAPI(prim).CreateCollisionEnabledAttr().Set(False) + if name == "hand_base_link": + palm_col_off += 1 + else: + cmc_disabled += 1 + except Exception as exc: + print(f"[stabilize] collision disable failed {prim.GetPath()}: {exc}") + if not prim.HasAPI(UsdPhysics.RigidBodyAPI): + continue + if name in ("hand_base_link", "base_link", "palm"): + palm = prim + elif name.startswith("thumb_"): + thumb_links.append(prim) + + if palm is None or not thumb_links: + print( + f"[stabilize] thumb-palm filter skipped " + f"(palm={palm is not None}, thumbs={len(thumb_links)}, " + f"cmc_off={cmc_disabled}, palm_col_off={palm_col_off})" + ) + return + + api = UsdPhysics.FilteredPairsAPI.Apply(palm) + rel = api.CreateFilteredPairsRel() + existing = {str(p) for p in (rel.GetTargets() or [])} + added = 0 + for link in thumb_links: + path = link.GetPath() + if str(path) in existing: + continue + rel.AddTarget(path) + other = UsdPhysics.FilteredPairsAPI.Apply(link) + other_rel = other.CreateFilteredPairsRel() + if palm.GetPath() not in (other_rel.GetTargets() or []): + other_rel.AddTarget(palm.GetPath()) + added += 1 + print( + f"[stabilize] palm↔thumb filter pairs={added} cmc_off={cmc_disabled} " + f"palm_col_off={palm_col_off} thumbs={[t.GetName() for t in thumb_links]}" + ) + + +def _stabilize_articulation( + articulation: Articulation, + *, + enable_gravity: bool, + disable_collisions: bool = False, + enable_self_collisions: bool = False, +) -> None: + """动力学仿真稳定性:默认保留碰撞;自碰需配合 PD 位置目标才有效。""" + try: + articulation.set_enabled_self_collisions([bool(enable_self_collisions)]) + except Exception as exc: + print(f"[stabilize] set_enabled_self_collisions failed: {exc}") + articulation.set_link_enabled_gravities(enable_gravity) + if disable_collisions: + from pxr import Usd, UsdPhysics + + try: + link_groups = articulation.link_paths + except Exception: + link_groups = [] + stage = stage_utils.get_current_stage() + predicate = Usd.TraverseInstanceProxies(Usd.PrimAllPrimsPredicate) + n_disabled = 0 + for group in link_groups: + for path in group: + prim = stage.GetPrimAtPath(path) + if not prim.IsValid(): + continue + for child in Usd.PrimRange(prim, predicate): + if child.HasAPI(UsdPhysics.CollisionAPI): + try: + UsdPhysics.CollisionAPI(child).CreateCollisionEnabledAttr().Set(False) + n_disabled += 1 + except Exception: + pass + print(f"[stabilize] disabled {n_disabled} collision APIs under articulation") + else: + print( + f"[stabilize] collisions ON, self_collision={'ON' if enable_self_collisions else 'OFF'}" + ) + + +def _patch_joint_max_forces(hand_path: str, max_force: float = DEFAULT_ACTUATED_MAX_EFFORT) -> None: + """URDF 转换默认 maxForce=1,直接改 USD 驱动上限。""" + from pxr import Usd, UsdPhysics + + stage = stage_utils.get_current_stage() + root = stage.GetPrimAtPath(hand_path) + if not root.IsValid(): + return + for prim in Usd.PrimRange(root): + for drive_name in ("angular", "linear"): + if not prim.HasAPI(UsdPhysics.DriveAPI, drive_name): + continue + drive = UsdPhysics.DriveAPI(prim, drive_name) + attr = drive.GetMaxForceAttr() + if attr: + attr.Set(float(max_force)) + stiff = drive.GetStiffnessAttr() + damp = drive.GetDampingAttr() + # 仅保证属性存在;实际增益仍由 Articulation.set_dof_gains 写入 + if stiff and stiff.Get() is None: + stiff.Set(0.0) + if damp and damp.Get() is None: + damp.Set(0.0) + + +def _disable_floating_root_joint(hand_path: str) -> None: + """禁用资产内无效 root_joint(body0 非刚体)。""" + from pxr import Usd, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + for prim in Usd.PrimRange(hand_prim): + if prim.GetName() == "root_joint" and prim.IsA(UsdPhysics.Joint): + prim.SetActive(False) + print(f"[anchor] disabled floating {prim.GetPath()}") + return + + +def _find_root_rigid_body(hand_prim) -> object | None: + """找掌根刚体:优先 hand_base_link / base_link,否则第一个 RigidBody。""" + from pxr import Usd, UsdPhysics + + preferred = None + first = None + for prim in Usd.PrimRange(hand_prim): + if not prim.HasAPI(UsdPhysics.RigidBodyAPI): + continue + if first is None: + first = prim + name = prim.GetName() + if name in ("hand_base_link", "base_link", "palm"): + preferred = prim + break + return preferred or first + + +def _fix_base_to_world(hand_path: str) -> None: + """把掌根钉到当前世界位姿:优先改写 USD 内 root_joint 的 localPos0/Rot0。 + + 交付 USD 的 root_joint 已是 body0=world、body1=palm;安装位姿由场景 Xform + 决定,因此这里只写入世界坐标,不另造 WorldFixedJoint(避免双固定)。 + """ + from pxr import Gf, Usd, UsdGeom, UsdPhysics + + stage = stage_utils.get_current_stage() + hand_prim = stage.GetPrimAtPath(hand_path) + if not hand_prim.IsValid(): + return + + base = _find_root_rigid_body(hand_prim) + if base is None: + print(f"[anchor] no RigidBody under {hand_path}") + return + + xf = UsdGeom.Xformable(base).ComputeLocalToWorldTransform(Usd.TimeCode.Default()) + pos = xf.ExtractTranslation() + quat = xf.ExtractRotationQuat() + pos_f = Gf.Vec3f(float(pos[0]), float(pos[1]), float(pos[2])) + rot_f = Gf.Quatf(float(quat.GetReal()), *[float(v) for v in quat.GetImaginary()]) + + for prim in Usd.PrimRange(hand_prim): + if prim.GetName() != "root_joint" or not prim.IsA(UsdPhysics.Joint): + continue + joint = UsdPhysics.Joint(prim) + b1 = [str(t) for t in (joint.GetBody1Rel().GetTargets() or [])] + b0 = [str(t) for t in (joint.GetBody0Rel().GetTargets() or [])] + if str(base.GetPath()) not in b1 or len(b0) != 0: + prim.SetActive(False) + print(f"[anchor] disabled invalid {prim.GetPath()} body0={b0} body1={b1}") + continue + if not prim.IsActive(): + prim.SetActive(True) + joint.CreateLocalPos0Attr().Set(pos_f) + joint.CreateLocalRot0Attr().Set(rot_f) + joint.CreateLocalPos1Attr().Set(Gf.Vec3f(0.0, 0.0, 0.0)) + joint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, 0.0, 0.0, 0.0)) + print( + f"[anchor] USD root_joint {prim.GetPath()} -> {base.GetPath()} @ " + f"({float(pos[0]):.3f},{float(pos[1]):.3f},{float(pos[2]):.3f})" + ) + return + + # Fallback if asset has no usable root_joint + joint_path = f"{hand_path}/WorldFixedJoint" + if stage.GetPrimAtPath(joint_path).IsValid(): + stage.RemovePrim(joint_path) + joint = UsdPhysics.FixedJoint.Define(stage, joint_path) + joint.CreateBody0Rel().SetTargets([]) + joint.CreateBody1Rel().SetTargets([base.GetPath()]) + joint.CreateLocalPos0Attr().Set(pos_f) + joint.CreateLocalRot0Attr().Set(rot_f) + joint.CreateLocalPos1Attr().Set(Gf.Vec3f(0.0, 0.0, 0.0)) + joint.CreateLocalRot1Attr().Set(Gf.Quatf(1.0, 0.0, 0.0, 0.0)) + joint.CreateExcludeFromArticulationAttr().Set(False) + print( + f"[anchor] WorldFixedJoint {joint_path} -> {base.GetPath()} @ " + f"({float(pos[0]):.3f},{float(pos[1]):.3f},{float(pos[2]):.3f})" + ) + + +def _load_hand_reference(usd_path: Path, mount_path: str, position: list[float]) -> str: + """加载手资产引用,返回 hand_path(此时尚未创建 Articulation)。""" + if not usd_path.is_file(): + raise FileNotFoundError(f"USD 不存在: {usd_path}") + stage_utils.define_prim(mount_path, "Xform") + XformPrim(mount_path, positions=[position], reset_xform_op_properties=True) + hand_path = f"{mount_path}/hand" + stage_utils.add_reference_to_stage(usd_path=str(usd_path), path=hand_path) + prim_utils.set_prim_variants(hand_path, variants=[("Physics", "physx")]) + _patch_joint_max_forces(hand_path) + return hand_path + + +def _print_g20_stability_report(samples: list[list[float]]) -> bool: + """Return True if G20 state is stable enough.""" + import statistics + + open_pose = [float(v) for v in G20_OPEN_CMD] + if len(samples) < 5: + print(f"G20 stability: insufficient samples ({len(samples)})") + return False + + max_step = 0.0 + for i in range(1, len(samples)): + for m in range(20): + max_step = max(max_step, abs(samples[i][m] - samples[i - 1][m])) + + motor_std = [statistics.pstdev(s[m] for s in samples) for m in range(20)] + max_dev = max(max(abs(s[m] - open_pose[m]) for s in samples) for m in range(20)) + unstable = [m for m, std in enumerate(motor_std) if std > 1.0] + + print("=== G20 stability report ===") + print(f"samples={len(samples)} max_step_delta={max_step:.2f} max_dev_open={max_dev:.2f}") + print(f"unstable_motors(std>1): {unstable}") + print(f"first: {[round(v, 1) for v in samples[0]]}") + print(f"last: {[round(v, 1) for v in samples[-1]]}") + ok = max_step <= 2.0 and len(unstable) == 0 and max_dev <= 80.0 + print("RESULT:", "PASS" if ok else "FAIL") + return ok + + +def main() -> None: + stage_utils.create_new_stage() + stage_utils.set_stage_units(meters_per_unit=1.0) + + GroundPlane("/World/GroundPlane", positions=[0.0, 0.0, 0.0]) + light = DistantLight("/World/DistantLight") + light.set_intensities(300.0) + set_camera_view(eye=[0.55, 0.0, 0.55], target=[0.0, 0.0, 0.35], camera_prim_path="/OmniverseKit_Persp") + + # 默认只加载 G20;--o6-only / --both 可改 + if args.both: + load_o6 = load_g20 = True + elif args.o6_only: + load_o6, load_g20 = True, False + else: + # --g20-only 或未指定:仅 G20 + load_o6, load_g20 = False, True + + o6_path = ( + _load_hand_reference(args.o6_usd, "/World/O6Hand", [0.0, -HAND_MOUNT_Y, HAND_MOUNT_Z]) + if load_o6 + else None + ) + g20_path = ( + _load_hand_reference(args.g20_usd, "/World/G20Hand", [0.0, HAND_MOUNT_Y, HAND_MOUNT_Z]) + if load_g20 + else None + ) + + SimulationManager.set_physics_dt(1.0 / 120.0) + + app_utils.play() + simulation_app.update() + + # play 之后再钉世界固定关节(此时世界位姿已正确) + if o6_path: + _disable_floating_root_joint(o6_path) + if g20_path: + _fix_base_to_world(g20_path) + + # 碰撞/自碰已写进交付 USD;此处不再运行时改 mesh + # 仅在显式 --no-collision 时关掉 + want_self_collision_early = False + if args.anti_penetration: + print( + "[stabilize] 碰撞/自碰已烘焙进 USD:" + f"{args.g20_usd if hasattr(args,'g20_usd') else 'g20'};" + "请直接加载该资产。运行时勿再改 collision。" + ) + args.anti_penetration = False + + app_utils.stop() + simulation_app.update() + app_utils.play() + simulation_app.update() + + # 不再调用 _author_self_collisions(交付以 USD 为准) + + app_utils.stop() + simulation_app.update() + app_utils.play() + simulation_app.update() + + # 必须在最终 play 之后创建 Articulation,否则 tensor 句柄会过期 + o6 = Articulation(o6_path) if o6_path else None + g20 = Articulation(g20_path) if g20_path else None + + hand_configs = [] + if load_o6: + hand_configs.append((o6, "O6", args.o6_side)) + if load_g20: + hand_configs.append((g20, "G20", args.g20_side)) + + # 硬写 set_dof_positions 会穿透接触;自碰必须用 PD 目标 + # 默认 PD(交付 USD 自碰生效);仅 --position-drive / --kinematic 关闭 + want_self_collision = (not args.no_collision) and (not args.kinematic) + use_physics_drive_early = (not args.kinematic) and (not args.position_drive) + if args.position_drive: + print( + "[stabilize] --position-drive:硬写关节,USD 自碰无法阻止穿模。" + "防拇指穿掌请去掉该参数(默认 PD)。" + ) + if args.self_collision and args.position_drive: + print("[stabilize] --self-collision 与 --position-drive 冲突,改用 PD") + use_physics_drive_early = True + if args.hand_gravity and not use_physics_drive_early: + print( + "[warn] --hand-gravity 在硬写位置驱动下已忽略。" + "测重力/摩擦: 默认 PD + --hand-gravity(不要加 --position-drive)" + ) + enable_link_gravity = bool(args.hand_gravity) and use_physics_drive_early + + for art, hand, side in hand_configs: + if use_physics_drive_early: + stiff = args.drive_stiffness + damp = args.drive_damping + if hand == "G20": + stiff = args.g20_drive_stiffness + damp = args.g20_drive_damping + if enable_link_gravity: + stiff *= GRAVITY_STIFFNESS_SCALE + damp *= GRAVITY_DAMPING_SCALE + effort = DEFAULT_ACTUATED_MAX_EFFORT + else: + # 位置驱动:零增益,只靠 set_dof_positions + stiff = 0.0 + damp = 0.0 + effort = DEFAULT_ACTUATED_MAX_EFFORT + _configure_drives( + art, + hand, + side, + kinematic=args.kinematic, + stiffness=stiff, + damping=damp, + max_effort=effort, + ) + if hand == "G20" and g20_path: + # 已在 stop/play 前写入;此处再刷一遍 API 状态 + try: + art.set_enabled_self_collisions([want_self_collision]) + except Exception: + pass + elif hand == "O6" and o6_path: + try: + art.set_enabled_self_collisions([want_self_collision]) + except Exception: + pass + _stabilize_articulation( + art, + enable_gravity=enable_link_gravity, + # 尊重 USD 碰撞;仅 --no-collision 时关掉 + disable_collisions=bool(args.no_collision), + enable_self_collisions=want_self_collision and use_physics_drive_early, + ) + + simulation_app.update() + + rclpy.init() + ros_node = Node("linker_hand_isaac_sim") + + # 与上面一致:自碰开启时必须用 PD 目标 + use_physics_drive = use_physics_drive_early + bridge_kwargs = { + "kinematic": args.kinematic, + "cmd_smooth": args.cmd_smooth, + "hold_open": args.hold_open or args.stability_test, + "use_physics_drive": use_physics_drive, + } + o6_bridge = None + g20_bridge = None + if load_o6: + o6_bridge = HandBridge( + ros_node, o6, hand="O6", side=args.o6_side, + cmd_topic=TOPICS["O6"]["cmd"], state_topic=TOPICS["O6"]["state"], + **bridge_kwargs, + ) + o6_bridge._mount_position = [0.0, -HAND_MOUNT_Y, HAND_MOUNT_Z] + if load_g20: + g20_bridge = HandBridge( + ros_node, g20, hand="G20", side=args.g20_side, + cmd_topic=TOPICS["G20"]["cmd"], state_topic=TOPICS["G20"]["state"], + **bridge_kwargs, + ) + g20_bridge._mount_position = [0.0, HAND_MOUNT_Y, HAND_MOUNT_Z] + + if o6_bridge: + o6_bridge.initialize_pose() + if g20_bridge: + g20_bridge.initialize_pose() + + if use_physics_drive: + for _ in range(120): + if o6_bridge: + o6_bridge.apply_targets() + if g20_bridge: + g20_bridge.apply_targets() + SimulationManager.step() + simulation_app.update() + if g20_bridge and args.stability_test: + ros_node.get_logger().info(f"G20 after settle: {g20_bridge._read_sdk_state()[:8]}") + else: + for _ in range(5): + simulation_app.update() + + mode_str = ( + "运动学" + if args.kinematic + else ( + "PD+自碰" + if use_physics_drive and want_self_collision + else ("纯 PD 动力学" if use_physics_drive else "位置驱动(可穿模)") + ) + ) + grav_str = "开" if enable_link_gravity else ("关(硬写忽略)" if args.hand_gravity else "关") + ros_node.get_logger().info( + f"仿真就绪 [{mode_str}, 手部重力={grav_str}]。" + f"UI: run_sim.sh ;测摩擦: run_sim.sh --pd-drive --hand-gravity" + ) + + stability_samples: list[list[float]] = [] + max_steps = args.max_steps + if args.stability_test and max_steps <= 0: + max_steps = 960 + if args.motion_test and max_steps <= 0: + max_steps = 720 + + def _motion_pose(phase: int) -> None: + """phase 偶数=张开,奇数=半握。""" + if phase % 2 == 0: + if o6_bridge: + o6_bridge.set_sdk_command(open_hand_command("O6")) + if g20_bridge: + g20_bridge.set_sdk_command(open_hand_command("G20")) + else: + if o6_bridge: + o6_bridge.set_sdk_command([80.0] * 6) + if g20_bridge: + g20_bridge.set_sdk_command([80.0] * 20) + + try: + step = 0 + while simulation_app.is_running(): + rclpy.spin_once(ros_node, timeout_sec=0.0) + if args.motion_test and step % 90 == 0: + _motion_pose(step // 90) + if o6_bridge: + o6_bridge.apply_targets() + if g20_bridge: + g20_bridge.apply_targets() + if step % 6 == 0: + if o6_bridge: + o6_bridge.publish_state() + if g20_bridge: + g20_bridge.publish_state() + if args.stability_test and g20_bridge and step >= 360: + stability_samples.append(g20_bridge._read_sdk_state()) + SimulationManager.step() + if not use_physics_drive: + if o6_bridge: + o6_bridge._pin_root() + if g20_bridge: + g20_bridge._pin_root() + RenderingManager.render() + simulation_app.update() + # update() 可能再推物理,渲染前最后再钉一次 + if not use_physics_drive: + if o6_bridge: + o6_bridge._pin_root() + if g20_bridge: + g20_bridge._pin_root() + step += 1 + if max_steps > 0 and step >= max_steps: + if args.stability_test: + _print_g20_stability_report(stability_samples) + if args.motion_test: + for br in (o6_bridge, g20_bridge): + if br is None: + continue + print( + f"[motion-test] {br.hand}: explode_count={br.explode_count} " + f"max_root_drift={br.max_root_drift:.4f}m" + ) + ok = all( + br is None or br.explode_count == 0 + for br in (o6_bridge, g20_bridge) + ) + print("[motion-test] RESULT:", "PASS" if ok else "FAIL") + else: + ros_node.get_logger().info(f"已完成 {max_steps} 步,退出。") + break + except KeyboardInterrupt: + pass + finally: + ros_node.destroy_node() + rclpy.shutdown() + app_utils.stop() + simulation_app.close() + + +if __name__ == "__main__": + main() diff --git a/run_g20_plan.sh b/run_g20_plan.sh new file mode 100755 index 0000000..c4fbd3a --- /dev/null +++ b/run_g20_plan.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Isaac G20 实机命令桥 +# 默认订阅 /g20/cb_left_hand_control_cmd(与真机相同 0~255) +# 发布 /sim/isaac/g20/left/joint_state +# PLAN 名义弧度: --plan-nominal +# 旧无前缀话题: --legacy-sdk +# 跟踪自检: --track-test +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ISAAC_DIR="${ISAAC_SIM_DIR:-$REPO_ROOT/_build/linux-x86_64/release}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +export ISAAC_SIM_DIR="$ISAAC_DIR" + +exec "$ISAAC_DIR/python.sh" "$SCRIPT_DIR/isaac_g20_plan_bridge.py" "$@" diff --git a/run_sim.sh b/run_sim.sh new file mode 100755 index 0000000..44a2f39 --- /dev/null +++ b/run_sim.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# 启动 LinkerHand Isaac Sim 仿真(默认仅 G20 + ROS2 桥) +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ISAAC_DIR="${ISAAC_SIM_DIR:-$REPO_ROOT/_build/linux-x86_64/release}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +export ISAAC_SIM_DIR="$ISAAC_DIR" + +exec "$ISAAC_DIR/python.sh" "$SCRIPT_DIR/linker_hand_dual_sim.py" "$@" diff --git a/run_ui.sh b/run_ui.sh new file mode 100755 index 0000000..9f56aec --- /dev/null +++ b/run_ui.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# 启动 O6/G20 关节控制 UI(系统 ROS2 + tkinter,不要用 Isaac python.sh) +set -eo pipefail + +# ROS setup.bash 会读未定义变量,不能在 set -u 下 source +if [[ -f /opt/ros/jazzy/setup.bash ]]; then + # shellcheck disable=SC1091 + source /opt/ros/jazzy/setup.bash +elif [[ -f /opt/ros/humble/setup.bash ]]; then + # shellcheck disable=SC1091 + source /opt/ros/humble/setup.bash +else + echo "未找到 ROS2 setup.bash(jazzy/humble)" >&2 + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +exec python3 "$SCRIPT_DIR/hand_control_ui.py" "$@" diff --git a/test_g20_stability.py b/test_g20_stability.py new file mode 100755 index 0000000..ce4105d --- /dev/null +++ b/test_g20_stability.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +"""Run built-in G20 stability test (headless).""" +import subprocess +import sys +from pathlib import Path + +ISAAC = Path(__file__).resolve().parents[1] / "_build/linux-x86_64/release" +SCRIPT = Path(__file__).resolve().parent / "linker_hand_dual_sim.py" + +cmd = [str(ISAAC / "python.sh"), str(SCRIPT), "--headless", "--stability-test", *sys.argv[1:]] +print("Running:", " ".join(cmd)) +raise SystemExit(subprocess.call(cmd)) diff --git a/urdf/g20/left/linkerhand_g20_left.urdf b/urdf/g20/left/linkerhand_g20_left.urdf new file mode 100644 index 0000000..000442c --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left.urdf @@ -0,0 +1,1285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/urdf/g20/left/linkerhand_g20_left/linkerhand_g20_left.usda b/urdf/g20/left/linkerhand_g20_left/linkerhand_g20_left.usda new file mode 100644 index 0000000..08e8582 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/linkerhand_g20_left.usda @@ -0,0 +1,52 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Xform "linkerhand_g20_left" ( + prepend references = @./payloads/base.usda@ + variants = { + string Physics = "physx" + } + append variantSets = "Physics" +) +{ + variantSet "Physics" = { + "mujoco" ( + prepend payload = @./payloads/Physics/mujoco.usda@ + ) { + + } + "none" { + + } + "physics" ( + prepend payload = @./payloads/Physics/physics.usda@ + ) { + + } + "physx" ( + prepend payload = @./payloads/Physics/physx.usda@ + ) { + + } + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/Physics/hand_body_limits.usda b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/hand_body_limits.usda new file mode 100644 index 0000000..da8d3c8 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/hand_body_limits.usda @@ -0,0 +1,398 @@ +#usda 1.0 +( + defaultPrim = "linkerhand_g20_left" + metersPerUnit = 1 + kilogramsPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_g20_left" +{ + over "Geometry" + { + over "hand_base_link" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + + over "hand_base_link" + { + over "thumb_metacarpals_base1" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + + over "hand_base_link" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals_base2" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + + over "hand_base_link" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals_base2" + { + over "thumb_metacarpals" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + + over "hand_base_link" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals_base2" + { + over "thumb_metacarpals" + { + over "thumb_proximal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + + over "hand_base_link" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals_base2" + { + over "thumb_metacarpals" + { + over "thumb_proximal" + { + over "thumb_distal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + } + + over "hand_base_link" + { + over "index_metacarpals" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + + over "hand_base_link" + { + over "index_metacarpals" + { + over "index_proximal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + + over "hand_base_link" + { + over "index_metacarpals" + { + over "index_proximal" + { + over "index_middle" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + + over "hand_base_link" + { + over "index_metacarpals" + { + over "index_proximal" + { + over "index_middle" + { + over "index_distal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + + over "hand_base_link" + { + over "middle_metacarpals" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + + over "hand_base_link" + { + over "middle_metacarpals" + { + over "middle_proximal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + + over "hand_base_link" + { + over "middle_metacarpals" + { + over "middle_proximal" + { + over "middle_middle" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + + over "hand_base_link" + { + over "middle_metacarpals" + { + over "middle_proximal" + { + over "middle_middle" + { + over "middle_distal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + + over "hand_base_link" + { + over "ring_metacarpals" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + + over "hand_base_link" + { + over "ring_metacarpals" + { + over "ring_proximal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + + over "hand_base_link" + { + over "ring_metacarpals" + { + over "ring_proximal" + { + over "ring_middle" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + + over "hand_base_link" + { + over "ring_metacarpals" + { + over "ring_proximal" + { + over "ring_middle" + { + over "ring_distal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + + over "hand_base_link" + { + over "pinky_metacarpals" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + + over "hand_base_link" + { + over "pinky_metacarpals" + { + over "pinky_proximal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + + over "hand_base_link" + { + over "pinky_metacarpals" + { + over "pinky_proximal" + { + over "pinky_middle" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + + over "hand_base_link" + { + over "pinky_metacarpals" + { + over "pinky_proximal" + { + over "pinky_middle" + { + over "pinky_distal" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 6.0 + float physxRigidBody:angularDamping = 6.0 + } + } + } + } + } + } +} diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/Physics/mujoco.usda b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/mujoco.usda new file mode 100644 index 0000000..5489a64 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/mujoco.usda @@ -0,0 +1,582 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_g20_left" +{ + over "Physics" + { + def MjcActuator "thumb_cmc_roll_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_cmc_yaw_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_cmc_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_mcp_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_ip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_pip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_pip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_pip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_pip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + over "root_joint" + { + } + + over "thumb_cmc_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_cmc_yaw" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_cmc_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_mcp" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_ip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + } + + over "Geometry" + { + over "hand_base_link" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals_base2" + { + over "thumb_metacarpals" + { + over "thumb_proximal" + { + over "thumb_distal" + { + over "thumb_distal" + { + } + + over "thumb_distal_1" + { + } + } + + over "thumb_proximal" + { + } + + over "thumb_proximal_1" + { + } + } + + over "thumb_metacarpals" + { + } + + over "thumb_metacarpals_1" + { + } + } + + over "thumb_metacarpals_base2" + { + } + + over "thumb_metacarpals_base2_1" + { + } + } + + over "thumb_metacarpals_base1" + { + } + + over "thumb_metacarpals_base1_1" + { + } + } + + over "index_metacarpals" + { + over "index_proximal" + { + over "index_middle" + { + over "index_distal" + { + over "index_distal" + { + } + + over "index_distal_1" + { + } + } + + over "index_middle" + { + } + + over "index_middle_1" + { + } + } + + over "index_proximal" + { + } + + over "index_proximal_1" + { + } + } + + over "index_metacarpals" + { + } + + over "index_metacarpals_1" + { + } + } + + over "middle_metacarpals" + { + over "middle_proximal" + { + over "middle_middle" + { + over "middle_distal" + { + over "middle_distal" + { + } + + over "middle_distal_1" + { + } + } + + over "middle_middle" + { + } + + over "middle_middle_1" + { + } + } + + over "middle_proximal" + { + } + + over "middle_proximal_1" + { + } + } + + over "middle_metacarpals" + { + } + + over "middle_metacarpals_1" + { + } + } + + over "ring_metacarpals" + { + over "ring_proximal" + { + over "ring_middle" + { + over "ring_distal" + { + over "ring_distal" + { + } + + over "ring_distal_1" + { + } + } + + over "ring_middle" + { + } + + over "ring_middle_1" + { + } + } + + over "ring_proximal" + { + } + + over "ring_proximal_1" + { + } + } + + over "ring_metacarpals" + { + } + + over "ring_metacarpals_1" + { + } + } + + over "pinky_metacarpals" + { + over "pinky_proximal" + { + over "pinky_middle" + { + over "pinky_distal" + { + over "pinky_distal" + { + } + + over "pinky_distal_1" + { + } + } + + over "pinky_middle" + { + } + + over "pinky_middle_1" + { + } + } + + over "pinky_proximal" + { + } + + over "pinky_proximal_1" + { + } + } + + over "pinky_metacarpals" + { + } + + over "pinky_metacarpals_1" + { + } + } + + over "hand_base_link" + { + } + + over "hand_base_link_1" + { + } + } + } + + over "Materials" + { + } + + over "VisualMaterials" + { + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physics.usda b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physics.usda new file mode 100644 index 0000000..820c87d --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physics.usda @@ -0,0 +1,720 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_g20_left" +{ + over "Geometry" ( + prepend apiSchemas = ["PhysicsArticulationRootAPI", "NewtonArticulationRootAPI"] + ) + { + bool newton:selfCollisionEnabled = 1 + + over "hand_base_link" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.000986417, 0.000268049, 0.077379845) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.1103735 + quatf physics:principalAxes = (0.70273006, 0.038762398, 0.7092034, -0.04121172) + + over "thumb_metacarpals_base1" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.011515513, 0.0039806883, 0.00027288825) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.69315267, 0.09873541, 0.69662505, -0.15653834) + + over "thumb_metacarpals_base2" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0028671462, -0.0061572655, 0.0047260527) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (-0.4856348, 0.6328352, 0.57746726, 0.17381014) + + over "thumb_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0067065787, 0.000086075896, 0.033141293) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.028716035 + quatf physics:principalAxes = (0.5003233, 0.49646425, 0.50234294, 0.50085074) + + over "thumb_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.002687344, 0.00056824455, 0.011850173) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.4466405, 0.44347262, 0.5443941, 0.55450827) + + over "thumb_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0007100218, -0.0026757591, 0.012476266) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.7076172, 0.49610376, 0.40506423, 0.29846585) + } + } + } + } + } + + over "index_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.007942997, -2.9367396e-7, 0.0022010603) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.15955442, 0.6888882, 0.68885684, -0.15953577) + + over "index_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0011418548, 0.000034731576, 0.02289284) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.5117973, 0.51168644, 0.48817277, 0.48777848) + + over "index_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00020699194, 0.0000026061707, 0.016706534) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.7445136, -0.00005444173, 0.6676073, 0.000047438436) + + over "index_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.008162465, 0.000022705892, 0.008118065) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.90243715, -0.0029940915, 0.43080872, -0.0014403827) + } + } + } + } + + over "middle_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.007942996, -2.9300665e-7, 0.0022010633) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.1595545, 0.6888883, 0.6888567, -0.15953599) + + over "middle_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0011418548, 0.000034731576, 0.02289284) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.5117973, 0.51168644, 0.48817277, 0.48777848) + + over "middle_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0002069919, 0.0000026062498, 0.016706534) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.7445136, -0.000054456927, 0.6676073, 0.00004744315) + + over "middle_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.008162466, 0.000022705855, 0.008118066) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.90243715, -0.0029941155, 0.4308087, -0.0014403895) + } + } + } + } + + over "ring_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.007942996, -2.945131e-7, 0.0022010615) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.15955459, 0.6888881, 0.68885696, -0.1595357) + + over "ring_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0011418548, 0.00003473158, 0.02289284) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.5117973, 0.51168644, 0.48817277, 0.48777848) + + over "ring_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00020699321, 0.0000026074692, 0.016706532) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.74451363, -0.000054586842, 0.6676073, 0.000047385933) + + over "ring_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.008162466, 0.000022705732, 0.008118066) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.90243715, -0.0029941578, 0.43080872, -0.0014404262) + } + } + } + } + + over "pinky_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.007942996, -2.9300685e-7, 0.0022010633) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.1595545, 0.6888883, 0.6888567, -0.15953599) + + over "pinky_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0011418548, 0.00003473158, 0.02289284) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.5117973, 0.51168644, 0.48817277, 0.48777848) + + over "pinky_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00020699325, 0.00000260749, 0.016706532) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.74451363, -0.0000545887, 0.6676073, 0.000047383306) + + over "pinky_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.008162466, 0.000022705419, 0.008118066) + float3 physics:diagonalInertia = (0.0005, 0.0005, 0.0005) + float physics:mass = 0.02 + quatf physics:principalAxes = (0.90243715, -0.002994122, 0.43080872, -0.001440418) + } + } + } + } + } + } + + over "Physics" + { + def PhysicsRevoluteJoint "thumb_cmc_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.01916, -0.01, 0.0436) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0, 0, -1, 0) + quatf physics:localRot1 = (0, 0, -1, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 84.22480 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Z" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.019845, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.9264883, 0.3763236, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 89.95438 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0088218, -0.024245, 0.0005) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.49418968, 0.41577393, -0.29111633, 0.7058044) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 48.128456 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_mcp" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.012701825, -6.938894e-18, 0.06272562) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 72.19268 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_ip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + float newton:mimicCoef1 = 1.02 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.004836522, 1.3877788e-17, 0.034222648) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 73.91155 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0038, -0.03525, 0.1481) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -13.178029 + float physics:upperLimit = 13.178029 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0021302, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041946, 0, 0.044819) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 99.69466 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0028245, 0, 0.031696) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 88.80846 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0038, -0.01175, 0.1526) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -13.178029 + float physics:upperLimit = 13.178029 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0021302, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.004194577, 0, 0.044819433) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 99.69466 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0028245, 0, 0.031696) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 88.80846 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0038, 0.01175, 0.1481) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -13.178029 + float physics:upperLimit = 13.178029 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0021302, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.004194577, 0, 0.044819433) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 99.69466 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0028245, 0, 0.031696) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 88.80846 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0038, 0.03525, 0.1436) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -13.178029 + float physics:upperLimit = 13.178029 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0021302, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041946, 0, 0.044819) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 99.69466 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 10 + uniform token drive:angular:physics:type = "force" + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0028245, 0, 0.031696) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 88.80846 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsFixedJoint "root_joint" + { + # Deliverable fixed base: empty body0 = world, body1 = palm rigid body. + # Mount pose comes from the referencing Xform in the scene (not localPos0). + custom rel physics:body0 + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + bool physics:jointEnabled = 1 + } + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physx.usda b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physx.usda new file mode 100644 index 0000000..7428bd8 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/Physics/physx.usda @@ -0,0 +1,230 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@, + @./hand_body_limits.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_g20_left" +{ + + # Deliverable PhysX limits: prevent contact impulse blow-ups when fingertips collide + over "Geometry" ( + prepend apiSchemas = ["PhysxArticulationAPI"] + ) + { + bool physxArticulation:enabledSelfCollisions = 1 + bool newton:selfCollisionEnabled = 1 + int physxArticulation:solverPositionIterationCount = 32 + int physxArticulation:solverVelocityIterationCount = 4 + float physxArticulation:sleepThreshold = 0.005 + + over "hand_base_link" ( + prepend apiSchemas = ["PhysxRigidBodyAPI"] + ) + { + # Retarget/PD 稳定:限速 + 阻尼,避免握拳末端冲飞 + float physxRigidBody:maxLinearVelocity = 3.0 + float physxRigidBody:maxAngularVelocity = 360.0 + float physxRigidBody:linearDamping = 5.0 + float physxRigidBody:angularDamping = 5.0 + bool physxRigidBody:disableGravity = 0 + } + } + + over "Physics" + { + over "thumb_cmc_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + + } + + over "thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + + } + + over "thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + + } + + over "thumb_mcp" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + + } + + over "thumb_ip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + + } + + over "index_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "index_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "index_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "index_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "middle_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "middle_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "middle_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "middle_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "ring_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "ring_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "ring_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "ring_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "pinky_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "pinky_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + + over "pinky_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 171.887 + float physxJoint:armature = 0.05 + } + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/base.usda b/urdf/g20/left/linkerhand_g20_left/payloads/base.usda new file mode 100644 index 0000000..f7f66db --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/base.usda @@ -0,0 +1,730 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./robot.usda@ + ] + upAxis = "Z" +) + +def Xform "linkerhand_g20_left" ( + prepend apiSchemas = ["GeomModelAPI"] + assetInfo = { + string name = "linkerhand_g20_left" + } + kind = "component" +) +{ + float3[] extentsHint = [(-0.031971373, -0.153883, -0.007755601), (0.095290326, 0.052480385, 0.25205174), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (-0.031971373, -0.153883, -0.007755601), (0.095290326, 0.052480385, 0.25205174)] + + def Scope "Materials" + { + } + + def Scope "Geometry" + { + def Xform "hand_base_link" + { + def Xform "hand_base_link" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_metacarpals_base1" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.01916, -0.01, 0.0436) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals_base1" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_metacarpals_base2" + { + quatf xformOp:orient = (0.9264883, 0.3763236, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.019845, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals_base2" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_metacarpals" + { + quatf xformOp:orient = (0.49418968, 0.41577393, -0.29111633, 0.7058044) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0088218, -0.024245, 0.0005) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0127018248047608, 0, 0.0627256157349894) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00483652209209624, 0, 0.0342226492098615) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_distal_1" ( + displayName = "thumb_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.70, 0.70, 0.70) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_proximal_1" ( + displayName = "thumb_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.55, 0.55, 0.55) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_1" ( + displayName = "thumb_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.55, 0.55, 0.55) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base2_1" ( + displayName = "thumb_metacarpals_base2" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.65, 0.65, 0.65) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base1_1" ( + displayName = "thumb_metacarpals_base1" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.65, 0.65, 0.65) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0038, -0.03525, 0.1481) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0021302, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0041946, 0, 0.044819) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0028245, 0, 0.031696) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_distal_1" ( + displayName = "index_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_middle_1" ( + displayName = "index_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_proximal_1" ( + displayName = "index_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_metacarpals_1" ( + displayName = "index_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00379999999265848, -0.0117500000029305, 0.1526) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0021302, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419457745591796, 0, 0.0448194332262389) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0028245, 0, 0.031696) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_distal_1" ( + displayName = "middle_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_middle_1" ( + displayName = "middle_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_proximal_1" ( + displayName = "middle_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_metacarpals_1" ( + displayName = "middle_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00379999999632174, 0.0117499999970695, 0.1481) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0021302, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419457745591796, 0, 0.0448194332262389) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0028245, 0, 0.031696) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_distal_1" ( + displayName = "ring_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_middle_1" ( + displayName = "ring_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_proximal_1" ( + displayName = "ring_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_metacarpals_1" ( + displayName = "ring_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00379999999998499, 0.0352499999970695, 0.1436) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0021302, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0041946, 0, 0.044819) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0028245, 0, 0.031696) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_distal_1" ( + displayName = "pinky_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_middle_1" ( + displayName = "pinky_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_proximal_1" ( + displayName = "pinky_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.85, 0.85, 0.85) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_metacarpals_1" ( + displayName = "pinky_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.75, 0.75, 0.75) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "hand_base_link_1" ( + displayName = "hand_base_link" + instanceable = true + prepend references = @./instances.usda@ + ) + { + # Same visual mesh as collision source; scale 1 = match rendered palm. + # purpose=guide on the mesh keeps this collider invisible in viewport. + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (0.90, 0.90, 0.90) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + } + + def Scope "Physics" + { + } + + def Scope "VisualMaterials" + { + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/geometries.usd b/urdf/g20/left/linkerhand_g20_left/payloads/geometries.usd new file mode 100644 index 0000000..7999ad6 Binary files /dev/null and b/urdf/g20/left/linkerhand_g20_left/payloads/geometries.usd differ diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/instances.usda b/urdf/g20/left/linkerhand_g20_left/payloads/instances.usda new file mode 100644 index 0000000..2f2ef05 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/instances.usda @@ -0,0 +1,798 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Instances" +{ + + def Xform "hand_base_link" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_1" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "hand_base_link_1" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # Self-collision ON: palm visual-mesh collider (purpose=guide). + # Mid/proximal finger hulls stay OFF to avoid PD fist-end explode. + bool physics:collisionEnabled = 1 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "thumb_metacarpals_base1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base1" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_2" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_base1_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base1" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: CMC rest-pose convexHull overlaps palm. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals_base2" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_3" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_base2_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: CMC rest-pose convexHull overlaps palm. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_4" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # OFF: open-pose convexHull embeds into palm → Instant NaN. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "thumb_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_5" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # OFF: open-pose convexHull embeds into palm → Instant NaN. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "thumb_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_6" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # ON: tip vs palm only (shaft OFF for open-pose stability). + bool physics:collisionEnabled = 1 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "index_metacarpals" ( + prepend references = @./geometries.usd@ + ) + { + over "index_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_7" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_metacarpals_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_metacarpals" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_metacarpals_2" ( + prepend references = @./geometries.usd@ + ) + { + over "index_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_11" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_metacarpals_3" ( + prepend references = @./geometries.usd@ + ) + { + over "index_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_15" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_metacarpals_4" ( + prepend references = @./geometries.usd@ + ) + { + over "index_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_19" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_8" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "index_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_9" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_middle_2" ( + prepend references = @./geometries.usd@ + ) + { + over "index_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_21" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_10" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # ON: fingertip contact under self-collision. + bool physics:collisionEnabled = 1 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "index_distal_2" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_18" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_12" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_13" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_14" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # ON: fingertip contact under self-collision. + bool physics:collisionEnabled = 1 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + + def Xform "ring_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_16" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_17" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_20" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + # OFF: fat/adjacent hulls explode under PD close-fist. + bool physics:collisionEnabled = 0 + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "material_22" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI", "PhysxCollisionAPI"] + ) + { + # ON: fingertip contact under self-collision. + bool physics:collisionEnabled = 1 + token physics:approximation = "convexHull" + token purpose = "guide" + float physxCollision:contactOffset = 0.001 + float physxCollision:restOffset = -0.0005 + } + } + +} diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/materials.usda b/urdf/g20/left/linkerhand_g20_left/payloads/materials.usda new file mode 100644 index 0000000..9d5008d --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/materials.usda @@ -0,0 +1,57 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/isaacsim/linkerhand/urdf/g20/left/linkerhand_g20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Materials" +{ + def Material "material_1" + { + color3f inputs:diffuseColor = (1, 1, 1) + float inputs:metallic = 0 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token inputs:wrapMode = "repeat" + token outputs:displacement ( + displayGroup = "Outputs" + ) + prepend token outputs:displacement.connect = + token outputs:surface ( + displayGroup = "Outputs" + ) + prepend token outputs:surface.connect = + token outputs:volume ( + displayGroup = "Outputs" + ) + + def Shader "PreviewSurface" ( + apiSchemas = ["NodeDefAPI"] + ) + { + token info:id = "UsdPreviewSurface" + prepend color3f inputs:diffuseColor.connect = + prepend float inputs:metallic.connect = + prepend float inputs:opacity.connect = + prepend float inputs:roughness.connect = + token outputs:displacement + token outputs:surface + } + } +} + diff --git a/urdf/g20/left/linkerhand_g20_left/payloads/robot.usda b/urdf/g20/left/linkerhand_g20_left/payloads/robot.usda new file mode 100644 index 0000000..727cbc7 --- /dev/null +++ b/urdf/g20/left/linkerhand_g20_left/payloads/robot.usda @@ -0,0 +1,327 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_g20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp5xni4jzi/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/usdex_linkerhand_g20_left/linkerhand_g20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_g20_left_9306w6un/temp_linkerhand_g20_left/linkerhand_g20_left.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_g20_left" ( + prepend apiSchemas = ["IsaacRobotAPI"] +) +{ + prepend rel isaac:physics:robotJoints = [ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ] + prepend rel isaac:physics:robotLinks = [ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ] + token isaac:robotType = "End Effector" + + over "Geometry" + { + over "hand_base_link" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_metacarpals_base1" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_metacarpals_base2" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + } + + over "index_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "middle_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "ring_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "pinky_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + } + } + + over "Physics" + { + over "root_joint" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_yaw" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_mcp" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_ip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + } +} + diff --git a/urdf/g20/left/meshes/hand_base_link.STL b/urdf/g20/left/meshes/hand_base_link.STL new file mode 100644 index 0000000..706606c Binary files /dev/null and b/urdf/g20/left/meshes/hand_base_link.STL differ diff --git a/urdf/g20/left/meshes/index_distal.STL b/urdf/g20/left/meshes/index_distal.STL new file mode 100644 index 0000000..281a53c Binary files /dev/null and b/urdf/g20/left/meshes/index_distal.STL differ diff --git a/urdf/g20/left/meshes/index_metacarpals.STL b/urdf/g20/left/meshes/index_metacarpals.STL new file mode 100644 index 0000000..608b860 Binary files /dev/null and b/urdf/g20/left/meshes/index_metacarpals.STL differ diff --git a/urdf/g20/left/meshes/index_middle.STL b/urdf/g20/left/meshes/index_middle.STL new file mode 100644 index 0000000..9f00fc4 Binary files /dev/null and b/urdf/g20/left/meshes/index_middle.STL differ diff --git a/urdf/g20/left/meshes/index_proximal.STL b/urdf/g20/left/meshes/index_proximal.STL new file mode 100644 index 0000000..4a4473d Binary files /dev/null and b/urdf/g20/left/meshes/index_proximal.STL differ diff --git a/urdf/g20/left/meshes/middle_distal.STL b/urdf/g20/left/meshes/middle_distal.STL new file mode 100644 index 0000000..37d5121 Binary files /dev/null and b/urdf/g20/left/meshes/middle_distal.STL differ diff --git a/urdf/g20/left/meshes/middle_metacarpals.STL b/urdf/g20/left/meshes/middle_metacarpals.STL new file mode 100644 index 0000000..96674b1 Binary files /dev/null and b/urdf/g20/left/meshes/middle_metacarpals.STL differ diff --git a/urdf/g20/left/meshes/middle_middle.STL b/urdf/g20/left/meshes/middle_middle.STL new file mode 100644 index 0000000..3b17190 Binary files /dev/null and b/urdf/g20/left/meshes/middle_middle.STL differ diff --git a/urdf/g20/left/meshes/middle_proximal.STL b/urdf/g20/left/meshes/middle_proximal.STL new file mode 100644 index 0000000..80b553d Binary files /dev/null and b/urdf/g20/left/meshes/middle_proximal.STL differ diff --git a/urdf/g20/left/meshes/pinky_distal.STL b/urdf/g20/left/meshes/pinky_distal.STL new file mode 100644 index 0000000..8e2e782 Binary files /dev/null and b/urdf/g20/left/meshes/pinky_distal.STL differ diff --git a/urdf/g20/left/meshes/pinky_metacarpals.STL b/urdf/g20/left/meshes/pinky_metacarpals.STL new file mode 100644 index 0000000..05a4d03 Binary files /dev/null and b/urdf/g20/left/meshes/pinky_metacarpals.STL differ diff --git a/urdf/g20/left/meshes/pinky_middle.STL b/urdf/g20/left/meshes/pinky_middle.STL new file mode 100644 index 0000000..afab601 Binary files /dev/null and b/urdf/g20/left/meshes/pinky_middle.STL differ diff --git a/urdf/g20/left/meshes/pinky_proximal.STL b/urdf/g20/left/meshes/pinky_proximal.STL new file mode 100644 index 0000000..446789a Binary files /dev/null and b/urdf/g20/left/meshes/pinky_proximal.STL differ diff --git a/urdf/g20/left/meshes/ring_distal.STL b/urdf/g20/left/meshes/ring_distal.STL new file mode 100644 index 0000000..6915e85 Binary files /dev/null and b/urdf/g20/left/meshes/ring_distal.STL differ diff --git a/urdf/g20/left/meshes/ring_metacarpals.STL b/urdf/g20/left/meshes/ring_metacarpals.STL new file mode 100644 index 0000000..f502969 Binary files /dev/null and b/urdf/g20/left/meshes/ring_metacarpals.STL differ diff --git a/urdf/g20/left/meshes/ring_middle.STL b/urdf/g20/left/meshes/ring_middle.STL new file mode 100644 index 0000000..88b6ef5 Binary files /dev/null and b/urdf/g20/left/meshes/ring_middle.STL differ diff --git a/urdf/g20/left/meshes/ring_proximal.STL b/urdf/g20/left/meshes/ring_proximal.STL new file mode 100644 index 0000000..5a06a97 Binary files /dev/null and b/urdf/g20/left/meshes/ring_proximal.STL differ diff --git a/urdf/g20/left/meshes/thumb_distal.STL b/urdf/g20/left/meshes/thumb_distal.STL new file mode 100644 index 0000000..dc10991 Binary files /dev/null and b/urdf/g20/left/meshes/thumb_distal.STL differ diff --git a/urdf/g20/left/meshes/thumb_metacarpals.STL b/urdf/g20/left/meshes/thumb_metacarpals.STL new file mode 100644 index 0000000..156e9b3 Binary files /dev/null and b/urdf/g20/left/meshes/thumb_metacarpals.STL differ diff --git a/urdf/g20/left/meshes/thumb_metacarpals_base1.STL b/urdf/g20/left/meshes/thumb_metacarpals_base1.STL new file mode 100644 index 0000000..16e1059 Binary files /dev/null and b/urdf/g20/left/meshes/thumb_metacarpals_base1.STL differ diff --git a/urdf/g20/left/meshes/thumb_metacarpals_base2.STL b/urdf/g20/left/meshes/thumb_metacarpals_base2.STL new file mode 100644 index 0000000..cf5fced Binary files /dev/null and b/urdf/g20/left/meshes/thumb_metacarpals_base2.STL differ diff --git a/urdf/g20/left/meshes/thumb_proximal.STL b/urdf/g20/left/meshes/thumb_proximal.STL new file mode 100644 index 0000000..b657d19 Binary files /dev/null and b/urdf/g20/left/meshes/thumb_proximal.STL differ diff --git a/urdf/l20/left/linkerhand_l20_left.urdf b/urdf/l20/left/linkerhand_l20_left.urdf new file mode 100644 index 0000000..cbc83ab --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left.urdf @@ -0,0 +1,1204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/l20/left/linkerhand_l20_left/linkerhand_l20_left.usda b/urdf/l20/left/linkerhand_l20_left/linkerhand_l20_left.usda new file mode 100644 index 0000000..ae56573 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/linkerhand_l20_left.usda @@ -0,0 +1,52 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Xform "linkerhand_l20_left" ( + prepend references = @./payloads/base.usda@ + variants = { + string Physics = "physx" + } + append variantSets = "Physics" +) +{ + variantSet "Physics" = { + "mujoco" ( + prepend payload = @./payloads/Physics/mujoco.usda@ + ) { + + } + "none" { + + } + "physics" ( + prepend payload = @./payloads/Physics/physics.usda@ + ) { + + } + "physx" ( + prepend payload = @./payloads/Physics/physx.usda@ + ) { + + } + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/Physics/mujoco.usda b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/mujoco.usda new file mode 100644 index 0000000..5043b74 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/mujoco.usda @@ -0,0 +1,582 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_l20_left" +{ + over "Physics" + { + def MjcActuator "pinky_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_pip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "pinky_dip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_pip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "ring_dip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_pip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "middle_dip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_mcp_roll_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_pip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "index_dip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_cmc_yaw_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_cmc_roll_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_cmc_pitch_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_mcp_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "thumb_ip_actuator" + { + uniform double mjc:forceRange:max = 1 + uniform double mjc:forceRange:min = -1 + custom rel mjc:target + prepend rel mjc:target = + } + + over "root_joint" + { + } + + over "pinky_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "pinky_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "ring_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "middle_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_mcp_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_pip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "index_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_cmc_yaw" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_cmc_roll" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_cmc_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_mcp" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "thumb_ip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + } + + over "Geometry" + { + over "hand_base_link" + { + over "pinky_metacarpals" + { + over "pinky_proximal" + { + over "pinky_middle" + { + over "pinky_distal" + { + over "pinky_distal" + { + } + + over "pinky_distal_1" + { + } + } + + over "pinky_middle" + { + } + + over "pinky_middle_1" + { + } + } + + over "pinky_proximal" + { + } + + over "pinky_proximal_1" + { + } + } + + over "pinky_metacarpals" + { + } + + over "pinky_metacarpals_1" + { + } + } + + over "ring_metacarpals" + { + over "ring_proximal" + { + over "ring_middle" + { + over "ring_distal" + { + over "ring_distal" + { + } + + over "ring_distal_1" + { + } + } + + over "ring_middle" + { + } + + over "ring_middle_1" + { + } + } + + over "ring_proximal" + { + } + + over "ring_proximal_1" + { + } + } + + over "ring_metacarpals" + { + } + + over "ring_metacarpals_1" + { + } + } + + over "middle_metacarpals" + { + over "middle_proximal" + { + over "middle_middle" + { + over "middle_distal" + { + over "middle_distal" + { + } + + over "middle_distal_1" + { + } + } + + over "middle_middle" + { + } + + over "middle_middle_1" + { + } + } + + over "middle_proximal" + { + } + + over "middle_proximal_1" + { + } + } + + over "middle_metacarpals" + { + } + + over "middle_metacarpals_1" + { + } + } + + over "index_metacarpals" + { + over "index_proximal" + { + over "index_middle" + { + over "index_distal" + { + over "index_distal" + { + } + + over "index_distal_1" + { + } + } + + over "index_middle" + { + } + + over "index_middle_1" + { + } + } + + over "index_proximal" + { + } + + over "index_proximal_1" + { + } + } + + over "index_metacarpals" + { + } + + over "index_metacarpals_1" + { + } + } + + over "thumb_metacarpals_base2" + { + over "thumb_metacarpals_base1" + { + over "thumb_metacarpals" + { + over "thumb_proximal" + { + over "thumb_distal" + { + over "thumb_distal" + { + } + + over "thumb_distal_1" + { + } + } + + over "thumb_proximal" + { + } + + over "thumb_proximal_1" + { + } + } + + over "thumb_metacarpals" + { + } + + over "thumb_metacarpals_1" + { + } + } + + over "thumb_metacarpals_base1" + { + } + + over "thumb_metacarpals_base1_1" + { + } + } + + over "thumb_metacarpals_base2" + { + } + + over "thumb_metacarpals_base2_1" + { + } + } + + over "hand_base_link" + { + } + + over "hand_base_link_1" + { + } + } + } + + over "Materials" + { + } + + over "VisualMaterials" + { + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physics.usda b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physics.usda new file mode 100644 index 0000000..9f9c5a5 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physics.usda @@ -0,0 +1,694 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_l20_left" +{ + over "Geometry" + { + over "hand_base_link" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsArticulationRootAPI", "NewtonArticulationRootAPI", "PhysicsMassAPI"] + ) + { + bool newton:selfCollisionEnabled = 0 + point3f physics:centerOfMass = (-0.0116727725, 0.0023917088, 0.08717629) + float3 physics:diagonalInertia = (0.00009926712, 0.000186614, 0.00027272134) + float physics:mass = 0.10108445 + quatf physics:principalAxes = (0.68135417, -0.0042015105, 0.73193634, -0.0028345578) + + over "pinky_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.01127336, 5.5879735e-7, 0.0022016335) + float3 physics:diagonalInertia = (2.688093e-8, 3.2323626e-8, 4.510111e-8) + float physics:mass = 0.000876741 + quatf physics:principalAxes = (-0.16874419, 0.6866895, 0.68666375, 0.16874777) + + over "pinky_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0025991977, 0.000018026341, 0.022354048) + float3 physics:diagonalInertia = (1.075331e-7, 6.213918e-7, 6.5115984e-7) + float physics:mass = 0.0037241937 + quatf physics:principalAxes = (0.48825243, 0.4883892, 0.511191, 0.511634) + + over "pinky_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00021099352, 0.0000028486395, 0.016837623) + float3 physics:diagonalInertia = (9.68419e-8, 1.8334333e-7, 2.3855722e-7) + float physics:mass = 0.0024073792 + quatf physics:principalAxes = (0.6712686, -0.0000017148097, 0.7412142, 0.0000113519045) + + over "pinky_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00808923, 0.000019308107, 0.007983399) + float3 physics:diagonalInertia = (8.634609e-8, 1.7910685e-7, 2.0911786e-7) + float physics:mass = 0.0034042916 + quatf physics:principalAxes = (0.43734092, -0.00058309664, 0.8992954, 0.0005812942) + } + } + } + } + + over "ring_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.01127336, 5.5879735e-7, 0.0022016335) + float3 physics:diagonalInertia = (2.688093e-8, 3.2323626e-8, 4.510111e-8) + float physics:mass = 0.000876741 + quatf physics:principalAxes = (-0.16874419, 0.6866895, 0.68666375, 0.16874777) + + over "ring_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0025991977, 0.000018026341, 0.022354048) + float3 physics:diagonalInertia = (1.075331e-7, 6.213918e-7, 6.5115984e-7) + float physics:mass = 0.0037241937 + quatf physics:principalAxes = (0.48825243, 0.4883892, 0.511191, 0.511634) + + over "ring_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0002109929, 0.0000028491947, 0.016837623) + float3 physics:diagonalInertia = (9.6841916e-8, 1.8334333e-7, 2.3855722e-7) + float physics:mass = 0.0024073794 + quatf physics:principalAxes = (0.6712686, -0.0000016942307, 0.7412142, 0.000011425998) + + over "ring_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00808923, 0.000019308129, 0.007983399) + float3 physics:diagonalInertia = (8.634609e-8, 1.7910685e-7, 2.0911786e-7) + float physics:mass = 0.0034042916 + quatf physics:principalAxes = (0.43734092, -0.0005831002, 0.8992954, 0.0005812897) + } + } + } + } + + over "middle_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.01127336, 5.5879735e-7, 0.0022016335) + float3 physics:diagonalInertia = (2.688093e-8, 3.2323626e-8, 4.510111e-8) + float physics:mass = 0.000876741 + quatf physics:principalAxes = (-0.16874419, 0.6866895, 0.68666375, 0.16874777) + + over "middle_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0025991977, 0.000018026341, 0.022354048) + float3 physics:diagonalInertia = (1.075331e-7, 6.213918e-7, 6.5115984e-7) + float physics:mass = 0.0037241937 + quatf physics:principalAxes = (0.48825243, 0.4883892, 0.511191, 0.511634) + + over "middle_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00021099295, 0.000002849104, 0.016837623) + float3 physics:diagonalInertia = (9.6841916e-8, 1.8334333e-7, 2.3855722e-7) + float physics:mass = 0.0024073794 + quatf physics:principalAxes = (0.6712686, -0.0000017088329, 0.7412142, 0.000011426379) + + over "middle_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00808923, 0.000019306884, 0.007983399) + float3 physics:diagonalInertia = (8.634607e-8, 1.7910686e-7, 2.0911783e-7) + float physics:mass = 0.0034042913 + quatf physics:principalAxes = (0.43734092, -0.00058307627, 0.89929545, 0.00058126054) + } + } + } + } + + over "index_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.01127336, 5.5879735e-7, 0.0022016335) + float3 physics:diagonalInertia = (2.688093e-8, 3.2323626e-8, 4.510111e-8) + float physics:mass = 0.000876741 + quatf physics:principalAxes = (-0.16874419, 0.6866895, 0.68666375, 0.16874777) + + over "index_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0025991977, 0.000018026341, 0.022354048) + float3 physics:diagonalInertia = (1.075331e-7, 6.213918e-7, 6.5115984e-7) + float physics:mass = 0.0037241937 + quatf physics:principalAxes = (0.48825243, 0.4883892, 0.511191, 0.511634) + + over "index_middle" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0002109937, 0.000002848504, 0.016837623) + float3 physics:diagonalInertia = (9.68419e-8, 1.8334332e-7, 2.3855722e-7) + float physics:mass = 0.002407379 + quatf physics:principalAxes = (0.6712686, -0.0000017342365, 0.7412142, 0.000011354987) + + over "index_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.00808923, 0.000019308074, 0.007983399) + float3 physics:diagonalInertia = (8.634609e-8, 1.7910685e-7, 2.0911786e-7) + float physics:mass = 0.0034042916 + quatf physics:principalAxes = (0.43734092, -0.00058310083, 0.8992954, 0.0005812904) + } + } + } + } + + over "thumb_metacarpals_base2" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.02371242, -0.0032577133, -0.0017911186) + float3 physics:diagonalInertia = (1.1234051e-8, 6.543079e-8, 6.770053e-8) + float physics:mass = 0.0009972232 + quatf physics:principalAxes = (-0.35413897, 0.5960251, 0.36731312, 0.6200167) + + over "thumb_metacarpals_base1" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0011972568, -0.006213203, 0.009803273) + float3 physics:diagonalInertia = (3.0495187e-7, 5.8936433e-7, 7.4814983e-7) + float physics:mass = 0.0045973556 + quatf physics:principalAxes = (0.74903965, 0.1874994, 0.62139153, -0.13287634) + + over "thumb_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.003908665, -0.0010197475, 0.025965149) + float3 physics:diagonalInertia = (0.0000023184932, 0.000008088414, 0.000009564724) + float physics:mass = 0.022965211 + quatf physics:principalAxes = (0.4916204, 0.49165696, 0.5082044, 0.50824314) + + over "thumb_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0015952424, -0.0013767378, 0.012809113) + float3 physics:diagonalInertia = (2.190736e-7, 4.8410817e-7, 6.1635996e-7) + float physics:mass = 0.005159339 + quatf physics:principalAxes = (0.57155734, 0.56299645, 0.41924012, 0.42496464) + + over "thumb_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.006749175, 0.001465402, 0.01296435) + float3 physics:diagonalInertia = (8.498717e-8, 2.6375918e-7, 2.7693662e-7) + float physics:mass = 0.004089755 + quatf physics:principalAxes = (0.38330695, 0.37363276, 0.5807098, 0.6133926) + } + } + } + } + } + } + } + + over "Physics" + { + def PhysicsRevoluteJoint "pinky_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.028670534, 0.038101938, 0.1503127) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -9.740282 + float physics:upperLimit = 9.740282 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.016769808, -0.0000126288305, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041945525, 0, 0.044819437) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 89.95438 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "pinky_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + float newton:mimicCoef1 = 0.8917 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0027556196, 0, 0.031702425) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0322943, 0.016501935, 0.15931144) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -9.740282 + float physics:upperLimit = 9.740282 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.016769808, -0.0000126288305, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041945525, 0, 0.044819437) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 89.95438 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "ring_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + float newton:mimicCoef1 = 0.8917 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0027556196, 0, 0.031702425) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.03459913, -0.005098064, 0.16380432) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -9.740282 + float physics:upperLimit = 9.740282 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.016769808, -0.0000126288305, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041945525, 0, 0.044819437) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 89.95438 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "middle_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + float newton:mimicCoef1 = 0.8917 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0027556196, 0, 0.031702425) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_mcp_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.02986529, -0.026698064, 0.15931144) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = -9.740282 + float physics:upperLimit = 9.740282 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.016769808, -0.0000126288305, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_pip" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0041945525, 0, 0.044819437) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 89.95438 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "index_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + float newton:mimicCoef1 = 0.8917 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0027556196, 0, 0.031702425) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "X" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.00091528, -0.0050818, 0.057392) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0, 0, -1, 0) + quatf physics:localRot1 = (0, 0, -1, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 80.21409 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_cmc_roll" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.024508, -0.002864, 0.0035063) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.510268, 0.86001545, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0011523, -0.00048559, 0.030795) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (-0.6851425, 0.17486598, -0.17486534, -0.685145) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 45.263664 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_mcp" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0064539, 3.469447e-18, 0.055858) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 60.16057 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "thumb_ip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 1 + float newton:mimicCoef1 = 1.1619 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0053547, 3.469447e-18, 0.034485) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 69.90085 + custom float urdf:limit:effort = 1 + custom float urdf:limit:velocity = 1 + } + + def PhysicsFixedJoint "root_joint" + { + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + } + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physx.usda b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physx.usda new file mode 100644 index 0000000..c4763b1 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/Physics/physx.usda @@ -0,0 +1,178 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_l20_left" +{ + over "Physics" + { + over "pinky_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "pinky_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "pinky_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "ring_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "ring_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "ring_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "ring_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "middle_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "middle_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "middle_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "middle_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "index_mcp_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "index_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "index_pip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "index_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "thumb_cmc_roll" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "thumb_mcp" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "thumb_ip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/base.usda b/urdf/l20/left/linkerhand_l20_left/payloads/base.usda new file mode 100644 index 0000000..bdf6296 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/base.usda @@ -0,0 +1,728 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./robot.usda@ + ] + upAxis = "Z" +) + +def Xform "linkerhand_l20_left" ( + prepend apiSchemas = ["GeomModelAPI"] + assetInfo = { + string name = "linkerhand_l20_left" + } + kind = "component" +) +{ + float3[] extentsHint = [(-0.03771345, -0.15657327, -1.4059577e-8), (0.038920756, 0.05546601, 0.2633897), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (-0.03771345, -0.15657327, -1.4059577e-8), (0.038920756, 0.05546601, 0.2633897)] + + def Scope "Materials" + { + } + + def Scope "Geometry" + { + def Xform "hand_base_link" + { + def Xform "hand_base_link" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0286705351154727, 0.0381019360798378, 0.150312712339165) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0167698082541766, -0.0000126288306181443, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419455239160021, 0, 0.0448194355727413) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00275561954550002, 0, 0.0317024252339397) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_distal_1" ( + displayName = "pinky_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_middle_1" ( + displayName = "pinky_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_proximal_1" ( + displayName = "pinky_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_metacarpals_1" ( + displayName = "pinky_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0322943001717225, 0.0165019360798537, 0.1593114381003) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0167698082541766, -0.0000126288306177003, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419455239160021, 0, 0.0448194355727413) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00275561954550363, 0, 0.0317024242175084) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_distal_1" ( + displayName = "ring_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_middle_1" ( + displayName = "ring_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_proximal_1" ( + displayName = "ring_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_metacarpals_1" ( + displayName = "ring_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0345991283789502, -0.00509806392012034, 0.163804328353988) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0167698082541766, -0.0000126288306171729, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419455239160021, 0, 0.0448194355727413) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00275561954550102, 0, 0.0317024252339387) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_distal_1" ( + displayName = "middle_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_middle_1" ( + displayName = "middle_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_proximal_1" ( + displayName = "middle_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_metacarpals_1" ( + displayName = "middle_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_metacarpals" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.029865288607565, -0.0266980639200853, 0.159311439204817) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0167698082541766, -0.0000126288306177003, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_middle" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00419455239160021, 0, 0.0448194355727413) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_middle" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00275561954550102, 0, 0.0317024252339397) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_distal_1" ( + displayName = "index_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_middle_1" ( + displayName = "index_middle" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_proximal_1" ( + displayName = "index_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_metacarpals_1" ( + displayName = "index_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base2" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.00091528, -0.0050818, 0.057392) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals_base2" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_metacarpals_base1" + { + quatf xformOp:orient = (0.510268, 0.86001545, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.024508, -0.002864, 0.0035063) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals_base1" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_metacarpals" + { + quatf xformOp:orient = (0.6851425, -0.17486598, 0.17486534, 0.685145) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0011523, -0.00048559, 0.030795) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0064539, 0, 0.055858) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0053547, 0, 0.034485) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_distal_1" ( + displayName = "thumb_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_proximal_1" ( + displayName = "thumb_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_1" ( + displayName = "thumb_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base1_1" ( + displayName = "thumb_metacarpals_base1" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base2_1" ( + displayName = "thumb_metacarpals_base2" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "hand_base_link_1" ( + displayName = "hand_base_link" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + } + + def Scope "Physics" + { + } + + def Scope "VisualMaterials" + { + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/geometries.usd b/urdf/l20/left/linkerhand_l20_left/payloads/geometries.usd new file mode 100644 index 0000000..012dcbe Binary files /dev/null and b/urdf/l20/left/linkerhand_l20_left/payloads/geometries.usd differ diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/instances.usda b/urdf/l20/left/linkerhand_l20_left/payloads/instances.usda new file mode 100644 index 0000000..25ccbb3 --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/instances.usda @@ -0,0 +1,708 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Instances" +{ + def Xform "hand_base_link" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "hand_base_link_1" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_metacarpals" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "BlackAccent" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_metacarpals_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_metacarpals" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_middle" ( + prepend references = @./geometries.usd@ + ) + { + over "index_middle" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_middle_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_middle" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals_base2" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "BlackAccent" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_base2_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals_base1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base1" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "BlackAccent" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_base1_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base1" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/materials.usda b/urdf/l20/left/linkerhand_l20_left/payloads/materials.usda new file mode 100644 index 0000000..f9ec22a --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/materials.usda @@ -0,0 +1,90 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/l20/left/linkerhand_l20_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Materials" +{ + def Material "silver" + { + color3f inputs:diffuseColor = (0.21404114, 0.21404114, 0.23302203) + float inputs:metallic = 0 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token inputs:wrapMode = "repeat" + token outputs:displacement ( + displayGroup = "Outputs" + ) + prepend token outputs:displacement.connect = + token outputs:surface ( + displayGroup = "Outputs" + ) + prepend token outputs:surface.connect = + token outputs:volume ( + displayGroup = "Outputs" + ) + + def Shader "PreviewSurface" ( + apiSchemas = ["NodeDefAPI"] + ) + { + token info:id = "UsdPreviewSurface" + prepend color3f inputs:diffuseColor.connect = + prepend float inputs:metallic.connect = + prepend float inputs:opacity.connect = + prepend float inputs:roughness.connect = + token outputs:displacement + token outputs:surface + } + } + + def Material "BlackAccent" + { + color3f inputs:diffuseColor = (0.01960665, 0.01960665, 0.01960665) + float inputs:metallic = 0 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token inputs:wrapMode = "repeat" + token outputs:displacement ( + displayGroup = "Outputs" + ) + prepend token outputs:displacement.connect = + token outputs:surface ( + displayGroup = "Outputs" + ) + prepend token outputs:surface.connect = + token outputs:volume ( + displayGroup = "Outputs" + ) + + def Shader "PreviewSurface" ( + apiSchemas = ["NodeDefAPI"] + ) + { + token info:id = "UsdPreviewSurface" + prepend color3f inputs:diffuseColor.connect = + prepend float inputs:metallic.connect = + prepend float inputs:opacity.connect = + prepend float inputs:roughness.connect = + token outputs:displacement + token outputs:surface + } + } +} + diff --git a/urdf/l20/left/linkerhand_l20_left/payloads/robot.usda b/urdf/l20/left/linkerhand_l20_left/payloads/robot.usda new file mode 100644 index 0000000..e7b1d9f --- /dev/null +++ b/urdf/l20/left/linkerhand_l20_left/payloads/robot.usda @@ -0,0 +1,327 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_l20_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp7daip3z6/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/usdex_linkerhand_l20_left/linkerhand_l20_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_l20_left_dqwe6zav/temp_linkerhand_l20_left/linkerhand_l20_left.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_l20_left" ( + prepend apiSchemas = ["IsaacRobotAPI"] +) +{ + prepend rel isaac:physics:robotJoints = [ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ] + prepend rel isaac:physics:robotLinks = [ + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ] + token isaac:robotType = "Default" + + over "Geometry" + { + over "hand_base_link" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "pinky_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "ring_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "ring_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "middle_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "middle_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "index_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_middle" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "index_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "thumb_metacarpals_base2" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_metacarpals_base1" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "thumb_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + } + } + } + + over "Physics" + { + over "root_joint" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "pinky_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "ring_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "middle_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_mcp_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_pip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "index_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_yaw" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_roll" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_cmc_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_mcp" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "thumb_ip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + } +} + diff --git a/urdf/l20/left/meshes/hand_base_link.STL b/urdf/l20/left/meshes/hand_base_link.STL new file mode 100644 index 0000000..824f32e Binary files /dev/null and b/urdf/l20/left/meshes/hand_base_link.STL differ diff --git a/urdf/l20/left/meshes/index_distal.STL b/urdf/l20/left/meshes/index_distal.STL new file mode 100644 index 0000000..23ceb48 Binary files /dev/null and b/urdf/l20/left/meshes/index_distal.STL differ diff --git a/urdf/l20/left/meshes/index_metacarpals.STL b/urdf/l20/left/meshes/index_metacarpals.STL new file mode 100644 index 0000000..585000a Binary files /dev/null and b/urdf/l20/left/meshes/index_metacarpals.STL differ diff --git a/urdf/l20/left/meshes/index_middle.STL b/urdf/l20/left/meshes/index_middle.STL new file mode 100644 index 0000000..3951f49 Binary files /dev/null and b/urdf/l20/left/meshes/index_middle.STL differ diff --git a/urdf/l20/left/meshes/index_proximal.STL b/urdf/l20/left/meshes/index_proximal.STL new file mode 100644 index 0000000..79761ee Binary files /dev/null and b/urdf/l20/left/meshes/index_proximal.STL differ diff --git a/urdf/l20/left/meshes/middle_distal.STL b/urdf/l20/left/meshes/middle_distal.STL new file mode 100644 index 0000000..da6f34f Binary files /dev/null and b/urdf/l20/left/meshes/middle_distal.STL differ diff --git a/urdf/l20/left/meshes/middle_metacarpals.STL b/urdf/l20/left/meshes/middle_metacarpals.STL new file mode 100644 index 0000000..585000a Binary files /dev/null and b/urdf/l20/left/meshes/middle_metacarpals.STL differ diff --git a/urdf/l20/left/meshes/middle_middle.STL b/urdf/l20/left/meshes/middle_middle.STL new file mode 100644 index 0000000..cf50891 Binary files /dev/null and b/urdf/l20/left/meshes/middle_middle.STL differ diff --git a/urdf/l20/left/meshes/middle_proximal.STL b/urdf/l20/left/meshes/middle_proximal.STL new file mode 100644 index 0000000..fabff13 Binary files /dev/null and b/urdf/l20/left/meshes/middle_proximal.STL differ diff --git a/urdf/l20/left/meshes/pinky_distal.STL b/urdf/l20/left/meshes/pinky_distal.STL new file mode 100644 index 0000000..ca25c0b Binary files /dev/null and b/urdf/l20/left/meshes/pinky_distal.STL differ diff --git a/urdf/l20/left/meshes/pinky_metacarpals.STL b/urdf/l20/left/meshes/pinky_metacarpals.STL new file mode 100644 index 0000000..585000a Binary files /dev/null and b/urdf/l20/left/meshes/pinky_metacarpals.STL differ diff --git a/urdf/l20/left/meshes/pinky_middle.STL b/urdf/l20/left/meshes/pinky_middle.STL new file mode 100644 index 0000000..76cc149 Binary files /dev/null and b/urdf/l20/left/meshes/pinky_middle.STL differ diff --git a/urdf/l20/left/meshes/pinky_proximal.STL b/urdf/l20/left/meshes/pinky_proximal.STL new file mode 100644 index 0000000..dcce5d4 Binary files /dev/null and b/urdf/l20/left/meshes/pinky_proximal.STL differ diff --git a/urdf/l20/left/meshes/ring_distal.STL b/urdf/l20/left/meshes/ring_distal.STL new file mode 100644 index 0000000..4dfa886 Binary files /dev/null and b/urdf/l20/left/meshes/ring_distal.STL differ diff --git a/urdf/l20/left/meshes/ring_metacarpals.STL b/urdf/l20/left/meshes/ring_metacarpals.STL new file mode 100644 index 0000000..585000a Binary files /dev/null and b/urdf/l20/left/meshes/ring_metacarpals.STL differ diff --git a/urdf/l20/left/meshes/ring_middle.STL b/urdf/l20/left/meshes/ring_middle.STL new file mode 100644 index 0000000..62deb2e Binary files /dev/null and b/urdf/l20/left/meshes/ring_middle.STL differ diff --git a/urdf/l20/left/meshes/ring_proximal.STL b/urdf/l20/left/meshes/ring_proximal.STL new file mode 100644 index 0000000..a0b1998 Binary files /dev/null and b/urdf/l20/left/meshes/ring_proximal.STL differ diff --git a/urdf/l20/left/meshes/thumb_distal.STL b/urdf/l20/left/meshes/thumb_distal.STL new file mode 100644 index 0000000..fe86625 Binary files /dev/null and b/urdf/l20/left/meshes/thumb_distal.STL differ diff --git a/urdf/l20/left/meshes/thumb_metacarpals.STL b/urdf/l20/left/meshes/thumb_metacarpals.STL new file mode 100644 index 0000000..0400ce7 Binary files /dev/null and b/urdf/l20/left/meshes/thumb_metacarpals.STL differ diff --git a/urdf/l20/left/meshes/thumb_metacarpals_base1.STL b/urdf/l20/left/meshes/thumb_metacarpals_base1.STL new file mode 100644 index 0000000..5495263 Binary files /dev/null and b/urdf/l20/left/meshes/thumb_metacarpals_base1.STL differ diff --git a/urdf/l20/left/meshes/thumb_metacarpals_base2.STL b/urdf/l20/left/meshes/thumb_metacarpals_base2.STL new file mode 100644 index 0000000..e6b7240 Binary files /dev/null and b/urdf/l20/left/meshes/thumb_metacarpals_base2.STL differ diff --git a/urdf/l20/left/meshes/thumb_proximal.STL b/urdf/l20/left/meshes/thumb_proximal.STL new file mode 100644 index 0000000..77b4ced Binary files /dev/null and b/urdf/l20/left/meshes/thumb_proximal.STL differ diff --git a/urdf/l20/right/linkerhand_l20_right.urdf b/urdf/l20/right/linkerhand_l20_right.urdf new file mode 100644 index 0000000..088e014 --- /dev/null +++ b/urdf/l20/right/linkerhand_l20_right.urdf @@ -0,0 +1,1204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/l20/right/meshes/base_link.STL b/urdf/l20/right/meshes/base_link.STL new file mode 100644 index 0000000..add665f Binary files /dev/null and b/urdf/l20/right/meshes/base_link.STL differ diff --git a/urdf/l20/right/meshes/index_distal.STL b/urdf/l20/right/meshes/index_distal.STL new file mode 100644 index 0000000..a19d1a9 Binary files /dev/null and b/urdf/l20/right/meshes/index_distal.STL differ diff --git a/urdf/l20/right/meshes/index_metacarpals.STL b/urdf/l20/right/meshes/index_metacarpals.STL new file mode 100644 index 0000000..f1b1287 Binary files /dev/null and b/urdf/l20/right/meshes/index_metacarpals.STL differ diff --git a/urdf/l20/right/meshes/index_middle.STL b/urdf/l20/right/meshes/index_middle.STL new file mode 100644 index 0000000..74e3db5 Binary files /dev/null and b/urdf/l20/right/meshes/index_middle.STL differ diff --git a/urdf/l20/right/meshes/index_proximal.STL b/urdf/l20/right/meshes/index_proximal.STL new file mode 100644 index 0000000..6a3064b Binary files /dev/null and b/urdf/l20/right/meshes/index_proximal.STL differ diff --git a/urdf/l20/right/meshes/middle_distal.STL b/urdf/l20/right/meshes/middle_distal.STL new file mode 100644 index 0000000..d4d3321 Binary files /dev/null and b/urdf/l20/right/meshes/middle_distal.STL differ diff --git a/urdf/l20/right/meshes/middle_metacarpals.STL b/urdf/l20/right/meshes/middle_metacarpals.STL new file mode 100644 index 0000000..2568c2e Binary files /dev/null and b/urdf/l20/right/meshes/middle_metacarpals.STL differ diff --git a/urdf/l20/right/meshes/middle_middle.STL b/urdf/l20/right/meshes/middle_middle.STL new file mode 100644 index 0000000..930e01b Binary files /dev/null and b/urdf/l20/right/meshes/middle_middle.STL differ diff --git a/urdf/l20/right/meshes/middle_proximal.STL b/urdf/l20/right/meshes/middle_proximal.STL new file mode 100644 index 0000000..7a4639b Binary files /dev/null and b/urdf/l20/right/meshes/middle_proximal.STL differ diff --git a/urdf/l20/right/meshes/pinky_distal.STL b/urdf/l20/right/meshes/pinky_distal.STL new file mode 100644 index 0000000..666bc74 Binary files /dev/null and b/urdf/l20/right/meshes/pinky_distal.STL differ diff --git a/urdf/l20/right/meshes/pinky_metacarpals.STL b/urdf/l20/right/meshes/pinky_metacarpals.STL new file mode 100644 index 0000000..40e62b6 Binary files /dev/null and b/urdf/l20/right/meshes/pinky_metacarpals.STL differ diff --git a/urdf/l20/right/meshes/pinky_middle.STL b/urdf/l20/right/meshes/pinky_middle.STL new file mode 100644 index 0000000..3428b81 Binary files /dev/null and b/urdf/l20/right/meshes/pinky_middle.STL differ diff --git a/urdf/l20/right/meshes/pinky_proximal.STL b/urdf/l20/right/meshes/pinky_proximal.STL new file mode 100644 index 0000000..21d42ef Binary files /dev/null and b/urdf/l20/right/meshes/pinky_proximal.STL differ diff --git a/urdf/l20/right/meshes/ring_distal.STL b/urdf/l20/right/meshes/ring_distal.STL new file mode 100644 index 0000000..62c1f4b Binary files /dev/null and b/urdf/l20/right/meshes/ring_distal.STL differ diff --git a/urdf/l20/right/meshes/ring_metacarpals.STL b/urdf/l20/right/meshes/ring_metacarpals.STL new file mode 100644 index 0000000..d1e2149 Binary files /dev/null and b/urdf/l20/right/meshes/ring_metacarpals.STL differ diff --git a/urdf/l20/right/meshes/ring_middle.STL b/urdf/l20/right/meshes/ring_middle.STL new file mode 100644 index 0000000..3e3aba1 Binary files /dev/null and b/urdf/l20/right/meshes/ring_middle.STL differ diff --git a/urdf/l20/right/meshes/ring_proximal.STL b/urdf/l20/right/meshes/ring_proximal.STL new file mode 100644 index 0000000..c336b91 Binary files /dev/null and b/urdf/l20/right/meshes/ring_proximal.STL differ diff --git a/urdf/l20/right/meshes/thumb_distal.STL b/urdf/l20/right/meshes/thumb_distal.STL new file mode 100644 index 0000000..7aecf08 Binary files /dev/null and b/urdf/l20/right/meshes/thumb_distal.STL differ diff --git a/urdf/l20/right/meshes/thumb_metacarpals.STL b/urdf/l20/right/meshes/thumb_metacarpals.STL new file mode 100644 index 0000000..1edc212 Binary files /dev/null and b/urdf/l20/right/meshes/thumb_metacarpals.STL differ diff --git a/urdf/l20/right/meshes/thumb_metacarpals_base1.STL b/urdf/l20/right/meshes/thumb_metacarpals_base1.STL new file mode 100644 index 0000000..30d9be3 Binary files /dev/null and b/urdf/l20/right/meshes/thumb_metacarpals_base1.STL differ diff --git a/urdf/l20/right/meshes/thumb_metacarpals_base2.STL b/urdf/l20/right/meshes/thumb_metacarpals_base2.STL new file mode 100644 index 0000000..6ad5412 Binary files /dev/null and b/urdf/l20/right/meshes/thumb_metacarpals_base2.STL differ diff --git a/urdf/l20/right/meshes/thumb_proximal.STL b/urdf/l20/right/meshes/thumb_proximal.STL new file mode 100644 index 0000000..361776a Binary files /dev/null and b/urdf/l20/right/meshes/thumb_proximal.STL differ diff --git a/urdf/o6/left/linkerhand_o6_left.urdf b/urdf/o6/left/linkerhand_o6_left.urdf new file mode 100644 index 0000000..1925ca0 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left.urdf @@ -0,0 +1,666 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/o6/left/linkerhand_o6_left/linkerhand_o6_left.usda b/urdf/o6/left/linkerhand_o6_left/linkerhand_o6_left.usda new file mode 100644 index 0000000..c9e1465 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/linkerhand_o6_left.usda @@ -0,0 +1,52 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Xform "linkerhand_o6_left" ( + prepend references = @./payloads/base.usda@ + variants = { + string Physics = "physx" + } + append variantSets = "Physics" +) +{ + variantSet "Physics" = { + "mujoco" ( + prepend payload = @./payloads/Physics/mujoco.usda@ + ) { + + } + "none" { + + } + "physics" ( + prepend payload = @./payloads/Physics/physics.usda@ + ) { + + } + "physx" ( + prepend payload = @./payloads/Physics/physx.usda@ + ) { + + } + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/Physics/mujoco.usda b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/mujoco.usda new file mode 100644 index 0000000..af0728a --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/mujoco.usda @@ -0,0 +1,332 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_o6_left" +{ + over "Physics" + { + def MjcActuator "lh_thumb_cmc_yaw_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_thumb_cmc_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_thumb_ip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_index_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_index_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_middle_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_middle_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_ring_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_ring_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_pinky_mcp_pitch_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + def MjcActuator "lh_pinky_dip_actuator" + { + uniform double mjc:forceRange:max = 100 + uniform double mjc:forceRange:min = -100 + custom rel mjc:target + prepend rel mjc:target = + } + + over "root_joint" + { + } + + over "lh_thumb_cmc_yaw" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_thumb_cmc_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_thumb_ip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_index_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_index_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_middle_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_middle_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_ring_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_ring_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_pinky_mcp_pitch" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + + over "lh_pinky_dip" ( + delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + } + } + + over "Geometry" + { + over "lh_hand_base_link" + { + over "lh_thumb_metacarpals_base2" + { + over "lh_thumb_metacarpals" + { + over "lh_thumb_distal" + { + over "thumb_distal" + { + } + + over "thumb_distal_1" + { + } + } + + over "thumb_metacarpals" + { + } + + over "thumb_metacarpals_1" + { + } + } + + over "thumb_metacarpals_base2" + { + } + + over "thumb_metacarpals_base2_1" + { + } + } + + over "lh_index_proximal" + { + over "lh_index_distal" + { + over "index_distal" + { + } + + over "index_distal_1" + { + } + } + + over "index_proximal" + { + } + + over "index_proximal_1" + { + } + } + + over "lh_middle_proximal" + { + over "lh_middle_distal" + { + over "middle_distal" + { + } + + over "middle_distal_1" + { + } + } + + over "middle_proximal" + { + } + + over "middle_proximal_1" + { + } + } + + over "lh_ring_proximal" + { + over "lh_ring_distal" + { + over "ring_distal" + { + } + + over "ring_distal_1" + { + } + } + + over "ring_proximal" + { + } + + over "ring_proximal_1" + { + } + } + + over "lh_pinky_proximal" + { + over "lh_pinky_distal" + { + over "pinky_distal" + { + } + + over "pinky_distal_1" + { + } + } + + over "pinky_proximal" + { + } + + over "pinky_proximal_1" + { + } + } + + over "hand_base_link" + { + } + + over "hand_base_link_1" + { + } + } + } + + over "Materials" + { + } + + over "VisualMaterials" + { + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physics.usda b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physics.usda new file mode 100644 index 0000000..c6dac36 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physics.usda @@ -0,0 +1,394 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_o6_left" +{ + over "Geometry" + { + over "lh_hand_base_link" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsArticulationRootAPI", "NewtonArticulationRootAPI", "PhysicsMassAPI"] + ) + { + bool newton:selfCollisionEnabled = 0 + point3f physics:centerOfMass = (-0.0015778857, -0.00034876727, 0.053845223) + float3 physics:diagonalInertia = (0.000022785269, 0.000033403405, 0.00005226303) + float physics:mass = 0.067293525 + quatf physics:principalAxes = (0.7112235, 0.0196564, 0.7019677, -0.031875554) + + over "lh_thumb_metacarpals_base2" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0016280068, -0.0027668017, -0.0018423444) + float3 physics:diagonalInertia = (2.804746e-8, 4.6153662e-8, 5.5545172e-8) + float physics:mass = 0.001385883 + quatf physics:principalAxes = (0.71651435, 0.1483551, 0.6348633, 0.2480857) + + over "lh_thumb_metacarpals" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.00004248162, 0.000017418392, 0.022834163) + float3 physics:diagonalInertia = (8.782631e-7, 0.0000011610094, 0.0000017675784) + float physics:mass = 0.012338159 + quatf physics:principalAxes = (0.602796, 0.6027095, 0.37003604, 0.3693936) + + over "lh_thumb_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.004137257, -5.907045e-8, 0.023011401) + float3 physics:diagonalInertia = (2.7226213e-7, 0.0000012248909, 0.0000013107585) + float physics:mass = 0.0076333294 + quatf physics:principalAxes = (0.7312508, 0.000050898147, 0.68210864, 0.000050140923) + } + } + } + + over "lh_index_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0020865656, 0.0000025383872, 0.017273495) + float3 physics:diagonalInertia = (7.583063e-8, 2.7291307e-7, 2.757608e-7) + float physics:mass = 0.0025317466 + quatf physics:principalAxes = (0.78133, 0.007643632, 0.6240355, 0.0066868095) + + over "lh_index_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0065898662, 0.0000051385564, 0.01943936) + float3 physics:diagonalInertia = (7.204472e-8, 3.6532765e-7, 3.7459085e-7) + float physics:mass = 0.003769511 + quatf physics:principalAxes = (0.54057455, 0.0024824692, 0.84128624, 0.0032386186) + } + } + + over "lh_middle_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0020866066, 0.0000025691818, 0.0172735) + float3 physics:diagonalInertia = (7.5831146e-8, 2.7291338e-7, 2.757611e-7) + float physics:mass = 0.0025317736 + quatf physics:principalAxes = (0.7813296, 0.0076768305, 0.62403536, 0.0067128767) + + over "lh_middle_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0065898653, 0.0000051086295, 0.019439332) + float3 physics:diagonalInertia = (7.204529e-8, 3.6532907e-7, 3.745922e-7) + float physics:mass = 0.003769528 + quatf physics:principalAxes = (0.5405751, 0.0024706838, 0.84128594, 0.003223407) + } + } + + over "lh_ring_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.0020866792, 0.0000026300042, 0.017273493) + float3 physics:diagonalInertia = (7.5832226e-8, 2.7291406e-7, 2.7576172e-7) + float physics:mass = 0.0025318223 + quatf physics:principalAxes = (0.78132856, 0.0077359965, 0.62403536, 0.0067587425) + + over "lh_ring_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.0065898667, 0.000005058835, 0.019439397) + float3 physics:diagonalInertia = (7.20441e-8, 3.6532612e-7, 3.7458938e-7) + float physics:mass = 0.003769496 + quatf physics:principalAxes = (0.54057366, 0.002450255, 0.841287, 0.0031969126) + } + } + + over "lh_pinky_proximal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (-0.002086736, 0.0000026806224, 0.017273486) + float3 physics:diagonalInertia = (7.5833086e-8, 2.7291458e-7, 2.7576223e-7) + float physics:mass = 0.00253186 + quatf physics:principalAxes = (0.78132784, 0.007784023, 0.6240353, 0.0067960154) + + over "lh_pinky_distal" ( + prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"] + ) + { + point3f physics:centerOfMass = (0.006589876, 0.0000050308754, 0.01943945) + float3 physics:diagonalInertia = (7.2043434e-8, 3.6532472e-7, 3.7458818e-7) + float physics:mass = 0.0037694806 + quatf physics:principalAxes = (0.54057276, 0.0024336982, 0.8412878, 0.0031746821) + } + } + } + } + + over "Physics" + { + def PhysicsRevoluteJoint "lh_thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Z" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.011508, -0.022975, 0.032794) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 74.48451 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0061649, -0.010678, -0.004891) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.41919965, 0.47202873, -0.27252436, 0.7260792) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 33.231552 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_thumb_ip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + float newton:mimicCoef1 = 2.29 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0037776, 7.372575e-18, 0.045368) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 61.87944 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_index_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0024758, -0.02419, 0.098779) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.99965733, 0.026176646, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 91.67325 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_index_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0052516, 0, 0.036625) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 81.93297 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_middle_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.00052576, -0.00634, 0.1027) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 91.67325 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_middle_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0052516, 0, 0.036625) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 81.93297 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_ring_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0010258, 0.011135, 0.098767) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.99965733, -0.026176646, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 91.67325 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_ring_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0052516, 0, 0.036625) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 81.93297 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0.0024758, 0.028372, 0.092741) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (0.99904823, -0.043619126, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 91.67325 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsRevoluteJoint "lh_pinky_dip" ( + prepend apiSchemas = ["NewtonMimicAPI", "PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"] + ) + { + float drive:angular:physics:maxForce = 100 + float newton:mimicCoef1 = 0.89 + rel newton:mimicJoint = + uniform token physics:axis = "Y" + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (-0.0052516, -3.469447e-18, 0.036625) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + float physics:lowerLimit = 0 + float physics:upperLimit = 81.93297 + custom float urdf:limit:effort = 100 + custom float urdf:limit:velocity = 1 + } + + def PhysicsFixedJoint "root_joint" + { + custom rel physics:body0 + prepend rel physics:body0 = + custom rel physics:body1 + prepend rel physics:body1 = + point3f physics:localPos0 = (0, 0, 0) + point3f physics:localPos1 = (0, 0, 0) + quatf physics:localRot0 = (1, 0, 0, 0) + quatf physics:localRot1 = (1, 0, 0, 0) + } + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physx.usda b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physx.usda new file mode 100644 index 0000000..be11684 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/Physics/physx.usda @@ -0,0 +1,108 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./physics.usda@ + ] + upAxis = "Z" +) + +over "linkerhand_o6_left" +{ + over "Physics" + { + over "lh_thumb_cmc_yaw" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_thumb_cmc_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_thumb_ip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_index_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_index_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_middle_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_middle_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_ring_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_ring_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_pinky_mcp_pitch" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + + over "lh_pinky_dip" ( + prepend apiSchemas = ["PhysxJointAPI"] + ) + { + float physxJoint:maxJointVelocity = 57.29578 + } + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/base.usda b/urdf/o6/left/linkerhand_o6_left/payloads/base.usda new file mode 100644 index 0000000..5c9478c --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/base.usda @@ -0,0 +1,418 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + subLayers = [ + @./robot.usda@ + ] + upAxis = "Z" +) + +def Xform "linkerhand_o6_left" ( + prepend apiSchemas = ["GeomModelAPI"] + assetInfo = { + string name = "linkerhand_o6_left" + } + kind = "component" +) +{ + float3[] extentsHint = [(-0.02, -0.116600335, 8.4912535e-11), (0.071913876, 0.040911872, 0.17689712), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (-0.02, -0.116600335, 8.4912535e-11), (0.071913876, 0.040911872, 0.17689712)] + + def Scope "Materials" + { + } + + def Scope "Geometry" + { + def Xform "lh_hand_base_link" + { + def Xform "hand_base_link" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_thumb_metacarpals_base2" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.011508, -0.022975, 0.032794) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals_base2" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_thumb_metacarpals" + { + quatf xformOp:orient = (0.41919965, 0.47202873, -0.27252436, 0.7260792) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0061649, -0.010678, -0.004891) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_metacarpals" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_thumb_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0037776, 0, 0.045368) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "thumb_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "thumb_distal_1" ( + displayName = "thumb_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_1" ( + displayName = "thumb_metacarpals" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "thumb_metacarpals_base2_1" ( + displayName = "thumb_metacarpals_base2" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "lh_index_proximal" + { + quatf xformOp:orient = (0.99965733, 0.026176646, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0024758, -0.02419, 0.098779) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_index_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0052516, 0, 0.036625) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "index_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "index_distal_1" ( + displayName = "index_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "index_proximal_1" ( + displayName = "index_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "lh_middle_proximal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.00052576, -0.00634, 0.1027) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_middle_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0052516, 0, 0.036625) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "middle_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "middle_distal_1" ( + displayName = "middle_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "middle_proximal_1" ( + displayName = "middle_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "lh_ring_proximal" + { + quatf xformOp:orient = (0.99965733, -0.026176646, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0010258, 0.011135, 0.098767) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_ring_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0052516, 0, 0.036625) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "ring_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "ring_distal_1" ( + displayName = "ring_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "ring_proximal_1" ( + displayName = "ring_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "lh_pinky_proximal" + { + quatf xformOp:orient = (0.99904823, -0.043619126, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0.0024758, 0.028372, 0.092741) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_proximal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "lh_pinky_distal" + { + quatf xformOp:orient = (1, 0, 0, 0) + float3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (-0.0052516, 0, 0.036625) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + + def Xform "pinky_distal" ( + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + + def Xform "pinky_distal_1" ( + displayName = "pinky_distal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "pinky_proximal_1" ( + displayName = "pinky_proximal" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + + def Xform "hand_base_link_1" ( + displayName = "hand_base_link" + instanceable = true + prepend references = @./instances.usda@ + ) + { + quatd xformOp:orient = (1, 0, 0, 0) + double3 xformOp:scale = (1, 1, 1) + double3 xformOp:translate = (0, 0, 0) + uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] + } + } + } + + def Scope "Physics" + { + } + + def Scope "VisualMaterials" + { + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/geometries.usd b/urdf/o6/left/linkerhand_o6_left/payloads/geometries.usd new file mode 100644 index 0000000..0375496 Binary files /dev/null and b/urdf/o6/left/linkerhand_o6_left/payloads/geometries.usd differ diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/instances.usda b/urdf/o6/left/linkerhand_o6_left/payloads/instances.usda new file mode 100644 index 0000000..8251fe0 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/instances.usda @@ -0,0 +1,456 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Instances" +{ + def Xform "hand_base_link" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "hand_base_link_1" ( + prepend references = @./geometries.usd@ + ) + { + over "hand_base_link" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals_base2" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "BlackAccent" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_base2_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals_base2" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_metacarpals" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_metacarpals_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_metacarpals" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "thumb_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "thumb_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "thumb_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "index_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "index_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "index_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "middle_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "middle_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "middle_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "ring_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "ring_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "ring_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_proximal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_proximal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_proximal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } + + def Xform "pinky_distal" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + custom rel material:binding + prepend rel material:binding = + } + + def Scope "VisualMaterials" + { + def Material "silver" ( + instanceable = true + prepend references = @./materials.usda@ + ) + { + } + } + } + + def Xform "pinky_distal_1" ( + prepend references = @./geometries.usd@ + ) + { + over "pinky_distal" ( + apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"] + ) + { + token physics:approximation = "convexHull" + token purpose = "guide" + } + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/materials.usda b/urdf/o6/left/linkerhand_o6_left/payloads/materials.usda new file mode 100644 index 0000000..4b6e4b2 --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/materials.usda @@ -0,0 +1,90 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd + + +Generated from Composed Stage of root layer /home/lxqs/mujoco_testwork/linkerhand-urdf/o6/left/linkerhand_o6_left/payloads/base.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +def Scope "Materials" +{ + def Material "silver" + { + color3f inputs:diffuseColor = (0.21404114, 0.21404114, 0.23302203) + float inputs:metallic = 0 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token inputs:wrapMode = "repeat" + token outputs:displacement ( + displayGroup = "Outputs" + ) + prepend token outputs:displacement.connect = + token outputs:surface ( + displayGroup = "Outputs" + ) + prepend token outputs:surface.connect = + token outputs:volume ( + displayGroup = "Outputs" + ) + + def Shader "PreviewSurface" ( + apiSchemas = ["NodeDefAPI"] + ) + { + token info:id = "UsdPreviewSurface" + prepend color3f inputs:diffuseColor.connect = + prepend float inputs:metallic.connect = + prepend float inputs:opacity.connect = + prepend float inputs:roughness.connect = + token outputs:displacement + token outputs:surface + } + } + + def Material "BlackAccent" + { + color3f inputs:diffuseColor = (0.01960665, 0.01960665, 0.01960665) + float inputs:metallic = 0 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token inputs:wrapMode = "repeat" + token outputs:displacement ( + displayGroup = "Outputs" + ) + prepend token outputs:displacement.connect = + token outputs:surface ( + displayGroup = "Outputs" + ) + prepend token outputs:surface.connect = + token outputs:volume ( + displayGroup = "Outputs" + ) + + def Shader "PreviewSurface" ( + apiSchemas = ["NodeDefAPI"] + ) + { + token info:id = "UsdPreviewSurface" + prepend color3f inputs:diffuseColor.connect = + prepend float inputs:metallic.connect = + prepend float inputs:opacity.connect = + prepend float inputs:roughness.connect = + token outputs:displacement + token outputs:surface + } + } +} + diff --git a/urdf/o6/left/linkerhand_o6_left/payloads/robot.usda b/urdf/o6/left/linkerhand_o6_left/payloads/robot.usda new file mode 100644 index 0000000..3020d4c --- /dev/null +++ b/urdf/o6/left/linkerhand_o6_left/payloads/robot.usda @@ -0,0 +1,197 @@ +#usda 1.0 +( + customLayerData = { + string creator = "URDF USD Converter v0.1.3" + } + defaultPrim = "linkerhand_o6_left" + doc = """Generated from Composed Stage of root layer /tmp/tmp43xsk_0z/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/usdex_linkerhand_o6_left/linkerhand_o6_left.usdc + + +Generated from Composed Stage of root layer /tmp/urdf_import_linkerhand_o6_left_7nekwe14/temp_linkerhand_o6_left/linkerhand_o6_left.usd +""" + kilogramsPerUnit = 1 + metersPerUnit = 1 + upAxis = "Z" +) + +over "linkerhand_o6_left" ( + prepend apiSchemas = ["IsaacRobotAPI"] +) +{ + prepend rel isaac:physics:robotJoints = [ + , + , + , + , + , + , + , + , + , + , + , + , + ] + prepend rel isaac:physics:robotLinks = [ + , + , + , + , + , + , + , + , + , + , + , + , + ] + token isaac:robotType = "Default" + + over "Geometry" + { + over "lh_hand_base_link" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_thumb_metacarpals_base2" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_thumb_metacarpals" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_thumb_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + + over "lh_index_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_index_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + + over "lh_middle_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_middle_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + + over "lh_ring_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_ring_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + + over "lh_pinky_proximal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + over "lh_pinky_distal" ( + prepend apiSchemas = ["IsaacLinkAPI"] + ) + { + } + } + } + } + + over "Physics" + { + over "root_joint" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_thumb_cmc_yaw" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_thumb_cmc_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_thumb_ip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_index_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_index_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_middle_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_middle_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_ring_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_ring_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_pinky_mcp_pitch" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + + over "lh_pinky_dip" ( + prepend apiSchemas = ["IsaacJointAPI"] + ) + { + } + } +} + diff --git a/urdf/o6/left/meshes/hand_base_link.STL b/urdf/o6/left/meshes/hand_base_link.STL new file mode 100644 index 0000000..b7ab0c1 Binary files /dev/null and b/urdf/o6/left/meshes/hand_base_link.STL differ diff --git a/urdf/o6/left/meshes/index_distal.STL b/urdf/o6/left/meshes/index_distal.STL new file mode 100644 index 0000000..db30679 Binary files /dev/null and b/urdf/o6/left/meshes/index_distal.STL differ diff --git a/urdf/o6/left/meshes/index_proximal.STL b/urdf/o6/left/meshes/index_proximal.STL new file mode 100644 index 0000000..f427e3c Binary files /dev/null and b/urdf/o6/left/meshes/index_proximal.STL differ diff --git a/urdf/o6/left/meshes/middle_distal.STL b/urdf/o6/left/meshes/middle_distal.STL new file mode 100644 index 0000000..a4838a5 Binary files /dev/null and b/urdf/o6/left/meshes/middle_distal.STL differ diff --git a/urdf/o6/left/meshes/middle_proximal.STL b/urdf/o6/left/meshes/middle_proximal.STL new file mode 100644 index 0000000..e8d4268 Binary files /dev/null and b/urdf/o6/left/meshes/middle_proximal.STL differ diff --git a/urdf/o6/left/meshes/pinky_distal.STL b/urdf/o6/left/meshes/pinky_distal.STL new file mode 100644 index 0000000..abcb9c0 Binary files /dev/null and b/urdf/o6/left/meshes/pinky_distal.STL differ diff --git a/urdf/o6/left/meshes/pinky_proximal.STL b/urdf/o6/left/meshes/pinky_proximal.STL new file mode 100644 index 0000000..5f013e6 Binary files /dev/null and b/urdf/o6/left/meshes/pinky_proximal.STL differ diff --git a/urdf/o6/left/meshes/ring_distal.STL b/urdf/o6/left/meshes/ring_distal.STL new file mode 100644 index 0000000..b8247b1 Binary files /dev/null and b/urdf/o6/left/meshes/ring_distal.STL differ diff --git a/urdf/o6/left/meshes/ring_proximal.STL b/urdf/o6/left/meshes/ring_proximal.STL new file mode 100644 index 0000000..7c47ff6 Binary files /dev/null and b/urdf/o6/left/meshes/ring_proximal.STL differ diff --git a/urdf/o6/left/meshes/thumb_distal.STL b/urdf/o6/left/meshes/thumb_distal.STL new file mode 100644 index 0000000..19eee73 Binary files /dev/null and b/urdf/o6/left/meshes/thumb_distal.STL differ diff --git a/urdf/o6/left/meshes/thumb_metacarpals.STL b/urdf/o6/left/meshes/thumb_metacarpals.STL new file mode 100644 index 0000000..9f1ab59 Binary files /dev/null and b/urdf/o6/left/meshes/thumb_metacarpals.STL differ diff --git a/urdf/o6/left/meshes/thumb_metacarpals_base2.STL b/urdf/o6/left/meshes/thumb_metacarpals_base2.STL new file mode 100644 index 0000000..5e66834 Binary files /dev/null and b/urdf/o6/left/meshes/thumb_metacarpals_base2.STL differ diff --git a/urdf/o6/right/linkerhand_o6_right.urdf b/urdf/o6/right/linkerhand_o6_right.urdf new file mode 100644 index 0000000..8fca23e --- /dev/null +++ b/urdf/o6/right/linkerhand_o6_right.urdf @@ -0,0 +1,664 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/o6/right/meshes/hand_base_link.STL b/urdf/o6/right/meshes/hand_base_link.STL new file mode 100644 index 0000000..6ab2f6f Binary files /dev/null and b/urdf/o6/right/meshes/hand_base_link.STL differ diff --git a/urdf/o6/right/meshes/index_distal.STL b/urdf/o6/right/meshes/index_distal.STL new file mode 100644 index 0000000..e530ec5 Binary files /dev/null and b/urdf/o6/right/meshes/index_distal.STL differ diff --git a/urdf/o6/right/meshes/index_proximal.STL b/urdf/o6/right/meshes/index_proximal.STL new file mode 100644 index 0000000..86a10cb Binary files /dev/null and b/urdf/o6/right/meshes/index_proximal.STL differ diff --git a/urdf/o6/right/meshes/middle_distal.STL b/urdf/o6/right/meshes/middle_distal.STL new file mode 100644 index 0000000..1582dfe Binary files /dev/null and b/urdf/o6/right/meshes/middle_distal.STL differ diff --git a/urdf/o6/right/meshes/middle_proximal.STL b/urdf/o6/right/meshes/middle_proximal.STL new file mode 100644 index 0000000..2a46d3f Binary files /dev/null and b/urdf/o6/right/meshes/middle_proximal.STL differ diff --git a/urdf/o6/right/meshes/pinky_distal.STL b/urdf/o6/right/meshes/pinky_distal.STL new file mode 100644 index 0000000..581901e Binary files /dev/null and b/urdf/o6/right/meshes/pinky_distal.STL differ diff --git a/urdf/o6/right/meshes/pinky_proximal.STL b/urdf/o6/right/meshes/pinky_proximal.STL new file mode 100644 index 0000000..b0326b3 Binary files /dev/null and b/urdf/o6/right/meshes/pinky_proximal.STL differ diff --git a/urdf/o6/right/meshes/ring_distal.STL b/urdf/o6/right/meshes/ring_distal.STL new file mode 100644 index 0000000..1c2830a Binary files /dev/null and b/urdf/o6/right/meshes/ring_distal.STL differ diff --git a/urdf/o6/right/meshes/ring_proximal.STL b/urdf/o6/right/meshes/ring_proximal.STL new file mode 100644 index 0000000..b98a3db Binary files /dev/null and b/urdf/o6/right/meshes/ring_proximal.STL differ diff --git a/urdf/o6/right/meshes/thumb_distal.STL b/urdf/o6/right/meshes/thumb_distal.STL new file mode 100644 index 0000000..e102dbe Binary files /dev/null and b/urdf/o6/right/meshes/thumb_distal.STL differ diff --git a/urdf/o6/right/meshes/thumb_metacarpals.STL b/urdf/o6/right/meshes/thumb_metacarpals.STL new file mode 100644 index 0000000..df9bccf Binary files /dev/null and b/urdf/o6/right/meshes/thumb_metacarpals.STL differ diff --git a/urdf/o6/right/meshes/thumb_metacarpals_base2.STL b/urdf/o6/right/meshes/thumb_metacarpals_base2.STL new file mode 100644 index 0000000..0546e91 Binary files /dev/null and b/urdf/o6/right/meshes/thumb_metacarpals_base2.STL differ