Organize hand models and launchers; use linear active joint mapping
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# G20
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
- `compare_left.sh`
|
||||
- `compare_right.sh`
|
||||
- `run_left.sh`
|
||||
- `run_right.sh`
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/G20
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/G20/linker_hand_g20_left/g20_left_passive.json
|
||||
@@ -0,0 +1 @@
|
||||
../../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/G20/linker_hand_g20_right/g20_right_passive.json
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_g20_left_dual_compare.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_g20_right_dual_compare.sh" "$@"
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_g20_mujoco_plan.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_g20_right_mujoco_plan.sh" "$@"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# G20 关节弧度监视 GUI(默认 6 位小数)
|
||||
# 订阅 /sim/mujoco/g20/left/joint_state
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_joint_monitor_gui "$@"
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo G20 左手 — 桌面 URDF 验证
|
||||
# URDF: /home/lxqs/桌面/L20/LEFT/linkerhand_g20_left.urdf(已同步到包内)
|
||||
# 默认 mapping=g20_urdf(四指侧摆无外部取负,跟 URDF 轴正向)
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/G20/scripts/run_g20_left_desktop_urdf.sh
|
||||
# ./hands/G20/scripts/run_g20_left_desktop_urdf.sh --pd-drive
|
||||
# 另开终端扫侧摆方向:
|
||||
# ./hands/G20/scripts/run_g20_left_mcp_roll_check.sh
|
||||
# 监视关节弧度:
|
||||
# ./hands/G20/scripts/run_g20_joint_gui.sh
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/G20/linker_hand_g20_left/linker_hand_g20_left_desktop.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/G20/linker_hand_g20_left/linkerhand_g20_left_desktop.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[g20-left-desktop] urdf=$URDF"
|
||||
echo "[g20-left-desktop] xml=$XML"
|
||||
echo "[g20-left-desktop] cmd-topic=/cb_left_hand_control_cmd"
|
||||
echo "[g20-left-desktop] sim-state=/sim/mujoco/g20/left/joint_state"
|
||||
echo "[g20-left-desktop] mapping=g20_urdf (侧摆 cmd0→负限位, cmd255→正限位, 无外部取负)"
|
||||
echo "[g20-left-desktop] URDF 四指 mcp_roll 轴: +X (未翻转;右手已改为 -X)"
|
||||
echo "[g20-left-desktop] 侧摆验证: 另开终端运行 ./hands/G20/scripts/run_g20_left_mcp_roll_check.sh"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name g20_mujoco_plan_bridge_left_desktop \
|
||||
--window-title "G20 left (desktop URDF)" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/g20/left/joint_state \
|
||||
--nominal-topic /retarget/g20/left/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:G20 左手标定 vs L20 原版 URDF(未标定)
|
||||
#
|
||||
# 标定: /home/lxqs/图片/linkerhand_g20_left_tag.urdf
|
||||
# → 同步包内 linker_hand_g20_left.xml(限位/侧摆轴/body 零位);mapping=g20_calibrated
|
||||
# (可用 G20_LEFT_URDF=... 覆盖)
|
||||
# 未标定: L20 V10.1 左手 URDF → 运行时按左手模板刷新 linker_hand_l20v101_left.xml
|
||||
# mapping=l20_urdf
|
||||
#
|
||||
# 主动关节统一按当前模型限位线性换算;g20_calibrated 仅保留可选被动 JSON 联动。
|
||||
#
|
||||
# 默认运动学硬写。需要 PD+自碰时手动加 --pd-drive(两窗均加)。
|
||||
# 两个窗口共用 /cb_left_hand_control_cmd(20 维 0~255)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/G20/scripts/run_g20_left_dual_compare.sh
|
||||
# ./hands/G20/scripts/run_g20_left_dual_compare.sh --cmd-topic /cb_left_hand_control_cmd --speed 1.0
|
||||
# ./hands/G20/scripts/run_g20_left_dual_compare.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2"
|
||||
G20_DIR="$PKG_SRC/urdf/G20/linker_hand_g20_left"
|
||||
URDF_CALIBRATED="${G20_LEFT_URDF:-$ROOT/hands/G20/reference/left_calibrated.urdf}"
|
||||
MESHDIR_CALIB="$G20_DIR/meshes"
|
||||
URDF_UNCALIBRATED="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_left/linkerhand_L20v10.1_left.urdf"
|
||||
MESHDIR_UNCAL="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_left/meshes"
|
||||
CALIB_XML="$G20_DIR/linker_hand_g20_left.xml"
|
||||
CALIB_URDF_PKG="$G20_DIR/linkerhand_g20_left.urdf"
|
||||
L20_TEMPLATE="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_left/linker_hand_l20v101_left.xml"
|
||||
STOCK_XML="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_left/linker_hand_l20v101_left.xml"
|
||||
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
# 回退到包内副本
|
||||
URDF_CALIBRATED="$CALIB_URDF_PKG"
|
||||
fi
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF template: $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$MESHDIR_UNCAL" ]]; then
|
||||
echo "[error] missing uncalibrated meshes: $MESHDIR_UNCAL" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$L20_TEMPLATE" ]]; then
|
||||
echo "[error] missing L20 V10.1 left MJCF template: $L20_TEMPLATE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[g20-left-dual] sync calibrated MJCF from G20 left URDF -> $CALIB_XML"
|
||||
python3 - "$URDF_CALIBRATED" "$MESHDIR_CALIB" "$CALIB_XML" "$CALIB_URDF_PKG" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
import numpy as np
|
||||
|
||||
urdf_cal = Path(sys.argv[1])
|
||||
meshdir_cal = Path(sys.argv[2])
|
||||
calib_xml = Path(sys.argv[3])
|
||||
calib_urdf_pkg = Path(sys.argv[4])
|
||||
|
||||
# 包内主副本 + tag 文件名副本
|
||||
shutil.copy2(urdf_cal, calib_urdf_pkg)
|
||||
shutil.copy2(urdf_cal, calib_urdf_pkg.parent / "linkerhand_g20_left_tag.urdf")
|
||||
|
||||
MCP_ROLL_JOINTS = (
|
||||
"index_mcp_roll",
|
||||
"middle_mcp_roll",
|
||||
"ring_mcp_roll",
|
||||
"pinky_mcp_roll",
|
||||
)
|
||||
BODY_FROM_JOINT = {
|
||||
"thumb_cmc_roll": "thumb_metacarpals_base1",
|
||||
"thumb_cmc_yaw": "thumb_metacarpals_base2",
|
||||
"thumb_cmc_pitch": "thumb_metacarpals",
|
||||
"thumb_mcp": "thumb_proximal",
|
||||
"thumb_ip": "thumb_distal",
|
||||
"index_mcp_roll": "index_metacarpals",
|
||||
"index_mcp_pitch": "index_proximal",
|
||||
"index_pip": "index_middle",
|
||||
"index_dip": "index_distal",
|
||||
"middle_mcp_roll": "middle_metacarpals",
|
||||
"middle_mcp_pitch": "middle_proximal",
|
||||
"middle_pip": "middle_middle",
|
||||
"middle_dip": "middle_distal",
|
||||
"ring_mcp_roll": "ring_metacarpals",
|
||||
"ring_mcp_pitch": "ring_proximal",
|
||||
"ring_pip": "ring_middle",
|
||||
"ring_dip": "ring_distal",
|
||||
"pinky_mcp_roll": "pinky_metacarpals",
|
||||
"pinky_mcp_pitch": "pinky_proximal",
|
||||
"pinky_pip": "pinky_middle",
|
||||
"pinky_dip": "pinky_distal",
|
||||
}
|
||||
|
||||
|
||||
def rpy_to_quat(roll, pitch, yaw):
|
||||
cr, sr = np.cos(roll / 2), np.sin(roll / 2)
|
||||
cp, sp = np.cos(pitch / 2), np.sin(pitch / 2)
|
||||
cy, sy = np.cos(yaw / 2), np.sin(yaw / 2)
|
||||
return np.array(
|
||||
[
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def parse_urdf(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
if "revolute" not in attrs:
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
# URDF 常写成 <axis\n xyz="..."/>,不能写死 "axis xyz="
|
||||
axis = re.search(r'<axis[^>]*xyz="([^"]+)"', body)
|
||||
xyz = [float(x) for x in origin.group(1).split()] if origin else [0.0, 0.0, 0.0]
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"xyz": xyz,
|
||||
"rpy": rpy,
|
||||
"axis": axis.group(1) if axis else "1 0 0",
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, joints: dict[str, dict]) -> str:
|
||||
xml = template
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
act_pat = rf'(<position name="{re.escape(jname)}_pos"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
act_pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
if jname in MCP_ROLL_JOINTS:
|
||||
ax = info["axis"].strip()
|
||||
ax_pat = rf'(<joint name="{re.escape(jname)}"[^>]*\saxis=")([^"]+)(")'
|
||||
xml = re.sub(ax_pat, lambda m, ax=ax: f"{m.group(1)}{ax}{m.group(3)}", xml, count=1)
|
||||
|
||||
# 同步零位 body pos/quat(拇指 CMC 等);保留原有 visual/collision geom 结构
|
||||
for jname, bname in BODY_FROM_JOINT.items():
|
||||
if jname not in joints:
|
||||
continue
|
||||
j = joints[jname]
|
||||
xyz, rpy = j["xyz"], j["rpy"]
|
||||
q = rpy_to_quat(*rpy)
|
||||
pos = f"{xyz[0]:g} {xyz[1]:g} {xyz[2]:g}"
|
||||
m = re.search(rf'<body name="{re.escape(bname)}"[^>]*>', xml)
|
||||
if not m:
|
||||
continue
|
||||
if np.allclose(q, [1, 0, 0, 0], atol=1e-9):
|
||||
new = f'<body name="{bname}" pos="{pos}">'
|
||||
else:
|
||||
quat = "{:.8g} {:.8g} {:.8g} {:.8g}".format(*q)
|
||||
new = f'<body name="{bname}" pos="{pos}" quat="{quat}">'
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
return xml
|
||||
|
||||
|
||||
joints = parse_urdf(urdf_cal)
|
||||
xml = apply_urdf_to_mjcf(calib_xml.read_text(), joints)
|
||||
calib_xml.write_text(xml)
|
||||
mujoco.MjModel.from_xml_path(str(calib_xml))
|
||||
|
||||
for j in MCP_ROLL_JOINTS:
|
||||
ax = re.search(rf'<joint name="{j}"[^>]*\saxis="([^"]+)"', calib_xml.read_text())
|
||||
print(f"[g20-left-dual] synced {j} axis={ax.group(1) if ax else '?'}")
|
||||
for j in ("thumb_cmc_roll", "thumb_cmc_yaw", "thumb_cmc_pitch"):
|
||||
info = joints[j]
|
||||
print(f"[g20-left-dual] {j} rpy={info['rpy']} lim=[{info['lo']}, {info['hi']}]")
|
||||
print(f"[g20-left-dual] calibrated URDF: {urdf_cal}")
|
||||
print(f"[g20-left-dual] calibrated MJCF: {calib_xml} (package template)")
|
||||
if meshdir_cal.is_dir():
|
||||
print(f"[g20-left-dual] calibrated meshes: {meshdir_cal}")
|
||||
PY
|
||||
|
||||
echo "[g20-left-dual] refresh uncalibrated L20 V10.1 left MJCF from $URDF_UNCALIBRATED"
|
||||
python3 - "$URDF_UNCALIBRATED" "$MESHDIR_UNCAL" "$L20_TEMPLATE" "$STOCK_XML" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
import numpy as np
|
||||
|
||||
urdf_path = Path(sys.argv[1])
|
||||
meshdir = Path(sys.argv[2])
|
||||
template_path = Path(sys.argv[3])
|
||||
out_path = Path(sys.argv[4])
|
||||
|
||||
|
||||
def rpy_to_quat(roll, pitch, yaw):
|
||||
cr, sr = np.cos(roll / 2), np.sin(roll / 2)
|
||||
cp, sp = np.cos(pitch / 2), np.sin(pitch / 2)
|
||||
cy, sy = np.cos(yaw / 2), np.sin(yaw / 2)
|
||||
return np.array([
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
])
|
||||
|
||||
|
||||
def parse_joints(path: Path) -> dict:
|
||||
text = path.read_text()
|
||||
joints = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name = re.search(r'name="([^"]+)"', attrs).group(1)
|
||||
jtype = re.search(r'type="([^"]+)"', attrs).group(1)
|
||||
if jtype != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
axis = re.search(r'<axis[^>]*xyz="([^"]+)"', body)
|
||||
joints[name] = {
|
||||
"xyz": tuple(map(float, origin.group(1).split())),
|
||||
"rpy": tuple(map(float, origin.group(2).split())),
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"axis": tuple(map(float, axis.group(1).split())),
|
||||
}
|
||||
if "thumb_dip" in joints and "thumb_ip" not in joints:
|
||||
joints["thumb_ip"] = dict(joints["thumb_dip"])
|
||||
return joints
|
||||
|
||||
|
||||
def fmt_axis(ax):
|
||||
return " ".join(f"{v:g}" for v in ax)
|
||||
|
||||
|
||||
def fmt_range(lo, hi):
|
||||
return f"{lo:g} {hi:g}"
|
||||
|
||||
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
mesh_out = out_path.parent / "meshes"
|
||||
mesh_out.mkdir(exist_ok=True)
|
||||
for f in meshdir.glob("*"):
|
||||
shutil.copy2(f, mesh_out / f.name)
|
||||
shutil.copy2(urdf_path, out_path.parent / urdf_path.name)
|
||||
|
||||
# 先读模板全文(out 可能与 template 同路径)
|
||||
xml = template_path.read_text()
|
||||
l20 = parse_joints(urdf_path)
|
||||
joint_specs = {n: (j["lo"], j["hi"], j["axis"]) for n, j in l20.items() if n != "thumb_dip"}
|
||||
|
||||
for name, (lo, hi, axis) in joint_specs.items():
|
||||
pat = re.compile(rf'<joint name="{re.escape(name)}"[^>]*>')
|
||||
m = pat.search(xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing joint {name}")
|
||||
new = (
|
||||
f'<joint name="{name}" pos="0 0 0" axis="{fmt_axis(axis)}" '
|
||||
f'range="{fmt_range(lo, hi)}" actuatorfrcrange="-100 100"/>'
|
||||
)
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
for name, (lo, hi, _) in joint_specs.items():
|
||||
pat = re.compile(
|
||||
rf'(<position name="{re.escape(name)}_pos"[^>]*\bctrlrange=")[^"]+(")'
|
||||
)
|
||||
if not pat.search(xml):
|
||||
raise SystemExit(f"missing actuator {name}_pos")
|
||||
xml = pat.sub(rf"\g<1>{lo:g} {hi:g}\2", xml, count=1)
|
||||
|
||||
body_from_joint = {
|
||||
"thumb_cmc_roll": "thumb_metacarpals_base1",
|
||||
"thumb_cmc_yaw": "thumb_metacarpals_base2",
|
||||
"thumb_cmc_pitch": "thumb_metacarpals",
|
||||
"thumb_mcp": "thumb_proximal",
|
||||
"thumb_ip": "thumb_distal",
|
||||
"index_mcp_roll": "index_metacarpals",
|
||||
"index_mcp_pitch": "index_proximal",
|
||||
"index_pip": "index_middle",
|
||||
"index_dip": "index_distal",
|
||||
"middle_mcp_roll": "middle_metacarpals",
|
||||
"middle_mcp_pitch": "middle_proximal",
|
||||
"middle_pip": "middle_middle",
|
||||
"middle_dip": "middle_distal",
|
||||
"ring_mcp_roll": "ring_metacarpals",
|
||||
"ring_mcp_pitch": "ring_proximal",
|
||||
"ring_pip": "ring_middle",
|
||||
"ring_dip": "ring_distal",
|
||||
"pinky_mcp_roll": "pinky_metacarpals",
|
||||
"pinky_mcp_pitch": "pinky_proximal",
|
||||
"pinky_pip": "pinky_middle",
|
||||
"pinky_dip": "pinky_distal",
|
||||
}
|
||||
|
||||
for jname, bname in body_from_joint.items():
|
||||
j = l20[jname]
|
||||
xyz = j["xyz"]
|
||||
rpy = j["rpy"]
|
||||
q = rpy_to_quat(*rpy)
|
||||
pos = f"{xyz[0]:g} {xyz[1]:g} {xyz[2]:g}"
|
||||
pat = re.compile(rf'<body name="{re.escape(bname)}"[^>]*>')
|
||||
m = pat.search(xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing body {bname}")
|
||||
if np.allclose(q, [1, 0, 0, 0], atol=1e-9):
|
||||
new = f'<body name="{bname}" pos="{pos}">'
|
||||
else:
|
||||
quat = "{:.6g} {:.6g} {:.6g} {:.6g}".format(*q)
|
||||
new = f'<body name="{bname}" pos="{pos}" quat="{quat}">'
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
out_path.write_text(xml)
|
||||
mujoco.MjModel.from_xml_path(str(out_path))
|
||||
print(f"[g20-left-dual] uncalibrated URDF: {urdf_path}")
|
||||
print(f"[g20-left-dual] uncalibrated meshes: {meshdir} -> {mesh_out}")
|
||||
print(f"[g20-left-dual] uncalibrated MJCF -> {out_path} (L20v101 left template + visual/collision split)")
|
||||
PY
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_G20:-}" ]] && kill "$PID_G20" 2>/dev/null || true
|
||||
[[ -n "${PID_L20:-}" ]] && kill "$PID_L20" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[g20-left-dual] G20 calibrated xml=$CALIB_XML"
|
||||
"$ROOT/hands/G20/scripts/run_g20_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name g20_calibrated_left \
|
||||
--window-title "G20 left 标定 (linkerhand_g20_left_tag)" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/g20/left/calibrated/joint_state \
|
||||
--mapping g20_calibrated \
|
||||
"${EXTRA[@]}" &
|
||||
PID_G20=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[g20-left-dual] L20 stock xml=$STOCK_XML (L20v101 left, URDF-native mapping)"
|
||||
"$ROOT/hands/G20/scripts/run_g20_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name l20_stock_left \
|
||||
--window-title "L20 V10.1 left 未标定" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l20/left/stock/joint_state \
|
||||
--mapping l20_urdf \
|
||||
"${EXTRA[@]}" &
|
||||
PID_L20=$!
|
||||
|
||||
echo "[g20-left-dual] both started. cmd topic: /cb_left_hand_control_cmd"
|
||||
echo "[g20-left-dual] mode: kinematic(运动学硬写;稳定跟 0~255)"
|
||||
echo "[g20-left-dual] 标定 mapping=g20_calibrated(主动线性,仅被动 JSON);未标定 mapping=l20_urdf + collision_project=on"
|
||||
echo "[g20-left-dual] 需要 PD+自碰: ./hands/G20/scripts/run_g20_left_dual_compare.sh --pd-drive"
|
||||
echo "[g20-left-dual] Ctrl+C stops both."
|
||||
wait "$PID_G20" "$PID_L20"
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# 左手四指侧摆方向检查:依次扫 SDK 通道 6~9(index/middle/ring/pinky mcp_roll)
|
||||
# 需先运行: ./hands/G20/scripts/run_g20_left_desktop_urdf.sh
|
||||
#
|
||||
# 预期(g20_urdf, URDF 轴 +X):
|
||||
# cmd=0 → 关节角为负(约 -0.23 rad,URDF lower)
|
||||
# cmd=255 → 关节角为正(约 +0.23 rad,URDF upper)
|
||||
# 若视觉与真机相反,说明 URDF 轴方向或映射仍不一致。
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
CMD_TOPIC="${CMD_TOPIC:-/cb_left_hand_control_cmd}"
|
||||
STATE_TOPIC="${STATE_TOPIC:-/sim/mujoco/g20/left/joint_state}"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_left_mcp_roll_check \
|
||||
--cmd-topic "$CMD_TOPIC" \
|
||||
--state-topic "$STATE_TOPIC" \
|
||||
"$@"
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo G20 左手仿真桥
|
||||
# 默认订阅 /cb_left_hand_control_cmd(0~255)
|
||||
# 发布 /sim/mujoco/g20/left/joint_state
|
||||
# 默认 1.35× 墙钟 + 关节限速;可用 --speed / --slew-rad-s 再调
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
# 源码优先(含 urdf 资产)
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_plan_bridge "$@"
|
||||
+337
@@ -0,0 +1,337 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:G20 右手标定 vs L20 原版 URDF(未标定)
|
||||
#
|
||||
# 标定: 包内 linker_hand_g20_right.xml(启动前从 linkerhand_G20_RIGHT_tag.urdf 仅 patch 限位/侧摆轴;保留 _col 碰撞体与 body quat)
|
||||
# 未标定: /home/lxqs/linkerhand_L20_V10 (2).1--0728/linkerhand_L20_V10.1_right.urdf → 运行时生成 *_stock.xml
|
||||
#
|
||||
# 默认运动学硬写(与 run_dual_mujoco_compare.sh / O6·L6 双开一致):稳定、跟 0~255 真机命令。
|
||||
# 需要 PD+自碰时手动加 --pd-drive(两窗均加)。
|
||||
#
|
||||
# 两个窗口共用 /cb_right_hand_control_cmd(20 维 0~255)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/G20/scripts/run_g20_right_dual_compare.sh
|
||||
# ./hands/G20/scripts/run_g20_right_dual_compare.sh --cmd-topic /cb_right_hand_control_cmd --speed 1.0
|
||||
# ./hands/G20/scripts/run_g20_right_dual_compare.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2"
|
||||
G20_DIR="$PKG_SRC/urdf/G20/linker_hand_g20_right"
|
||||
URDF_CALIBRATED="${G20_RIGHT_URDF:-$ROOT/hands/G20/reference/right_calibrated.urdf}"
|
||||
MESHDIR_CALIB="$G20_DIR/meshes"
|
||||
URDF_UNCALIBRATED="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_right/linkerhand_L20v10.1_right.urdf"
|
||||
MESHDIR_UNCAL="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_right/meshes"
|
||||
CALIB_XML="$G20_DIR/linker_hand_g20_right.xml"
|
||||
CALIB_URDF_PKG="$G20_DIR/linkerhand_g20_right.urdf"
|
||||
L20_TEMPLATE="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_left/linker_hand_l20v101_left.xml"
|
||||
STOCK_XML="$PKG_SRC/urdf/L20_V10.1/linker_hand_l20v101_right/linker_hand_l20v101_right.xml"
|
||||
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF template: $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$MESHDIR_UNCAL" ]]; then
|
||||
echo "[error] missing uncalibrated meshes: $MESHDIR_UNCAL" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$L20_TEMPLATE" ]]; then
|
||||
echo "[error] missing L20 V10.1 left MJCF template: $L20_TEMPLATE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[g20-right-dual] sync calibrated MJCF from G20_RIGHT_tag URDF -> $CALIB_XML"
|
||||
python3 - "$URDF_CALIBRATED" "$MESHDIR_CALIB" "$CALIB_XML" "$CALIB_URDF_PKG" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
|
||||
urdf_cal = Path(sys.argv[1])
|
||||
meshdir_cal = Path(sys.argv[2])
|
||||
calib_xml = Path(sys.argv[3])
|
||||
calib_urdf_pkg = Path(sys.argv[4])
|
||||
|
||||
# 包内留一份 Linkerbot URDF 副本,便于对照
|
||||
shutil.copy2(urdf_cal, calib_urdf_pkg)
|
||||
|
||||
# 只同步限位/轴;不要改 body quat(会破坏 MJCF 运动链,_col 与 visual 错位→对指穿模)
|
||||
|
||||
MCP_ROLL_JOINTS = (
|
||||
"index_mcp_roll",
|
||||
"middle_mcp_roll",
|
||||
"ring_mcp_roll",
|
||||
"pinky_mcp_roll",
|
||||
)
|
||||
|
||||
|
||||
def parse_urdf(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
if 'revolute' not in attrs:
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
# URDF 常写成 <axis\n xyz="..."/>,不能写死 "axis xyz="
|
||||
axis = re.search(r'<axis[^>]*xyz="([^"]+)"', body)
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"rpy": rpy,
|
||||
"axis": axis.group(1) if axis else "1 0 0",
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, joints: dict[str, dict]) -> str:
|
||||
xml = template
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
act_pat = rf'(<position name="{re.escape(jname)}_pos"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
act_pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
if jname in MCP_ROLL_JOINTS:
|
||||
ax = info["axis"].strip()
|
||||
ax_pat = rf'(<joint name="{re.escape(jname)}"[^>]*\saxis=")([^"]+)(")'
|
||||
xml = re.sub(ax_pat, lambda m, ax=ax: f"{m.group(1)}{ax}{m.group(3)}", xml, count=1)
|
||||
|
||||
return xml
|
||||
|
||||
|
||||
joints = parse_urdf(urdf_cal)
|
||||
xml = apply_urdf_to_mjcf(calib_xml.read_text(), joints)
|
||||
calib_xml.write_text(xml)
|
||||
mujoco.MjModel.from_xml_path(str(calib_xml))
|
||||
|
||||
for j in MCP_ROLL_JOINTS:
|
||||
ax = re.search(rf'<joint name="{j}"[^>]*\saxis="([^"]+)"', calib_xml.read_text())
|
||||
print(f"[g20-right-dual] synced {j} axis={ax.group(1) if ax else '?'}")
|
||||
print(f"[g20-right-dual] calibrated URDF: {urdf_cal}")
|
||||
print(f"[g20-right-dual] calibrated MJCF: {calib_xml} (package template + _col)")
|
||||
if meshdir_cal.is_dir():
|
||||
print(f"[g20-right-dual] calibrated meshes: {meshdir_cal} (package _col meshes)")
|
||||
PY
|
||||
|
||||
echo "[g20-right-dual] build uncalibrated L20 V10.1 right MJCF from template + $URDF_UNCALIBRATED"
|
||||
python3 - "$URDF_UNCALIBRATED" "$MESHDIR_UNCAL" "$L20_TEMPLATE" "$STOCK_XML" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
import numpy as np
|
||||
|
||||
urdf_path = Path(sys.argv[1])
|
||||
meshdir = Path(sys.argv[2])
|
||||
template_path = Path(sys.argv[3])
|
||||
out_path = Path(sys.argv[4])
|
||||
|
||||
|
||||
def rpy_to_quat(roll, pitch, yaw):
|
||||
cr, sr = np.cos(roll / 2), np.sin(roll / 2)
|
||||
cp, sp = np.cos(pitch / 2), np.sin(pitch / 2)
|
||||
cy, sy = np.cos(yaw / 2), np.sin(yaw / 2)
|
||||
return np.array([
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
])
|
||||
|
||||
|
||||
def parse_joints(path: Path) -> dict:
|
||||
text = path.read_text()
|
||||
joints = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name = re.search(r'name="([^"]+)"', attrs).group(1)
|
||||
jtype = re.search(r'type="([^"]+)"', attrs).group(1)
|
||||
if jtype != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
axis = re.search(r'<axis[^>]*xyz="([^"]+)"', body)
|
||||
joints[name] = {
|
||||
"xyz": tuple(map(float, origin.group(1).split())),
|
||||
"rpy": tuple(map(float, origin.group(2).split())),
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"axis": tuple(map(float, axis.group(1).split())),
|
||||
}
|
||||
if "thumb_dip" in joints and "thumb_ip" not in joints:
|
||||
joints["thumb_ip"] = dict(joints["thumb_dip"])
|
||||
return joints
|
||||
|
||||
|
||||
def fmt_axis(ax):
|
||||
return " ".join(f"{v:g}" for v in ax)
|
||||
|
||||
|
||||
def fmt_range(lo, hi):
|
||||
return f"{lo:g} {hi:g}"
|
||||
|
||||
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
mesh_out = out_path.parent / "meshes"
|
||||
mesh_out.mkdir(exist_ok=True)
|
||||
for f in meshdir.glob("*"):
|
||||
shutil.copy2(f, mesh_out / f.name)
|
||||
shutil.copy2(urdf_path, out_path.parent / urdf_path.name)
|
||||
|
||||
l20 = parse_joints(urdf_path)
|
||||
xml = template_path.read_text()
|
||||
xml = xml.replace('model="linker_hand_l20v101_left"', 'model="linker_hand_l20v101_right"')
|
||||
joint_specs = {n: (j["lo"], j["hi"], j["axis"]) for n, j in l20.items() if n != "thumb_dip"}
|
||||
|
||||
for name, (lo, hi, axis) in joint_specs.items():
|
||||
pat = re.compile(rf'<joint name="{re.escape(name)}"[^>]*>')
|
||||
m = pat.search(xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing joint {name}")
|
||||
new = (
|
||||
f'<joint name="{name}" pos="0 0 0" axis="{fmt_axis(axis)}" '
|
||||
f'range="{fmt_range(lo, hi)}" actuatorfrcrange="-100 100"/>'
|
||||
)
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
for name, (lo, hi, _) in joint_specs.items():
|
||||
pat = re.compile(
|
||||
rf'(<position name="{re.escape(name)}_pos"[^>]*\bctrlrange=")[^"]+(")'
|
||||
)
|
||||
if not pat.search(xml):
|
||||
raise SystemExit(f"missing actuator {name}_pos")
|
||||
xml = pat.sub(rf"\g<1>{lo:g} {hi:g}\2", xml, count=1)
|
||||
|
||||
body_from_joint = {
|
||||
"thumb_cmc_roll": "thumb_metacarpals_base1",
|
||||
"thumb_cmc_yaw": "thumb_metacarpals_base2",
|
||||
"thumb_cmc_pitch": "thumb_metacarpals",
|
||||
"thumb_mcp": "thumb_proximal",
|
||||
"thumb_ip": "thumb_distal",
|
||||
"index_mcp_roll": "index_metacarpals",
|
||||
"index_mcp_pitch": "index_proximal",
|
||||
"index_pip": "index_middle",
|
||||
"index_dip": "index_distal",
|
||||
"middle_mcp_roll": "middle_metacarpals",
|
||||
"middle_mcp_pitch": "middle_proximal",
|
||||
"middle_pip": "middle_middle",
|
||||
"middle_dip": "middle_distal",
|
||||
"ring_mcp_roll": "ring_metacarpals",
|
||||
"ring_mcp_pitch": "ring_proximal",
|
||||
"ring_pip": "ring_middle",
|
||||
"ring_dip": "ring_distal",
|
||||
"pinky_mcp_roll": "pinky_metacarpals",
|
||||
"pinky_mcp_pitch": "pinky_proximal",
|
||||
"pinky_pip": "pinky_middle",
|
||||
"pinky_dip": "pinky_distal",
|
||||
}
|
||||
|
||||
for jname, bname in body_from_joint.items():
|
||||
j = l20[jname]
|
||||
xyz = j["xyz"]
|
||||
rpy = j["rpy"]
|
||||
q = rpy_to_quat(*rpy)
|
||||
pos = f"{xyz[0]:g} {xyz[1]:g} {xyz[2]:g}"
|
||||
pat = re.compile(rf'<body name="{re.escape(bname)}"[^>]*>')
|
||||
m = pat.search(xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing body {bname}")
|
||||
if np.allclose(q, [1, 0, 0, 0], atol=1e-9):
|
||||
new = f'<body name="{bname}" pos="{pos}">'
|
||||
else:
|
||||
quat = "{:.6g} {:.6g} {:.6g} {:.6g}".format(*q)
|
||||
new = f'<body name="{bname}" pos="{pos}" quat="{quat}">'
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
out_path.write_text(xml)
|
||||
mujoco.MjModel.from_xml_path(str(out_path))
|
||||
print(f"[g20-right-dual] uncalibrated URDF: {urdf_path}")
|
||||
print(f"[g20-right-dual] uncalibrated meshes: {meshdir} -> {mesh_out}")
|
||||
print(f"[g20-right-dual] uncalibrated MJCF -> {out_path} (L20v101 template + visual/collision split)")
|
||||
PY
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_G20:-}" ]] && kill "$PID_G20" 2>/dev/null || true
|
||||
[[ -n "${PID_L20:-}" ]] && kill "$PID_L20" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[g20-right-dual] G20 calibrated xml=$CALIB_XML"
|
||||
"$ROOT/hands/G20/scripts/run_g20_right_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name g20_calibrated_right \
|
||||
--window-title "G20 right 标定 (G20_RIGHT_tag)" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/g20/right/calibrated/joint_state \
|
||||
--mapping g20_urdf \
|
||||
"${EXTRA[@]}" &
|
||||
PID_G20=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[g20-right-dual] L20 stock xml=$STOCK_XML (L20v101 template, URDF-native mapping)"
|
||||
"$ROOT/hands/G20/scripts/run_g20_right_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name l20_stock_right \
|
||||
--window-title "L20 V10.1 right 未标定" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l20/right/stock/joint_state \
|
||||
--mapping l20_urdf \
|
||||
"${EXTRA[@]}" &
|
||||
PID_L20=$!
|
||||
|
||||
echo "[g20-right-dual] both started. cmd topic: /cb_right_hand_control_cmd"
|
||||
echo "[g20-right-dual] mode: kinematic(运动学硬写,与左手双开一致;稳定跟 0~255)"
|
||||
echo "[g20-right-dual] 标定 mapping=g20_urdf(仅按URDF,不查JSON);未标定 mapping=l20_urdf + collision_project=on"
|
||||
echo "[g20-right-dual] 需要 PD+自碰: ./hands/G20/scripts/run_g20_right_dual_compare.sh --pd-drive"
|
||||
echo "[g20-right-dual] Ctrl+C stops both."
|
||||
wait "$PID_G20" "$PID_L20"
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# G20 右手关节弧度监视 GUI(默认 6 位小数)
|
||||
# 订阅 /sim/mujoco/g20/right/joint_state
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_joint_monitor_gui \
|
||||
--topic /sim/mujoco/g20/right/joint_state \
|
||||
"$@"
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo G20 右手仿真桥
|
||||
# 默认订阅 /cb_right_hand_control_cmd(0~255,与真机 SDK 一致)
|
||||
# 发布 /sim/mujoco/g20/right/joint_state
|
||||
# 模型:urdf/G20/linker_hand_g20_right/linker_hand_g20_right.xml
|
||||
# 默认 1.35× 墙钟 + 关节限速;可用 --speed / --slew-rad-s 再调
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/G20/scripts/run_g20_right_mujoco_plan.sh
|
||||
# ./hands/G20/scripts/run_g20_right_mujoco_plan.sh --cmd-topic /g20/cb_right_hand_control_cmd
|
||||
# 监视关节(另开终端):
|
||||
# ./hands/G20/scripts/run_g20_right_joint_gui.sh
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
# 源码优先(含 urdf 资产)
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/G20/linker_hand_g20_right/linker_hand_g20_right.xml"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing G20 right MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[g20-right] xml=$XML"
|
||||
echo "[g20-right] model=G20_RIGHT_tag"
|
||||
echo "[g20-right] cmd-topic=/cb_right_hand_control_cmd (override with --cmd-topic)"
|
||||
echo "[g20-right] sim-state=/sim/mujoco/g20/right/joint_state"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.g20_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name g20_mujoco_plan_bridge_right \
|
||||
--window-title "G20 right" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/g20/right/joint_state \
|
||||
--nominal-topic /retarget/g20/right/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
@@ -0,0 +1,6 @@
|
||||
# L20_V10.1
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/L20_V10.1
|
||||
@@ -0,0 +1,10 @@
|
||||
# L6
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
- `compare_left.sh`
|
||||
- `compare_right.sh`
|
||||
- `run_left.sh`
|
||||
- `run_right.sh`
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/L6
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_l6_left_dual_compare.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_l6_right_dual_compare.sh" "$@"
|
||||
@@ -0,0 +1,956 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<robot
|
||||
name="linkerhand_l6v3.1_left">
|
||||
<!-- 手掌基座,作为整只手的根链接 -->
|
||||
<link
|
||||
name="lh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00199 -0.00091 0.058381"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.4185" />
|
||||
<inertia
|
||||
ixx="0.0004998"
|
||||
ixy="0.000012853"
|
||||
ixz="-0.000008317"
|
||||
iyy="0.0003567"
|
||||
iyz="0.000010354"
|
||||
izz="0.0002301" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_metacarpals_base1">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0018663 -0.0066406 0.001533"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.01" />
|
||||
<inertia
|
||||
ixx="3.3724E-07"
|
||||
ixy="1.11E-07"
|
||||
ixz="-3.6039E-08"
|
||||
iyy="2.9457E-07"
|
||||
iyz="5.7181E-08"
|
||||
izz="4.903E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_roll"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0078133 -0.029898 0.026692"
|
||||
rpy="-0.0349060486431202 -0.000257767554592503 -0.00738147635662772" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals_base1" />
|
||||
<axis
|
||||
xyz="0 0 1" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.12177324"
|
||||
effort="0.588"
|
||||
velocity="5.95" />
|
||||
<dynamics damping="0.02" friction="0.05416667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00769270907060086 0.0859662184722988 0.0235283086675235"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.065" />
|
||||
<inertia
|
||||
ixx="8.407E-06"
|
||||
ixy="-1.1338E-09"
|
||||
ixz="1.1136E-08"
|
||||
iyy="8.3899E-06"
|
||||
iyz="3.1171E-07"
|
||||
izz="2.0091E-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0057298 -0.01332 0.0027456"
|
||||
rpy="1.01778644 0 0.40143" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals_base1" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="-1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.65673088"
|
||||
effort="1.008"
|
||||
velocity="3.47" />
|
||||
<dynamics damping="0.02" friction="0.0375"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00769270907081708 0.0798662184721594 -0.0591716913325555"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018" />
|
||||
<inertia
|
||||
ixx="1.5546E-06"
|
||||
ixy="2.4423E-09"
|
||||
ixz="2.8147E-09"
|
||||
iyy="1.7108E-06"
|
||||
iyz="-7.2756E-08"
|
||||
izz="9.1709E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0 0.0035 0.026"
|
||||
rpy="0 0 1.5708" />
|
||||
<parent
|
||||
link="lh_thumb_distal" />
|
||||
<child
|
||||
link="lh_thumb_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_thumb_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0 0.0061 0.0827"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals" />
|
||||
<child
|
||||
link="lh_thumb_distal" />
|
||||
<axis
|
||||
xyz="-1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.963287"
|
||||
effort="0"
|
||||
velocity="1.7" />
|
||||
<mimic
|
||||
joint="lh_thumb_cmc_pitch"
|
||||
multiplier="0.88524192477979"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 -0.028967 0.11722"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.04"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_index_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_distal" />
|
||||
<child
|
||||
link="lh_index_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_proximal" />
|
||||
<child
|
||||
link="lh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_index_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 -0.0089013 0.12322"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02708333"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_middle_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_distal" />
|
||||
<child
|
||||
link="lh_middle_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_proximal" />
|
||||
<child
|
||||
link="lh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_middle_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067368 0.010717 0.11822"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02291667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_ring_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_distal" />
|
||||
<child
|
||||
link="lh_ring_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_proximal" />
|
||||
<child
|
||||
link="lh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_ring_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067852 0.029814 0.11424"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.01"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_pinky_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_distal" />
|
||||
<child
|
||||
link="lh_pinky_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_proximal" />
|
||||
<child
|
||||
link="lh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_pinky_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<transmission name="trans_thumb_cmc_roll">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0084</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_index_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_middle_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_ring_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_pinky_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_thumb_cmc_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0144</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<mujoco>
|
||||
<compiler meshdir="meshes/" balanceinertia="true" discardvisual="false"/>
|
||||
<default>
|
||||
<joint armature="3.4707e-08" damping="5.0" frictionloss="0.5"/>
|
||||
</default>
|
||||
<equality>
|
||||
<!-- 四指DIP关节的mimic约束 - 统一使用1.125676 -->
|
||||
<!-- polycoef格式: c0 c1 c2 c3 c4 c5,关系: q1 = c0 + c1*q2 + c2*q2^2 + ... -->
|
||||
<!-- 对于 mimic: q_dip = 0 + 1.125676*q_mcp + 0*q_mcp^2 + ... -->
|
||||
<joint name="lh_couple_index" joint1="lh_index_dip" joint2="lh_index_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="lh_couple_middle" joint1="lh_middle_dip" joint2="lh_middle_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="lh_couple_ring" joint1="lh_ring_dip" joint2="lh_ring_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="lh_couple_pinky" joint1="lh_pinky_dip" joint2="lh_pinky_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<!-- 大拇指DIP关节的mimic约束 - 使用1.226495 -->
|
||||
<joint name="lh_couple_thumb" joint1="lh_thumb_dip" joint2="lh_thumb_cmc_pitch" polycoef="0 0.88524192477979 0 0 0 0"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
<gazebo reference="lh_hand_base_link">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_thumb_distal">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_index_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_middle_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_ring_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_pinky_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
</robot>
|
||||
@@ -0,0 +1,956 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<robot
|
||||
name="linkerhand_l6v3.1_left">
|
||||
<!-- 手掌基座,作为整只手的根链接 -->
|
||||
<link
|
||||
name="lh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00199 -0.00091 0.058381"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.4185" />
|
||||
<inertia
|
||||
ixx="0.0004998"
|
||||
ixy="0.000012853"
|
||||
ixz="-0.000008317"
|
||||
iyy="0.0003567"
|
||||
iyz="0.000010354"
|
||||
izz="0.0002301" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_metacarpals_base1">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0018663 -0.0066406 0.001533"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.01" />
|
||||
<inertia
|
||||
ixx="3.3724E-07"
|
||||
ixy="1.11E-07"
|
||||
ixz="-3.6039E-08"
|
||||
iyy="2.9457E-07"
|
||||
iyz="5.7181E-08"
|
||||
izz="4.903E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_roll"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0078133 -0.029898 0.026692"
|
||||
rpy="-0.034907 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals_base1" />
|
||||
<axis
|
||||
xyz="0 0 1" />
|
||||
<limit
|
||||
lower="-0.087266"
|
||||
upper="1.256637"
|
||||
effort="0.588"
|
||||
velocity="5.95" />
|
||||
<dynamics damping="0.02" friction="0.05416667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00769270907060086 0.0859662184722988 0.0235283086675235"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.065" />
|
||||
<inertia
|
||||
ixx="8.407E-06"
|
||||
ixy="-1.1338E-09"
|
||||
ixz="1.1136E-08"
|
||||
iyy="8.3899E-06"
|
||||
iyz="3.1171E-07"
|
||||
izz="2.0091E-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0057298 -0.01332 0.0027456"
|
||||
rpy="1.1083 0 0.40143" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals_base1" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="-1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.837758"
|
||||
effort="1.008"
|
||||
velocity="3.47" />
|
||||
<dynamics damping="0.02" friction="0.0375"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00769270907081708 0.0798662184721594 -0.0591716913325555"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018" />
|
||||
<inertia
|
||||
ixx="1.5546E-06"
|
||||
ixy="2.4423E-09"
|
||||
ixz="2.8147E-09"
|
||||
iyy="1.7108E-06"
|
||||
iyz="-7.2756E-08"
|
||||
izz="9.1709E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0 0.0035 0.026"
|
||||
rpy="0 0 1.5708" />
|
||||
<parent
|
||||
link="lh_thumb_distal" />
|
||||
<child
|
||||
link="lh_thumb_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_thumb_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0 0.0061 0.0827"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals" />
|
||||
<child
|
||||
link="lh_thumb_distal" />
|
||||
<axis
|
||||
xyz="-1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.963287"
|
||||
effort="0"
|
||||
velocity="1.7" />
|
||||
<mimic
|
||||
joint="lh_thumb_cmc_pitch"
|
||||
multiplier="1.226495"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 -0.028967 0.11722"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.04"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_index_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_distal" />
|
||||
<child
|
||||
link="lh_index_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_proximal" />
|
||||
<child
|
||||
link="lh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_index_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 -0.0089013 0.12322"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02708333"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_middle_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_distal" />
|
||||
<child
|
||||
link="lh_middle_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_proximal" />
|
||||
<child
|
||||
link="lh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_middle_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067368 0.010717 0.11822"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02291667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_ring_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_distal" />
|
||||
<child
|
||||
link="lh_ring_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_proximal" />
|
||||
<child
|
||||
link="lh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_ring_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.001776 -0.00011 0.012556"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="0.000000797543"
|
||||
ixy="-0.000000001275"
|
||||
ixz="0.000000138601"
|
||||
iyy="0.000000800499"
|
||||
iyz="0.000000000939"
|
||||
izz="0.000000357001" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067852 0.029814 0.11424"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.01"/>
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134 0.002262 0.016992"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="0.000002488712"
|
||||
ixy="0.000000008249"
|
||||
ixz="-0.000001523059"
|
||||
iyy="0.000003723754"
|
||||
iyz="0.000000014019"
|
||||
izz="0.000001813582" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_pinky_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_distal" />
|
||||
<child
|
||||
link="lh_pinky_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="lh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00093749 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_proximal" />
|
||||
<child
|
||||
link="lh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="lh_pinky_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<transmission name="trans_thumb_cmc_roll">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0084</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_index_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_middle_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_ring_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_pinky_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_thumb_cmc_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="lh_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0144</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<mujoco>
|
||||
<compiler meshdir="meshes/" balanceinertia="true" discardvisual="false"/>
|
||||
<default>
|
||||
<joint armature="3.4707e-08" damping="5.0" frictionloss="0.5"/>
|
||||
</default>
|
||||
<equality>
|
||||
<!-- 四指DIP关节的mimic约束 - 统一使用1.125676 -->
|
||||
<!-- polycoef格式: c0 c1 c2 c3 c4 c5,关系: q1 = c0 + c1*q2 + c2*q2^2 + ... -->
|
||||
<!-- 对于 mimic: q_dip = 0 + 1.125676*q_mcp + 0*q_mcp^2 + ... -->
|
||||
<joint name="lh_couple_index" joint1="lh_index_dip" joint2="lh_index_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="lh_couple_middle" joint1="lh_middle_dip" joint2="lh_middle_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="lh_couple_ring" joint1="lh_ring_dip" joint2="lh_ring_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="lh_couple_pinky" joint1="lh_pinky_dip" joint2="lh_pinky_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<!-- 大拇指DIP关节的mimic约束 - 使用1.226495 -->
|
||||
<joint name="lh_couple_thumb" joint1="lh_thumb_dip" joint2="lh_thumb_cmc_pitch" polycoef="0 1.226495 0 0 0 0"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
<gazebo reference="lh_hand_base_link">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_thumb_distal">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_index_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_middle_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_ring_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="lh_pinky_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
</robot>
|
||||
@@ -0,0 +1,953 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<robot
|
||||
name="linkerhand_l6v3.1_right">
|
||||
<!-- 手掌基座,作为整只手的根链接 -->
|
||||
<link
|
||||
name="rh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0019900000 0.0009100000 0.0583810000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.4185" />
|
||||
<inertia
|
||||
ixx="0.0004998"
|
||||
ixy="-1.2853e-05"
|
||||
ixz="-8.317e-06"
|
||||
iyy="0.0003567"
|
||||
iyz="-1.0354e-05"
|
||||
izz="0.0002301" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_metacarpals_base1">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0018663000 0.0066406000 0.0015330000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.01" />
|
||||
<inertia
|
||||
ixx="3.3724e-07"
|
||||
ixy="-1.11e-07"
|
||||
ixz="-3.6039e-08"
|
||||
iyy="2.9457e-07"
|
||||
iyz="-5.7181e-08"
|
||||
izz="4.903e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_roll"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0078133 0.030812 0.025678"
|
||||
rpy="-0.0349069999759288 6.51804876738993e-09 0.00738597563689764" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals_base1" />
|
||||
<axis
|
||||
xyz="0 0.034899 -0.99939" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.12177324"
|
||||
effort="0.588"
|
||||
velocity="5.95" />
|
||||
<dynamics damping="0.02" friction="0.05416667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0076927091 -0.0859662185 0.0235283087"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.065" />
|
||||
<inertia
|
||||
ixx="8.407e-06"
|
||||
ixy="1.1338e-09"
|
||||
ixz="1.1136e-08"
|
||||
iyy="8.3899e-06"
|
||||
iyz="-3.1171e-07"
|
||||
izz="2.0091e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0054997 0.013314 0.0032166"
|
||||
rpy="-0.98568644 0.0136370000000001 -0.40121" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals_base1" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.65673088"
|
||||
effort="1.008"
|
||||
velocity="3.47" />
|
||||
<dynamics damping="0.02" friction="0.0375"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0076927091 -0.0798662185 -0.0591716913"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018" />
|
||||
<inertia
|
||||
ixx="1.5546e-06"
|
||||
ixy="-2.4423e-09"
|
||||
ixz="2.8147e-09"
|
||||
iyy="1.7108e-06"
|
||||
iyz="7.2756e-08"
|
||||
izz="9.1709e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0 -0.0035 0.026"
|
||||
rpy="0 0 -1.5708" />
|
||||
<parent
|
||||
link="rh_thumb_distal" />
|
||||
<child
|
||||
link="rh_thumb_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_thumb_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0 -0.0061 0.0827"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals" />
|
||||
<child
|
||||
link="rh_thumb_distal" />
|
||||
<axis
|
||||
xyz="1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.963287"
|
||||
effort="0"
|
||||
velocity="1.7" />
|
||||
<mimic
|
||||
joint="rh_thumb_cmc_pitch"
|
||||
multiplier="0.88524192477979"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 0.033467 0.11622"
|
||||
rpy="-0.087266 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.04"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_index_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_distal" />
|
||||
<child
|
||||
link="rh_index_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_proximal" />
|
||||
<child
|
||||
link="rh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_index_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 0.0134013 0.12272"
|
||||
rpy="-0.034907 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02708333"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_middle_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_distal" />
|
||||
<child
|
||||
link="rh_middle_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_proximal" />
|
||||
<child
|
||||
link="rh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_middle_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067368 -0.006217 0.11872"
|
||||
rpy="0.017453 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02291667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_ring_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_distal" />
|
||||
<child
|
||||
link="rh_ring_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_proximal" />
|
||||
<child
|
||||
link="rh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_ring_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067852 -0.025314 0.11474"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.23208487"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.01"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_pinky_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_distal" />
|
||||
<child
|
||||
link="rh_pinky_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_proximal" />
|
||||
<child
|
||||
link="rh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_pinky_mcp_pitch"
|
||||
multiplier="0.923280528556446"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<transmission name="trans_thumb_cmc_roll">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0084</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_index_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_middle_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_ring_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_pinky_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_thumb_cmc_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0144</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<mujoco>
|
||||
<compiler meshdir="meshes/" balanceinertia="true" discardvisual="false"/>
|
||||
<default>
|
||||
<joint armature="3.4707e-08" damping="5.0" frictionloss="0.5"/>
|
||||
</default>
|
||||
<equality>
|
||||
<joint name="rh_couple_index" joint1="rh_index_dip" joint2="rh_index_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="rh_couple_middle" joint1="rh_middle_dip" joint2="rh_middle_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="rh_couple_ring" joint1="rh_ring_dip" joint2="rh_ring_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="rh_couple_pinky" joint1="rh_pinky_dip" joint2="rh_pinky_mcp_pitch" polycoef="0 1.17646620703189 -0.184902818001199 0 0 0"/>
|
||||
<joint name="rh_couple_thumb" joint1="rh_thumb_dip" joint2="rh_thumb_cmc_pitch" polycoef="0 0.88524192477979 0 0 0 0"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
<gazebo reference="rh_hand_base_link">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_thumb_distal">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_index_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_middle_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_ring_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_pinky_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
</robot>
|
||||
@@ -0,0 +1,953 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<robot
|
||||
name="linkerhand_l6v3.1_right">
|
||||
<!-- 手掌基座,作为整只手的根链接 -->
|
||||
<link
|
||||
name="rh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0019900000 0.0009100000 0.0583810000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.4185" />
|
||||
<inertia
|
||||
ixx="0.0004998"
|
||||
ixy="-1.2853e-05"
|
||||
ixz="-8.317e-06"
|
||||
iyy="0.0003567"
|
||||
iyz="-1.0354e-05"
|
||||
izz="0.0002301" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_metacarpals_base1">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0018663000 0.0066406000 0.0015330000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.01" />
|
||||
<inertia
|
||||
ixx="3.3724e-07"
|
||||
ixy="-1.11e-07"
|
||||
ixz="-3.6039e-08"
|
||||
iyy="2.9457e-07"
|
||||
iyz="-5.7181e-08"
|
||||
izz="4.903e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base1.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_roll"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0078133 0.030812 0.025678"
|
||||
rpy="-0.034907 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals_base1" />
|
||||
<axis
|
||||
xyz="0 0.034899 -0.99939" />
|
||||
<limit
|
||||
lower="-0.087266"
|
||||
upper="1.256637"
|
||||
effort="0.588"
|
||||
velocity="5.95" />
|
||||
<dynamics damping="0.02" friction="0.05416667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0076927091 -0.0859662185 0.0235283087"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.065" />
|
||||
<inertia
|
||||
ixx="8.407e-06"
|
||||
ixy="1.1338e-09"
|
||||
ixz="1.1136e-08"
|
||||
iyy="8.3899e-06"
|
||||
iyz="-3.1171e-07"
|
||||
izz="2.0091e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0054997 0.013314 0.0032166"
|
||||
rpy="-1.0762 0.013637 -0.40121" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals_base1" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.837758"
|
||||
effort="1.008"
|
||||
velocity="3.47" />
|
||||
<dynamics damping="0.02" friction="0.0375"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0076927091 -0.0798662185 -0.0591716913"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018" />
|
||||
<inertia
|
||||
ixx="1.5546e-06"
|
||||
ixy="-2.4423e-09"
|
||||
ixz="2.8147e-09"
|
||||
iyy="1.7108e-06"
|
||||
iyz="7.2756e-08"
|
||||
izz="9.1709e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0 -0.0035 0.026"
|
||||
rpy="0 0 -1.5708" />
|
||||
<parent
|
||||
link="rh_thumb_distal" />
|
||||
<child
|
||||
link="rh_thumb_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_thumb_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0 -0.0061 0.0827"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals" />
|
||||
<child
|
||||
link="rh_thumb_distal" />
|
||||
<axis
|
||||
xyz="1 0 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.963287"
|
||||
effort="0"
|
||||
velocity="1.7" />
|
||||
<mimic
|
||||
joint="rh_thumb_cmc_pitch"
|
||||
multiplier="1.226495"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 0.033467 0.11622"
|
||||
rpy="-0.087266 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.04"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_index_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_distal" />
|
||||
<child
|
||||
link="rh_index_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_proximal" />
|
||||
<child
|
||||
link="rh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_index_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00066821 0.0134013 0.12272"
|
||||
rpy="-0.034907 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02708333"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_middle_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_distal" />
|
||||
<child
|
||||
link="rh_middle_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_proximal" />
|
||||
<child
|
||||
link="rh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_middle_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067368 -0.006217 0.11872"
|
||||
rpy="0.017453 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.02291667"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_ring_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_distal" />
|
||||
<child
|
||||
link="rh_ring_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_proximal" />
|
||||
<child
|
||||
link="rh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_ring_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0017760000 0.0001100000 0.0125560000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.008553" />
|
||||
<inertia
|
||||
ixx="7.97543e-07"
|
||||
ixy="1.275e-09"
|
||||
ixz="1.38601e-07"
|
||||
iyy="8.00499e-07"
|
||||
iyz="-9.39e-10"
|
||||
izz="3.57001e-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.00067852 -0.025314 0.11474"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.134464"
|
||||
effort="0.574"
|
||||
velocity="6.10" />
|
||||
<dynamics damping="0.01" friction="0.01"/>
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.0134000000 -0.0022620000 0.0169920000"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.018408" />
|
||||
<inertia
|
||||
ixx="2.488712e-06"
|
||||
ixy="-8.249e-09"
|
||||
ixz="-1.523059e-06"
|
||||
iyy="3.723754e-06"
|
||||
iyz="-1.4019e-08"
|
||||
izz="1.813582e-06" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material
|
||||
name="">
|
||||
<color
|
||||
rgba="0.796078431372549 0.823529411764706 0.937254901960784 1" />
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_pinky_tip">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="1e-06" />
|
||||
<inertia
|
||||
ixx="1e-09"
|
||||
ixy="0"
|
||||
ixz="0"
|
||||
iyy="1e-09"
|
||||
iyz="0"
|
||||
izz="1e-09" />
|
||||
</inertial>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_tip_fixed"
|
||||
type="fixed">
|
||||
<origin
|
||||
xyz="0.0341 0 0.034"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_distal" />
|
||||
<child
|
||||
link="rh_pinky_tip" />
|
||||
</joint>
|
||||
<joint
|
||||
name="rh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0009359 0 0.028002"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_proximal" />
|
||||
<child
|
||||
link="rh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.277039"
|
||||
effort="0"
|
||||
velocity="3.1" />
|
||||
<mimic
|
||||
joint="rh_pinky_mcp_pitch"
|
||||
multiplier="1.125676"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<transmission name="trans_thumb_cmc_roll">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_roll">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0084</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_index_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_index_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_middle_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_middle_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_ring_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_ring_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_pinky_mcp_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_pinky_mcp_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0082</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<transmission name="trans_thumb_cmc_pitch">
|
||||
<type>transmission_interface/SimpleTransmission</type>
|
||||
<joint name="rh_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
</joint>
|
||||
<actuator name="motor_thumb_cmc_pitch">
|
||||
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
|
||||
<mechanicalReduction>0.0144</mechanicalReduction>
|
||||
</actuator>
|
||||
</transmission>
|
||||
<mujoco>
|
||||
<compiler meshdir="meshes/" balanceinertia="true" discardvisual="false"/>
|
||||
<default>
|
||||
<joint armature="3.4707e-08" damping="5.0" frictionloss="0.5"/>
|
||||
</default>
|
||||
<equality>
|
||||
<joint name="rh_couple_index" joint1="rh_index_dip" joint2="rh_index_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="rh_couple_middle" joint1="rh_middle_dip" joint2="rh_middle_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="rh_couple_ring" joint1="rh_ring_dip" joint2="rh_ring_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="rh_couple_pinky" joint1="rh_pinky_dip" joint2="rh_pinky_mcp_pitch" polycoef="0 1.125676 0 0 0 0"/>
|
||||
<joint name="rh_couple_thumb" joint1="rh_thumb_dip" joint2="rh_thumb_cmc_pitch" polycoef="0 1.226495 0 0 0 0"/>
|
||||
</equality>
|
||||
</mujoco>
|
||||
<gazebo reference="rh_hand_base_link">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_thumb_distal">
|
||||
<mu1>1.5</mu1>
|
||||
<mu2>1.5</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_index_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_middle_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_ring_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
<gazebo reference="rh_pinky_distal">
|
||||
<mu1>1.1</mu1>
|
||||
<mu2>1.1</mu2>
|
||||
<selfCollide>true</selfCollide>
|
||||
</gazebo>
|
||||
</robot>
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_l6_left_mujoco_plan.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_l6_right_mujoco_plan.sh" "$@"
|
||||
Executable
+216
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:L6 v3.1 左手标定 vs 未标定 URDF
|
||||
#
|
||||
# 未标定: /home/lxqs/linkerhand-urdf/l6/left
|
||||
# 标定: /home/lxqs/Linkerbot_URDF/L6/LEFT(直接用 linker_hand_l6v31_left.xml,与单开相同)
|
||||
#
|
||||
# 两个窗口共用同一条 6 维 SDK 控制话题(/cb_left_hand_control_cmd)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/L6/scripts/run_l6_left_dual_compare.sh
|
||||
# ./hands/L6/scripts/run_l6_left_dual_compare.sh --pd-drive
|
||||
# ./hands/L6/scripts/run_l6_left_dual_compare.sh --cmd-topic /cb_left_hand_control_cmd --speed 1.0
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_UNCALIBRATED="$ROOT/hands/L6/reference/left_uncalibrated.urdf"
|
||||
URDF_CALIBRATED="$ROOT/hands/L6/reference/left_calibrated.urdf"
|
||||
PKG_L6="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_left"
|
||||
CALIB_XML="$PKG_L6/linker_hand_l6v31_left.xml"
|
||||
STOCK_XML="$PKG_L6/linker_hand_l6v31_left_stock.xml"
|
||||
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF: $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[l6-left-dual] calibrated xml=$CALIB_XML (same as single-run)"
|
||||
echo "[l6-left-dual] build uncalibrated MJCF from $URDF_UNCALIBRATED"
|
||||
python3 - "$CALIB_XML" "$URDF_UNCALIBRATED" "$STOCK_XML" <<'PY'
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
template_xml = Path(sys.argv[1])
|
||||
urdf_uncal = Path(sys.argv[2])
|
||||
out_uncal = Path(sys.argv[3])
|
||||
|
||||
joint_body = {
|
||||
"lh_thumb_cmc_roll": "lh_thumb_metacarpals_base1",
|
||||
"lh_thumb_cmc_pitch": "lh_thumb_metacarpals",
|
||||
}
|
||||
MESHDIR_UNCAL = "/home/lxqs/linkerhand-urdf/l6/left/meshes"
|
||||
|
||||
|
||||
def parse_urdf_limits(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
jtype_m = re.search(r'type="([^"]+)"', attrs)
|
||||
if not jtype_m or jtype_m.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"rpy": rpy,
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def rpy_to_quat(r: float, p: float, y: float) -> tuple[float, float, float, float]:
|
||||
cr, sr = math.cos(r * 0.5), math.sin(r * 0.5)
|
||||
cp, sp = math.cos(p * 0.5), math.sin(p * 0.5)
|
||||
cy, sy = math.cos(y * 0.5), math.sin(y * 0.5)
|
||||
w = cr * cp * cy + sr * sp * sy
|
||||
x = sr * cp * cy - cr * sp * sy
|
||||
yq = cr * sp * cy + sr * cp * sy
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
return w, x, yq, z
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, urdf_path: Path, model_name: str) -> str:
|
||||
joints = parse_urdf_limits(urdf_path)
|
||||
xml = template.replace(
|
||||
'model="linkerhand_l6v31_left"',
|
||||
f'model="{model_name}"',
|
||||
1,
|
||||
)
|
||||
xml = re.sub(
|
||||
r'(<compiler[^>]*meshdir=")[^"]+(")',
|
||||
rf"\1{MESHDIR_UNCAL}\2",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
r, p, y = info["rpy"]
|
||||
bname = joint_body.get(jname)
|
||||
if bname and abs(r) + abs(p) + abs(y) > 1e-9:
|
||||
w, x, yq, z = rpy_to_quat(r, p, y)
|
||||
quat = f"{w:.9f} {x:.9f} {yq:.9f} {z:.9f}"
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)(>)'
|
||||
|
||||
def add_quat(m, quat=quat):
|
||||
tag = m.group(1)
|
||||
if 'quat="' in tag:
|
||||
tag = re.sub(r'quat="[^"]+"', f'quat="{quat}"', tag, count=1)
|
||||
else:
|
||||
tag = tag + f' quat="{quat}"'
|
||||
return tag + m.group(2)
|
||||
|
||||
xml = re.sub(bpat, add_quat, xml, count=1)
|
||||
elif bname:
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)\squat="[^"]+"([^>]*>)'
|
||||
xml = re.sub(bpat, r"\1\2", xml, count=1)
|
||||
|
||||
act_map = {
|
||||
"lh_thumb_cmc_roll_pos": "lh_thumb_cmc_roll",
|
||||
"lh_thumb_cmc_pitch_pos": "lh_thumb_cmc_pitch",
|
||||
"lh_index_mcp_pitch_pos": "lh_index_mcp_pitch",
|
||||
"lh_middle_mcp_pitch_pos": "lh_middle_mcp_pitch",
|
||||
"lh_ring_mcp_pitch_pos": "lh_ring_mcp_pitch",
|
||||
"lh_pinky_mcp_pitch_pos": "lh_pinky_mcp_pitch",
|
||||
}
|
||||
for act, jname in act_map.items():
|
||||
lo, hi = joints[jname]["lo"], joints[jname]["hi"]
|
||||
pat = rf'(<position name="{act}"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
return xml
|
||||
|
||||
|
||||
import mujoco
|
||||
|
||||
out_uncal.write_text(
|
||||
apply_urdf_to_mjcf(template_xml.read_text(), urdf_uncal, "linkerhand_l6v31_left_uncalibrated")
|
||||
)
|
||||
mujoco.MjModel.from_xml_path(str(out_uncal))
|
||||
print(f"[l6-left-dual] uncalibrated URDF: {urdf_uncal}")
|
||||
print(f"[l6-left-dual] uncalibrated meshes: {MESHDIR_UNCAL}")
|
||||
print(f"[l6-left-dual] uncalibrated MJCF -> {out_uncal}")
|
||||
PY
|
||||
|
||||
echo "[l6-left-dual] calibrated URDF: $URDF_CALIBRATED"
|
||||
echo "[l6-left-dual] calibrated meshes: $PKG_L6/meshes (package, 标定安装)"
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_UNCAL:-}" ]] && kill "$PID_UNCAL" 2>/dev/null || true
|
||||
[[ -n "${PID_CALIB:-}" ]] && kill "$PID_CALIB" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[l6-left-dual] launch uncalibrated window"
|
||||
"$ROOT/hands/L6/scripts/run_l6_left_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name l6_left_uncalibrated \
|
||||
--window-title "L6 left 未标定 (linkerhand-urdf)" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/left/uncalibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_UNCAL=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[l6-left-dual] launch calibrated window"
|
||||
"$ROOT/hands/L6/scripts/run_l6_left_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name l6_left_calibrated \
|
||||
--window-title "L6 left 标定 (Linkerbot_URDF)" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/left/calibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_CALIB=$!
|
||||
|
||||
echo "[l6-left-dual] both started. cmd topic: /cb_left_hand_control_cmd"
|
||||
echo "[l6-left-dual] Ctrl+C stops both."
|
||||
wait "$PID_UNCAL" "$PID_CALIB"
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo L6 v3.1 左手仿真桥
|
||||
# URDF 来源: /home/lxqs/Linkerbot_URDF/L6/LEFT/linkerhand_l6v3.1_left_transferred_from_L6_RIGHT_001.urdf
|
||||
# 默认订阅 /l6/cb_left_hand_control_cmd(6 维 SDK 0~255)
|
||||
# 发布 /sim/mujoco/l6/left/joint_state
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/L6/scripts/run_l6_left_mujoco_plan.sh
|
||||
# ./hands/L6/scripts/run_l6_left_mujoco_plan.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_left/linker_hand_l6v31_left.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_left/linkerhand_l6_left.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing L6 left MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[l6-left] urdf=$URDF"
|
||||
echo "[l6-left] xml=$XML"
|
||||
echo "[l6-left] cmd-topic=/l6/cb_left_hand_control_cmd"
|
||||
echo "[l6-left] sim-state=/sim/mujoco/l6/left/joint_state"
|
||||
echo "[l6-left] SDK 6ch: pitch, roll, index, middle, ring, pinky"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.l6_left_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name l6_mujoco_plan_bridge_left \
|
||||
--window-title "L6 v3.1 left" \
|
||||
--cmd-topic /l6/cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/left/joint_state \
|
||||
--nominal-topic /retarget/l6/left/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:L6 v3.1 右手标定 vs 未标定 URDF
|
||||
#
|
||||
# 未标定: /home/lxqs/linkerhand-urdf/l6/right
|
||||
# 标定: /home/lxqs/Linkerbot_URDF/L6/RIGHT(直接用 linker_hand_l6v31_right.xml,与单开相同)
|
||||
#
|
||||
# 两个窗口共用同一条 6 维 SDK 控制话题(/cb_right_hand_control_cmd)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/L6/scripts/run_l6_right_dual_compare.sh
|
||||
# ./hands/L6/scripts/run_l6_right_dual_compare.sh --pd-drive
|
||||
# ./hands/L6/scripts/run_l6_right_dual_compare.sh --cmd-topic /cb_right_hand_control_cmd --speed 1.0
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_UNCALIBRATED="$ROOT/hands/L6/reference/right_uncalibrated.urdf"
|
||||
URDF_CALIBRATED="$ROOT/hands/L6/reference/right_calibrated.urdf"
|
||||
PKG_L6="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_right"
|
||||
CALIB_XML="$PKG_L6/linker_hand_l6v31_right.xml"
|
||||
STOCK_XML="$PKG_L6/linker_hand_l6v31_right_stock.xml"
|
||||
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF: $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[l6-right-dual] calibrated xml=$CALIB_XML (same as single-run)"
|
||||
echo "[l6-right-dual] build uncalibrated MJCF from $URDF_UNCALIBRATED"
|
||||
python3 - "$CALIB_XML" "$URDF_UNCALIBRATED" "$STOCK_XML" <<'PY'
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
template_xml = Path(sys.argv[1])
|
||||
urdf_uncal = Path(sys.argv[2])
|
||||
out_uncal = Path(sys.argv[3])
|
||||
|
||||
joint_body = {
|
||||
"rh_thumb_cmc_roll": "rh_thumb_metacarpals_base1",
|
||||
"rh_thumb_cmc_pitch": "rh_thumb_metacarpals",
|
||||
}
|
||||
MESHDIR_UNCAL = "/home/lxqs/linkerhand-urdf/l6/right/meshes"
|
||||
|
||||
|
||||
def parse_urdf_limits(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
jtype_m = re.search(r'type="([^"]+)"', attrs)
|
||||
if not jtype_m or jtype_m.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"rpy": rpy,
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def rpy_to_quat(r: float, p: float, y: float) -> tuple[float, float, float, float]:
|
||||
cr, sr = math.cos(r * 0.5), math.sin(r * 0.5)
|
||||
cp, sp = math.cos(p * 0.5), math.sin(p * 0.5)
|
||||
cy, sy = math.cos(y * 0.5), math.sin(y * 0.5)
|
||||
w = cr * cp * cy + sr * sp * sy
|
||||
x = sr * cp * cy - cr * sp * sy
|
||||
yq = cr * sp * cy + sr * cp * sy
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
return w, x, yq, z
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, urdf_path: Path, model_name: str) -> str:
|
||||
joints = parse_urdf_limits(urdf_path)
|
||||
xml = template.replace(
|
||||
'model="linkerhand_l6v31_right"',
|
||||
f'model="{model_name}"',
|
||||
1,
|
||||
)
|
||||
xml = re.sub(
|
||||
r'(<compiler[^>]*meshdir=")[^"]+(")',
|
||||
rf"\1{MESHDIR_UNCAL}\2",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
r, p, y = info["rpy"]
|
||||
bname = joint_body.get(jname)
|
||||
if bname and abs(r) + abs(p) + abs(y) > 1e-9:
|
||||
w, x, yq, z = rpy_to_quat(r, p, y)
|
||||
quat = f"{w:.9f} {x:.9f} {yq:.9f} {z:.9f}"
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)(>)'
|
||||
|
||||
def add_quat(m, quat=quat):
|
||||
tag = m.group(1)
|
||||
if 'quat="' in tag:
|
||||
tag = re.sub(r'quat="[^"]+"', f'quat="{quat}"', tag, count=1)
|
||||
else:
|
||||
tag = tag + f' quat="{quat}"'
|
||||
return tag + m.group(2)
|
||||
|
||||
xml = re.sub(bpat, add_quat, xml, count=1)
|
||||
elif bname:
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)\squat="[^"]+"([^>]*>)'
|
||||
xml = re.sub(bpat, r"\1\2", xml, count=1)
|
||||
|
||||
act_map = {
|
||||
"rh_thumb_cmc_roll_pos": "rh_thumb_cmc_roll",
|
||||
"rh_thumb_cmc_pitch_pos": "rh_thumb_cmc_pitch",
|
||||
"rh_index_mcp_pitch_pos": "rh_index_mcp_pitch",
|
||||
"rh_middle_mcp_pitch_pos": "rh_middle_mcp_pitch",
|
||||
"rh_ring_mcp_pitch_pos": "rh_ring_mcp_pitch",
|
||||
"rh_pinky_mcp_pitch_pos": "rh_pinky_mcp_pitch",
|
||||
}
|
||||
for act, jname in act_map.items():
|
||||
lo, hi = joints[jname]["lo"], joints[jname]["hi"]
|
||||
pat = rf'(<position name="{act}"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
return xml
|
||||
|
||||
|
||||
import mujoco
|
||||
|
||||
out_uncal.write_text(
|
||||
apply_urdf_to_mjcf(template_xml.read_text(), urdf_uncal, "linkerhand_l6v31_right_uncalibrated")
|
||||
)
|
||||
mujoco.MjModel.from_xml_path(str(out_uncal))
|
||||
print(f"[l6-right-dual] uncalibrated URDF: {urdf_uncal}")
|
||||
print(f"[l6-right-dual] uncalibrated meshes: {MESHDIR_UNCAL}")
|
||||
print(f"[l6-right-dual] uncalibrated MJCF -> {out_uncal}")
|
||||
PY
|
||||
|
||||
echo "[l6-right-dual] calibrated URDF: $URDF_CALIBRATED"
|
||||
echo "[l6-right-dual] calibrated meshes: $PKG_L6/meshes (package, 标定安装)"
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_UNCAL:-}" ]] && kill "$PID_UNCAL" 2>/dev/null || true
|
||||
[[ -n "${PID_CALIB:-}" ]] && kill "$PID_CALIB" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[l6-right-dual] launch uncalibrated window"
|
||||
"$ROOT/hands/L6/scripts/run_l6_right_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name l6_right_uncalibrated \
|
||||
--window-title "L6 right 未标定 (linkerhand-urdf)" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/right/uncalibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_UNCAL=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[l6-right-dual] launch calibrated window"
|
||||
"$ROOT/hands/L6/scripts/run_l6_right_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name l6_right_calibrated \
|
||||
--window-title "L6 right 标定 (Linkerbot_URDF)" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/right/calibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_CALIB=$!
|
||||
|
||||
echo "[l6-right-dual] both started. cmd topic: /cb_right_hand_control_cmd"
|
||||
echo "[l6-right-dual] Ctrl+C stops both."
|
||||
wait "$PID_UNCAL" "$PID_CALIB"
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo L6 v3.1 右手仿真桥
|
||||
# URDF 来源: /home/lxqs/下载/linkerhand_l6v3.1_right_partial_zero_calibrated_L6_RIGHT_001_20260902_142125.urdf
|
||||
# 默认订阅 /cb_right_hand_control_cmd(6 维 SDK 0~255)
|
||||
# 发布 /sim/mujoco/l6/right/joint_state
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/L6/scripts/run_l6_right_mujoco_plan.sh
|
||||
# ./hands/L6/scripts/run_l6_right_mujoco_plan.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_right/linker_hand_l6v31_right.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/L6/linker_hand_l6v31_right/linkerhand_l6_right.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing L6 MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[l6-right] urdf=$URDF"
|
||||
echo "[l6-right] xml=$XML"
|
||||
echo "[l6-right] cmd-topic=/cb_right_hand_control_cmd"
|
||||
echo "[l6-right] sim-state=/sim/mujoco/l6/right/joint_state"
|
||||
echo "[l6-right] SDK 6ch: pitch, roll, index, middle, ring, pinky"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.l6_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name l6_mujoco_plan_bridge_right \
|
||||
--window-title "L6 v3.1 right" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/l6/right/joint_state \
|
||||
--nominal-topic /retarget/l6/right/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
@@ -0,0 +1,8 @@
|
||||
# O12
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
- `compare_right.sh`
|
||||
- `run_right.sh`
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O12
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o12_right_dual_compare.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o12_right_mujoco_plan.sh" "$@"
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:O12 右手标定 vs 未标定 URDF
|
||||
#
|
||||
# 标定: /home/lxqs/Linkerbot_URDF/012/right/linkerhand_o12_right_biaoding.urdf
|
||||
# 未标定: /home/lxqs/Linkerbot_URDF/012/right/linkerhand_o12_right.urdf
|
||||
#
|
||||
# 启动前各自同步 MJCF(限位/轴/body 零位);两窗各自用对应 URDF 的限位+mimic 映射。
|
||||
# 共用 /o12/right/joint_cmd(12 路 SDK 弧度)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O12/scripts/run_o12_right_dual_compare.sh
|
||||
# ./hands/O12/scripts/run_o12_right_dual_compare.sh --no-pd-drive
|
||||
# ./hands/O12/scripts/run_o12_right_dual_compare.sh --pd-drive --slew-rad-s 4
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_DIR="${O12_RIGHT_URDF_DIR:-$ROOT/assets/vendor/Linkerbot_URDF/012/right}"
|
||||
URDF_CALIBRATED="${O12_RIGHT_URDF_CALIBRATED:-$URDF_DIR/linkerhand_o12_right_biaoding.urdf}"
|
||||
URDF_UNCALIBRATED="${O12_RIGHT_URDF_UNCALIBRATED:-$URDF_DIR/linkerhand_o12_right.urdf}"
|
||||
MESHDIR="${O12_RIGHT_MESHDIR:-$URDF_DIR/meshes}"
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2"
|
||||
O12_DIR="$PKG_SRC/urdf/O12/linker_hand_o12_right"
|
||||
TEMPLATE_XML="$O12_DIR/linker_hand_o12_right.xml"
|
||||
CALIB_XML="$O12_DIR/linker_hand_o12_right.xml"
|
||||
STOCK_XML="$O12_DIR/linker_hand_o12_right_stock.xml"
|
||||
CALIB_URDF_PKG="$O12_DIR/linkerhand_o12_right.urdf"
|
||||
STOCK_URDF_PKG="$O12_DIR/linkerhand_o12_right_stock.urdf"
|
||||
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$TEMPLATE_XML" ]]; then
|
||||
echo "[error] missing O12 MJCF template: $TEMPLATE_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$MESHDIR" ]]; then
|
||||
echo "[error] missing meshes: $MESHDIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o12-right-dual] sync calibrated + uncalibrated MJCF from Linkerbot_URDF"
|
||||
python3 - "$URDF_CALIBRATED" "$URDF_UNCALIBRATED" "$MESHDIR" "$TEMPLATE_XML" \
|
||||
"$CALIB_XML" "$STOCK_XML" "$CALIB_URDF_PKG" "$STOCK_URDF_PKG" <<'PY'
|
||||
import math
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
import numpy as np
|
||||
|
||||
urdf_cal = Path(sys.argv[1])
|
||||
urdf_unc = Path(sys.argv[2])
|
||||
meshdir = Path(sys.argv[3])
|
||||
template_xml = Path(sys.argv[4])
|
||||
calib_xml = Path(sys.argv[5])
|
||||
stock_xml = Path(sys.argv[6])
|
||||
calib_urdf_pkg = Path(sys.argv[7])
|
||||
stock_urdf_pkg = Path(sys.argv[8])
|
||||
|
||||
BODY_FROM_JOINT = {
|
||||
"thumb_cmc_roll": "thumb_metacarpals_base1",
|
||||
"thumb_cmc_yaw": "thumb_metacarpals_base2",
|
||||
"thumb_cmc_pitch": "thumb_metacarpals",
|
||||
"thumb_mcp": "thumb_proximal",
|
||||
"thumb_dip": "thumb_distal",
|
||||
"index_mcp_roll": "index_metacarpals",
|
||||
"index_mcp_pitch": "index_proximal",
|
||||
"index_pip": "index_middle",
|
||||
"index_dip": "index_distal",
|
||||
"middle_mcp_roll": "middle_metacarpals",
|
||||
"middle_mcp_pitch": "middle_proximal",
|
||||
"middle_pip": "middle_middle",
|
||||
"middle_dip": "middle_distal",
|
||||
"ring_mcp_pitch": "ring_proximal",
|
||||
"ring_pip": "ring_middle",
|
||||
"ring_dip": "ring_distal",
|
||||
"pinky_mcp_pitch": "pinky_proximal",
|
||||
"pinky_pip": "pinky_middle",
|
||||
"pinky_dip": "pinky_distal",
|
||||
}
|
||||
|
||||
|
||||
def rpy_to_quat(roll, pitch, yaw):
|
||||
cr, sr = np.cos(roll / 2), np.sin(roll / 2)
|
||||
cp, sp = np.cos(pitch / 2), np.sin(pitch / 2)
|
||||
cy, sy = np.cos(yaw / 2), np.sin(yaw / 2)
|
||||
return np.array(
|
||||
[
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def localize_urdf(src: Path, dst: Path) -> None:
|
||||
text = src.read_text()
|
||||
text = re.sub(r"package://[^/]+/meshes/", "meshes/", text)
|
||||
dst.write_text(text)
|
||||
|
||||
|
||||
def parse_urdf(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
if "revolute" not in attrs:
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
axis = re.search(r'<axis[^>]*xyz="([^"]+)"', body)
|
||||
xyz = [float(x) for x in origin.group(1).split()] if origin else [0.0, 0.0, 0.0]
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"xyz": xyz,
|
||||
"rpy": rpy,
|
||||
"axis": axis.group(1).strip() if axis else "0 0 1",
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, joints: dict[str, dict], model_name: str) -> str:
|
||||
xml = re.sub(
|
||||
r'model="[^"]+"',
|
||||
f'model="{model_name}"',
|
||||
template,
|
||||
count=1,
|
||||
)
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
ax = info["axis"]
|
||||
jpat = re.compile(rf'<joint name="{re.escape(jname)}"[^>]*/?>')
|
||||
m = jpat.search(xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing joint in MJCF: {jname}")
|
||||
attrs = m.group(0)
|
||||
# keep damping/frictionloss if present
|
||||
damp = re.search(r'\bdamping="[^"]+"', attrs)
|
||||
fric = re.search(r'\bfrictionloss="[^"]+"', attrs)
|
||||
extra = ""
|
||||
if damp:
|
||||
extra += f" {damp.group(0)}"
|
||||
if fric:
|
||||
extra += f" {fric.group(0)}"
|
||||
new = (
|
||||
f'<joint name="{jname}" pos="0 0 0" axis="{ax}" '
|
||||
f'range="{lo:g} {hi:g}"{extra}/>'
|
||||
)
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
|
||||
act_pat = re.compile(
|
||||
rf'(<position name="{re.escape(jname)}_pos"[^>]*\bctrlrange=")[^"]+(")'
|
||||
)
|
||||
if act_pat.search(xml):
|
||||
xml = act_pat.sub(rf"\g<1>{lo:g} {hi:g}\2", xml, count=1)
|
||||
|
||||
for jname, bname in BODY_FROM_JOINT.items():
|
||||
if jname not in joints:
|
||||
continue
|
||||
j = joints[jname]
|
||||
xyz, rpy = j["xyz"], j["rpy"]
|
||||
q = rpy_to_quat(*rpy)
|
||||
pos = f"{xyz[0]:g} {xyz[1]:g} {xyz[2]:g}"
|
||||
m = re.search(rf'<body name="{re.escape(bname)}"[^>]*>', xml)
|
||||
if not m:
|
||||
raise SystemExit(f"missing body in MJCF: {bname}")
|
||||
if np.allclose(q, [1, 0, 0, 0], atol=1e-9):
|
||||
new = f'<body name="{bname}" pos="{pos}">'
|
||||
else:
|
||||
quat = "{:.8g} {:.8g} {:.8g} {:.8g}".format(*q)
|
||||
new = f'<body name="{bname}" pos="{pos}" quat="{quat}">'
|
||||
xml = xml[: m.start()] + new + xml[m.end() :]
|
||||
return xml
|
||||
|
||||
|
||||
# meshes → 包内(两窗共用)
|
||||
mesh_out = calib_xml.parent / "meshes"
|
||||
mesh_out.mkdir(exist_ok=True)
|
||||
for f in meshdir.glob("*"):
|
||||
if f.is_file():
|
||||
shutil.copy2(f, mesh_out / f.name)
|
||||
|
||||
localize_urdf(urdf_cal, calib_urdf_pkg)
|
||||
localize_urdf(urdf_unc, stock_urdf_pkg)
|
||||
shutil.copy2(urdf_cal, calib_urdf_pkg.parent / "linkerhand_o12_right_biaoding.urdf")
|
||||
|
||||
template = template_xml.read_text()
|
||||
cal_joints = parse_urdf(urdf_cal)
|
||||
unc_joints = parse_urdf(urdf_unc)
|
||||
|
||||
calib_xml.write_text(
|
||||
apply_urdf_to_mjcf(template, cal_joints, "linkerhand_o12_right_calibrated")
|
||||
)
|
||||
stock_xml.write_text(
|
||||
apply_urdf_to_mjcf(template, unc_joints, "linkerhand_o12_right_uncalibrated")
|
||||
)
|
||||
mujoco.MjModel.from_xml_path(str(calib_xml))
|
||||
mujoco.MjModel.from_xml_path(str(stock_xml))
|
||||
|
||||
print(f"[o12-right-dual] calibrated URDF: {urdf_cal}")
|
||||
print(f"[o12-right-dual] calibrated MJCF: {calib_xml}")
|
||||
print(f"[o12-right-dual] uncalibrated URDF: {urdf_unc}")
|
||||
print(f"[o12-right-dual] uncalibrated MJCF: {stock_xml}")
|
||||
for j in ("thumb_cmc_roll", "thumb_cmc_yaw", "index_mcp_roll", "index_mcp_pitch"):
|
||||
c, u = cal_joints[j], unc_joints[j]
|
||||
print(
|
||||
f"[o12-right-dual] {j}: cal lim=[{c['lo']:g},{c['hi']:g}] rpy={c['rpy']} | "
|
||||
f"unc lim=[{u['lo']:g},{u['hi']:g}] rpy={u['rpy']}"
|
||||
)
|
||||
PY
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_CALIB:-}" ]] && kill "$PID_CALIB" 2>/dev/null || true
|
||||
[[ -n "${PID_UNCAL:-}" ]] && kill "$PID_UNCAL" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[o12-right-dual] launch calibrated window"
|
||||
"$ROOT/hands/O12/scripts/run_o12_right_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--o12-urdf "$URDF_CALIBRATED" \
|
||||
--node-name o12_right_calibrated \
|
||||
--window-title "O12 right 标定 (biaoding)" \
|
||||
--cmd-topic /o12/right/joint_cmd \
|
||||
--sim-state-topic /sim/mujoco/o12/right/calibrated/joint_states \
|
||||
"${EXTRA[@]}" &
|
||||
PID_CALIB=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[o12-right-dual] launch uncalibrated window"
|
||||
"$ROOT/hands/O12/scripts/run_o12_right_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--o12-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name o12_right_uncalibrated \
|
||||
--window-title "O12 right 未标定 (stock)" \
|
||||
--cmd-topic /o12/right/joint_cmd \
|
||||
--sim-state-topic /sim/mujoco/o12/right/uncalibrated/joint_states \
|
||||
"${EXTRA[@]}" &
|
||||
PID_UNCAL=$!
|
||||
|
||||
echo "[o12-right-dual] both started. shared cmd: /o12/right/joint_cmd (12 rad)"
|
||||
echo "[o12-right-dual] calibrated: $URDF_CALIBRATED"
|
||||
echo "[o12-right-dual] uncalibrated: $URDF_UNCALIBRATED"
|
||||
echo "[o12-right-dual] Ctrl+C stops both."
|
||||
wait "$PID_CALIB" "$PID_UNCAL"
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo O12 T3 右手仿真桥(OmniHand Pro 2025 ROS2 接口)
|
||||
# URDF 来源: /home/lxqs/下载/linkerhand_o12_t3_right-0703_calibrated_O12_RIGHT_001_REVIEW_ONLY_20260909_112041.urdf
|
||||
# (包内: urdf/O12/linker_hand_o12_right/linkerhand_o12_right.urdf)
|
||||
# 订阅 /o12/right/joint_cmd(12 路弧度)
|
||||
# 发布 /o12/right/joint_states(12 路弧度)
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O12/scripts/run_o12_right_mujoco_plan.sh # 默认 --pd-drive(可见接触力,按 F)
|
||||
# ./hands/O12/scripts/run_o12_right_mujoco_plan.sh --no-pd-drive # 纯 kinematic,最稳
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O12/linker_hand_o12_right/linker_hand_o12_right.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O12/linker_hand_o12_right/linkerhand_o12_right.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing O12 MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[o12-right] urdf=$URDF"
|
||||
echo "[o12-right] xml=$XML"
|
||||
echo "[o12-right] cmd-topic=/o12/right/joint_cmd (12 rad)"
|
||||
echo "[o12-right] state-topic=/o12/right/joint_states (12 rad)"
|
||||
echo "[o12-right] default mode=pd-drive (viewer 按 F 看接触力; 默认 slew=4 rad/s 防穿模)"
|
||||
echo "[o12-right] order (API_CPP_O12): thumb_roll,yaw,pitch,mcp,idx_roll,idx_pitch,idx_pip,mid_roll,mid_pitch,mid_pip,ring,pinky"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.o12_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name o12_mujoco_plan_bridge_right \
|
||||
--window-title "O12 T3 right" \
|
||||
--cmd-topic /o12/right/joint_cmd \
|
||||
--sim-state-topic /o12/right/joint_states \
|
||||
--no-legacy-sdk \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
@@ -0,0 +1,8 @@
|
||||
# O30
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
- `run_left.sh`
|
||||
- `run_right.sh`
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Historical V5 asset only: active piecewise mapping is disabled by current linear policy.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
export O30_RIGHT_URDF="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_endpoint_calibrated.urdf"
|
||||
exec "$ROOT/hands/O30/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the preserved V6 pure linear URDF.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
export O30_RIGHT_URDF="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_linear_calibrated.urdf"
|
||||
exec "$ROOT/hands/O30/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the preserved V7 pure linear URDF.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
export O30_RIGHT_URDF="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_two_joint_calibrated.urdf"
|
||||
exec "$ROOT/hands/O30/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the preserved V8 pure linear URDF.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
export O30_RIGHT_URDF="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_pinky_root_calibrated.urdf"
|
||||
exec "$ROOT/hands/O30/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the preserved V9 pure linear URDF.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
export O30_RIGHT_URDF="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_middle_calibrated.urdf"
|
||||
exec "$ROOT/hands/O30/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../assets/exports/O30_V10_left_right
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../outputs/reports/O30
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o30_left_mujoco_plan.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o30_right_mujoco_plan.sh" "$@"
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo O30i 左手单窗仿真
|
||||
# URDF: exports/O30_V9_left_right/left/linkerhand_o30_left_v9.urdf (V10 right mirrored; existing asset path retained)
|
||||
# 订阅 /cb_left_hand_control_cmd(20 路 SDK 0~255,按 URDF 限位线性换算)
|
||||
# 发布 /o30/left/joint_states(20 路弧度)
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O30/scripts/run_o30_left_mujoco_plan.sh
|
||||
# ./hands/O30/scripts/run_o30_left_mujoco_plan.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_SRC="${O30_LEFT_URDF:-$ROOT/assets/exports/O30_V10_left_right/left/linkerhand_o30_left_v10.urdf}"
|
||||
MESH_SRC="${O30_LEFT_MESHDIR:-$(dirname "$URDF_SRC")/meshes}"
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2"
|
||||
O30_DIR="$PKG_SRC/urdf/O30/linker_hand_o30_left"
|
||||
XML="$O30_DIR/linker_hand_o30_left.xml"
|
||||
URDF_PKG="$O30_DIR/linkerhand_o30_left.urdf"
|
||||
|
||||
if [[ ! -f "$URDF_SRC" ]]; then
|
||||
echo "[error] missing O30 URDF: $URDF_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$MESH_SRC" ]]; then
|
||||
echo "[error] missing O30 meshes: $MESH_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o30-left] sync MJCF from $URDF_SRC"
|
||||
python3 - "$URDF_SRC" "$MESH_SRC" "$O30_DIR" "$XML" "$URDF_PKG" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
|
||||
urdf_src = Path(sys.argv[1])
|
||||
mesh_src = Path(sys.argv[2])
|
||||
out_dir = Path(sys.argv[3])
|
||||
xml_path = Path(sys.argv[4])
|
||||
urdf_pkg = Path(sys.argv[5])
|
||||
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
mesh_out = out_dir / "meshes"
|
||||
mesh_out.mkdir(exist_ok=True)
|
||||
for f in mesh_src.iterdir():
|
||||
if f.is_file():
|
||||
shutil.copy2(f, mesh_out / f.name)
|
||||
|
||||
text = urdf_src.read_text()
|
||||
text = re.sub(r"package://[^/]+/meshes/", "meshes/", text)
|
||||
urdf_pkg.write_text(text)
|
||||
|
||||
|
||||
def attrs_of(chunk: str) -> dict[str, str]:
|
||||
return dict(re.findall(r'(\w+)="([^"]*)"', chunk))
|
||||
|
||||
|
||||
def parse_links(urdf: str) -> dict[str, dict]:
|
||||
links: dict[str, dict] = {}
|
||||
for m in re.finditer(r'<link\s+name="([^"]+)"[^>]*>(.*?)</link>', urdf, re.S):
|
||||
name, body = m.group(1), m.group(2)
|
||||
inertial = re.search(r"<inertial>(.*?)</inertial>", body, re.S)
|
||||
pos = "0 0 0"
|
||||
mass = "0.01"
|
||||
fullinertia = "1e-6 1e-6 1e-6 0 0 0"
|
||||
if inertial:
|
||||
ib = inertial.group(1)
|
||||
origin = re.search(r"<origin\b([^/]*)/>", ib)
|
||||
mass_m = re.search(r'<mass\b([^/]*)/>', ib)
|
||||
inertia = re.search(r"<inertia\b([^/]*)/>", ib)
|
||||
if origin:
|
||||
pos = attrs_of(origin.group(1)).get("xyz", pos)
|
||||
if mass_m:
|
||||
mass = attrs_of(mass_m.group(1)).get("value", mass)
|
||||
if inertia:
|
||||
ia = attrs_of(inertia.group(1))
|
||||
fullinertia = " ".join(
|
||||
ia.get(k, "0") for k in ("ixx", "iyy", "izz", "ixy", "ixz", "iyz")
|
||||
)
|
||||
color = "0.7 0.7 0.7 1"
|
||||
vis = re.search(r"<visual>(.*?)</visual>", body, re.S)
|
||||
if vis:
|
||||
col = re.search(r'rgba="([^"]+)"', vis.group(1))
|
||||
if col:
|
||||
color = col.group(1)
|
||||
mesh = None
|
||||
mesh_m = re.search(r'<mesh\b([^>]*)/>', body)
|
||||
if mesh_m:
|
||||
fn = attrs_of(mesh_m.group(1)).get("filename", "")
|
||||
mesh = Path(fn).name
|
||||
links[name] = {
|
||||
"pos": pos,
|
||||
"mass": mass,
|
||||
"fullinertia": fullinertia,
|
||||
"color": color,
|
||||
"mesh": mesh,
|
||||
}
|
||||
return links
|
||||
|
||||
|
||||
def parse_joints(urdf: str) -> list[dict]:
|
||||
joints = []
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", urdf, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name = re.search(r'name="([^"]+)"', attrs)
|
||||
jtype = re.search(r'type="([^"]+)"', attrs)
|
||||
if not name or not jtype or jtype.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r"<origin\b([^/]*)/>", body)
|
||||
axis = re.search(r"<axis\b([^/]*)/>", body)
|
||||
lim = re.search(r"<limit\b([^/]*)/>", body)
|
||||
parent = re.search(r'<parent[^>]*link="([^"]+)"', body)
|
||||
child = re.search(r'<child[^>]*link="([^"]+)"', body)
|
||||
oa = attrs_of(origin.group(1)) if origin else {}
|
||||
la = attrs_of(lim.group(1)) if lim else {}
|
||||
joints.append(
|
||||
{
|
||||
"name": name.group(1),
|
||||
"xyz": oa.get("xyz", "0 0 0"),
|
||||
"rpy": oa.get("rpy", "0 0 0"),
|
||||
"axis": attrs_of(axis.group(1)).get("xyz", "0 0 1") if axis else "0 0 1",
|
||||
"lo": float(la.get("lower", "0")),
|
||||
"hi": float(la.get("upper", "0")),
|
||||
"parent": parent.group(1) if parent else "",
|
||||
"child": child.group(1) if child else "",
|
||||
}
|
||||
)
|
||||
return joints
|
||||
|
||||
|
||||
def rpy_to_quat(rpy: str) -> str | None:
|
||||
import math
|
||||
|
||||
r, p, y = [float(x) for x in rpy.split()]
|
||||
if abs(r) + abs(p) + abs(y) < 1e-12:
|
||||
return None
|
||||
cr, sr = math.cos(r / 2), math.sin(r / 2)
|
||||
cp, sp = math.cos(p / 2), math.sin(p / 2)
|
||||
cy, sy = math.cos(y / 2), math.sin(y / 2)
|
||||
w = cr * cp * cy + sr * sp * sy
|
||||
x = sr * cp * cy - cr * sp * sy
|
||||
yq = cr * sp * cy + sr * cp * sy
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
return f"{w:.16g} {x:.16g} {yq:.16g} {z:.16g}"
|
||||
|
||||
|
||||
links = parse_links(text)
|
||||
joints = parse_joints(text)
|
||||
children = {j["parent"]: [] for j in joints}
|
||||
for j in joints:
|
||||
children.setdefault(j["parent"], []).append(j)
|
||||
# keep URDF order
|
||||
order = [j["name"] for j in joints]
|
||||
by_parent: dict[str, list[dict]] = {}
|
||||
for j in joints:
|
||||
by_parent.setdefault(j["parent"], []).append(j)
|
||||
|
||||
root = "hand_base_link"
|
||||
meshes = sorted({info["mesh"] for info in links.values() if info["mesh"]})
|
||||
|
||||
lines = [
|
||||
'<mujoco model="linkerhand_o30_left">',
|
||||
' <compiler angle="radian" meshdir="meshes"/>',
|
||||
' <option timestep="0.002" gravity="0 0 -9.81" integrator="implicitfast"/>',
|
||||
' <statistic center="0.01 0 0.08" extent="0.16"/>',
|
||||
" <default>",
|
||||
' <joint damping="0.15" armature="0.01"/>',
|
||||
' <position kp="80" kv="8" forcelimited="true" forcerange="-8 8"/>',
|
||||
' <default class="visual">',
|
||||
' <geom type="mesh" contype="0" conaffinity="0" group="2"/>',
|
||||
" </default>",
|
||||
' <default class="collision">',
|
||||
' <geom type="mesh" contype="1" conaffinity="1" condim="3" group="3"',
|
||||
' rgba="0 1 0 0.15" friction="1 0.5 0.01"',
|
||||
' solref="0.004 1" solimp="0.95 0.99 0.001" margin="0"/>',
|
||||
" </default>",
|
||||
" </default>",
|
||||
" <asset>",
|
||||
]
|
||||
# Respect the asset scale: V10 STL vertices are already mirrored.
|
||||
import xml.etree.ElementTree as ET
|
||||
mesh_scales = {}
|
||||
for element in ET.fromstring(text).findall('.//mesh'):
|
||||
filename = Path(element.get('filename')).name
|
||||
scale = element.get('scale', '1 1 1')
|
||||
if filename in mesh_scales and mesh_scales[filename] != scale:
|
||||
raise ValueError(f'Conflicting mesh scales: {filename}')
|
||||
mesh_scales[filename] = scale
|
||||
for mesh in meshes:
|
||||
scale = mesh_scales[Path(mesh).name]
|
||||
lines.append(f' <mesh name="{Path(mesh).stem}" file="{mesh}" scale="{scale}"/>')
|
||||
lines.append(" </asset>")
|
||||
lines.append(" <worldbody>")
|
||||
|
||||
|
||||
def emit_body(link: str, indent: int, joint: dict | None) -> None:
|
||||
pad = " " * indent
|
||||
info = links[link]
|
||||
if joint is None:
|
||||
lines.append(f'{pad}<body name="{link}">')
|
||||
else:
|
||||
quat = rpy_to_quat(joint["rpy"])
|
||||
pose = f'pos="{joint["xyz"]}"'
|
||||
if quat:
|
||||
pose += f' quat="{quat}"'
|
||||
lines.append(f'{pad}<body name="{link}" {pose}>')
|
||||
lines.append(
|
||||
f'{pad} <inertial pos="{info["pos"]}" mass="{info["mass"]}" '
|
||||
f'fullinertia="{info["fullinertia"]}"/>'
|
||||
)
|
||||
if joint is not None:
|
||||
lines.append(
|
||||
f'{pad} <joint name="{joint["name"]}" pos="0 0 0" axis="{joint["axis"]}" '
|
||||
f'range="{joint["lo"]:.16g} {joint["hi"]:.16g}"/>'
|
||||
)
|
||||
mesh = Path(info["mesh"]).stem if info["mesh"] else None
|
||||
if mesh:
|
||||
lines.append(
|
||||
f'{pad} <geom class="visual" rgba="{info["color"]}" mesh="{mesh}"/>'
|
||||
)
|
||||
lines.append(f'{pad} <geom class="collision" mesh="{mesh}"/>')
|
||||
for child_j in by_parent.get(link, []):
|
||||
emit_body(child_j["child"], indent + 1, child_j)
|
||||
lines.append(f"{pad}</body>")
|
||||
|
||||
|
||||
emit_body(root, 2, None)
|
||||
lines.append(" </worldbody>")
|
||||
lines.append(" <contact>")
|
||||
for j in joints:
|
||||
lines.append(f' <exclude body1="{j["parent"]}" body2="{j["child"]}"/>')
|
||||
# 张开位掌心与近节 mesh 贴合,否则 PD 会把手指顶开
|
||||
for other in (
|
||||
"thumb_metacarpals_base2",
|
||||
"index_proximal",
|
||||
"middle_proximal",
|
||||
"ring_proximal",
|
||||
"pinky_proximal",
|
||||
):
|
||||
lines.append(f' <exclude body1="hand_base_link" body2="{other}"/>')
|
||||
lines.append(" </contact>")
|
||||
lines.append(" <actuator>")
|
||||
for j in joints:
|
||||
lines.append(
|
||||
f' <position name="{j["name"]}_pos" joint="{j["name"]}" '
|
||||
f'ctrlrange="{j["lo"]:.16g} {j["hi"]:.16g}"/>'
|
||||
)
|
||||
lines.append(" </actuator>")
|
||||
lines.append("</mujoco>")
|
||||
xml_path.write_text("\n".join(lines) + "\n")
|
||||
model = mujoco.MjModel.from_xml_path(str(xml_path))
|
||||
print(f"[o30-left] wrote {xml_path} njnt={model.njnt} nbody={model.nbody}")
|
||||
PY
|
||||
|
||||
if [[ "${O30_LEFT_PREPARE_ONLY:-0}" == "1" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[o30-left] urdf=$URDF_PKG"
|
||||
echo "[o30-left] xml=$XML"
|
||||
echo "[o30-left] cmd-topic=/cb_left_hand_control_cmd (20 SDK values, 0..255)"
|
||||
echo "[o30-left] state-topic=/o30/left/joint_states (20 rad)"
|
||||
echo "[o30-left] SDK order: thumb_roll,thumb_yaw,index_yaw,middle_yaw,ring_yaw,pinky_yaw, thumb_root,index_root,middle_root,ring_root,pinky_root, index_pip,middle_pip,ring_pip,pinky_pip, thumb_tip,index_tip,middle_tip,ring_tip,pinky_tip"
|
||||
echo "[o30-left] default mode=kinematic; 加 --pd-drive 看接触"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.o30_left_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name o30_mujoco_plan_bridge_left \
|
||||
--window-title "O30i left V10 mirrored" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /o30/left/joint_states \
|
||||
--no-legacy-sdk \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo O30i 右手单窗仿真(V2_0819)
|
||||
# 默认使用 V10 纯 URDF:保留对指锚点,调整新零位,保持线性换算。
|
||||
# O30_RIGHT_URDF 可覆盖;启动姿态对应第五张照片的零位数组。
|
||||
# 订阅 /cb_right_hand_control_cmd(20 维 SDK 0~255,顺序见 linkerhand-o30-ros2 JOINT_MAP)
|
||||
# 发布 /sim/mujoco/o30/right/joint_state
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O30/scripts/run_o30_right_mujoco_plan.sh
|
||||
# ./hands/O30/scripts/run_o30_right_mujoco_plan.sh --pd-drive
|
||||
# O30_RIGHT_PREPARE_ONLY=1 ./hands/O30/scripts/run_o30_right_mujoco_plan.sh # 只生成/校验模型
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2"
|
||||
O30_DIR="$PKG_SRC/urdf/O30/linker_hand_o30_right"
|
||||
URDF_SRC="${O30_RIGHT_URDF:-$O30_DIR/linkerhand_o30_right_zero_v10_calibrated.urdf}"
|
||||
MESH_SRC="${O30_RIGHT_MESHDIR:-$O30_DIR/meshes}"
|
||||
XML="$O30_DIR/linker_hand_o30_right.xml"
|
||||
URDF_PKG="$O30_DIR/linkerhand_o30_right.urdf"
|
||||
|
||||
if [[ ! -f "$URDF_SRC" ]]; then
|
||||
echo "[error] missing O30 right URDF: $URDF_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$MESH_SRC" ]]; then
|
||||
echo "[error] missing O30 right meshes: $MESH_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o30-right] sync MJCF from $URDF_SRC"
|
||||
python3 - "$URDF_SRC" "$MESH_SRC" "$O30_DIR" "$XML" "$URDF_PKG" <<'PY'
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
import mujoco
|
||||
|
||||
urdf_src = Path(sys.argv[1])
|
||||
mesh_src = Path(sys.argv[2])
|
||||
out_dir = Path(sys.argv[3])
|
||||
xml_path = Path(sys.argv[4])
|
||||
urdf_pkg = Path(sys.argv[5])
|
||||
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
mesh_out = out_dir / "meshes"
|
||||
mesh_out.mkdir(exist_ok=True)
|
||||
for f in mesh_src.iterdir():
|
||||
if f.is_file() and f.resolve() != (mesh_out / f.name).resolve():
|
||||
shutil.copy2(f, mesh_out / f.name)
|
||||
|
||||
text = urdf_src.read_text()
|
||||
text = re.sub(r"package://[^/]+/meshes/", "meshes/", text)
|
||||
urdf_pkg.write_text(text)
|
||||
|
||||
|
||||
def attrs_of(chunk: str) -> dict[str, str]:
|
||||
return dict(re.findall(r'(\w+)="([^"]*)"', chunk))
|
||||
|
||||
|
||||
def parse_links(urdf: str) -> dict[str, dict]:
|
||||
links: dict[str, dict] = {}
|
||||
for m in re.finditer(r'<link\s+name="([^"]+)"[^>]*>(.*?)</link>', urdf, re.S):
|
||||
name, body = m.group(1), m.group(2)
|
||||
inertial = re.search(r"<inertial>(.*?)</inertial>", body, re.S)
|
||||
pos = "0 0 0"
|
||||
mass = "0.01"
|
||||
fullinertia = "1e-6 1e-6 1e-6 0 0 0"
|
||||
if inertial:
|
||||
ib = inertial.group(1)
|
||||
origin = re.search(r"<origin\b([^/]*)/>", ib)
|
||||
mass_m = re.search(r"<mass\b([^/]*)/>", ib)
|
||||
inertia = re.search(r"<inertia\b([^/]*)/>", ib)
|
||||
if origin:
|
||||
pos = attrs_of(origin.group(1)).get("xyz", pos)
|
||||
if mass_m:
|
||||
mass = attrs_of(mass_m.group(1)).get("value", mass)
|
||||
if inertia:
|
||||
ia = attrs_of(inertia.group(1))
|
||||
fullinertia = " ".join(
|
||||
ia.get(k, "0") for k in ("ixx", "iyy", "izz", "ixy", "ixz", "iyz")
|
||||
)
|
||||
color = "0.7 0.7 0.7 1"
|
||||
vis = re.search(r"<visual>(.*?)</visual>", body, re.S)
|
||||
if vis:
|
||||
col = re.search(r'rgba="([^"]+)"', vis.group(1))
|
||||
if col:
|
||||
color = col.group(1)
|
||||
mesh = None
|
||||
mesh_scale = None
|
||||
mesh_m = re.search(r"<mesh\b([^>]*)/>", body)
|
||||
if mesh_m:
|
||||
ma = attrs_of(mesh_m.group(1))
|
||||
fn = ma.get("filename", "")
|
||||
mesh = Path(fn).name
|
||||
mesh_scale = ma.get("scale")
|
||||
links[name] = {
|
||||
"pos": pos,
|
||||
"mass": mass,
|
||||
"fullinertia": fullinertia,
|
||||
"color": color,
|
||||
"mesh": mesh,
|
||||
"mesh_scale": mesh_scale,
|
||||
}
|
||||
return links
|
||||
|
||||
|
||||
def parse_joints(urdf: str) -> list[dict]:
|
||||
joints = []
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", urdf, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name = re.search(r'name="([^"]+)"', attrs)
|
||||
jtype = re.search(r'type="([^"]+)"', attrs)
|
||||
if not name or not jtype or jtype.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r"<origin\b([^/]*)/>", body)
|
||||
axis = re.search(r"<axis\b([^/]*)/>", body)
|
||||
lim = re.search(r"<limit\b([^/]*)/>", body)
|
||||
parent = re.search(r'<parent[^>]*link="([^"]+)"', body)
|
||||
child = re.search(r'<child[^>]*link="([^"]+)"', body)
|
||||
oa = attrs_of(origin.group(1)) if origin else {}
|
||||
la = attrs_of(lim.group(1)) if lim else {}
|
||||
joints.append(
|
||||
{
|
||||
"name": name.group(1),
|
||||
"xyz": oa.get("xyz", "0 0 0"),
|
||||
"rpy": oa.get("rpy", "0 0 0"),
|
||||
"axis": attrs_of(axis.group(1)).get("xyz", "0 0 1") if axis else "0 0 1",
|
||||
"lo": float(la.get("lower", "0")),
|
||||
"hi": float(la.get("upper", "0")),
|
||||
"parent": parent.group(1) if parent else "",
|
||||
"child": child.group(1) if child else "",
|
||||
}
|
||||
)
|
||||
return joints
|
||||
|
||||
|
||||
def rpy_to_quat(rpy: str) -> str | None:
|
||||
import math
|
||||
|
||||
r, p, y = [float(x) for x in rpy.split()]
|
||||
if abs(r) + abs(p) + abs(y) < 1e-12:
|
||||
return None
|
||||
cr, sr = math.cos(r / 2), math.sin(r / 2)
|
||||
cp, sp = math.cos(p / 2), math.sin(p / 2)
|
||||
cy, sy = math.cos(y / 2), math.sin(y / 2)
|
||||
w = cr * cp * cy + sr * sp * sy
|
||||
x = sr * cp * cy - cr * sp * sy
|
||||
yq = cr * sp * cy + sr * cp * sy
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
return f"{w:.12g} {x:.12g} {yq:.12g} {z:.12g}"
|
||||
|
||||
|
||||
links = parse_links(text)
|
||||
joints = parse_joints(text)
|
||||
by_parent: dict[str, list[dict]] = {}
|
||||
for j in joints:
|
||||
by_parent.setdefault(j["parent"], []).append(j)
|
||||
|
||||
root = "hand_base_link"
|
||||
# mesh name -> scale (from first link that uses it)
|
||||
mesh_scale: dict[str, str | None] = {}
|
||||
for info in links.values():
|
||||
if info["mesh"] and info["mesh"] not in mesh_scale:
|
||||
mesh_scale[info["mesh"]] = info["mesh_scale"]
|
||||
meshes = sorted(mesh_scale.keys())
|
||||
|
||||
lines = [
|
||||
'<mujoco model="linkerhand_o30_right">',
|
||||
' <compiler angle="radian" meshdir="meshes"/>',
|
||||
' <option timestep="0.002" gravity="0 0 -9.81" integrator="implicitfast"/>',
|
||||
' <statistic center="0.01 0 0.08" extent="0.16"/>',
|
||||
" <default>",
|
||||
' <joint damping="0.15" armature="0.01"/>',
|
||||
' <position kp="80" kv="8" forcelimited="true" forcerange="-8 8"/>',
|
||||
' <default class="visual">',
|
||||
' <geom type="mesh" contype="0" conaffinity="0" group="2"/>',
|
||||
" </default>",
|
||||
' <default class="collision">',
|
||||
' <geom type="mesh" contype="1" conaffinity="1" condim="3" group="3"',
|
||||
' rgba="0 1 0 0.15" friction="1 0.5 0.01"',
|
||||
' solref="0.004 1" solimp="0.95 0.99 0.001" margin="0"/>',
|
||||
" </default>",
|
||||
" </default>",
|
||||
" <asset>",
|
||||
]
|
||||
for mesh in meshes:
|
||||
stem = Path(mesh).stem
|
||||
sc = mesh_scale.get(mesh)
|
||||
if sc:
|
||||
lines.append(f' <mesh name="{stem}" file="{mesh}" scale="{sc}"/>')
|
||||
else:
|
||||
lines.append(f' <mesh name="{stem}" file="{mesh}"/>')
|
||||
lines.append(" </asset>")
|
||||
lines.append(" <worldbody>")
|
||||
|
||||
|
||||
def emit_body(link: str, indent: int, joint: dict | None) -> None:
|
||||
pad = " " * indent
|
||||
info = links[link]
|
||||
if joint is None:
|
||||
lines.append(f'{pad}<body name="{link}">')
|
||||
else:
|
||||
quat = rpy_to_quat(joint["rpy"])
|
||||
pose = f'pos="{joint["xyz"]}"'
|
||||
if quat:
|
||||
pose += f' quat="{quat}"'
|
||||
lines.append(f'{pad}<body name="{link}" {pose}>')
|
||||
lines.append(
|
||||
f'{pad} <inertial pos="{info["pos"]}" mass="{info["mass"]}" '
|
||||
f'fullinertia="{info["fullinertia"]}"/>'
|
||||
)
|
||||
if joint is not None:
|
||||
lines.append(
|
||||
f'{pad} <joint name="{joint["name"]}" pos="0 0 0" axis="{joint["axis"]}" '
|
||||
f'range="{joint["lo"]:.12g} {joint["hi"]:.12g}"/>'
|
||||
)
|
||||
mesh = Path(info["mesh"]).stem if info["mesh"] else None
|
||||
if mesh:
|
||||
lines.append(
|
||||
f'{pad} <geom class="visual" rgba="{info["color"]}" mesh="{mesh}"/>'
|
||||
)
|
||||
lines.append(f'{pad} <geom class="collision" mesh="{mesh}"/>')
|
||||
for child_j in by_parent.get(link, []):
|
||||
emit_body(child_j["child"], indent + 1, child_j)
|
||||
lines.append(f"{pad}</body>")
|
||||
|
||||
|
||||
emit_body(root, 2, None)
|
||||
lines.append(" </worldbody>")
|
||||
lines.append(" <contact>")
|
||||
for j in joints:
|
||||
lines.append(f' <exclude body1="{j["parent"]}" body2="{j["child"]}"/>')
|
||||
for other in (
|
||||
"thumb_metacarpals_base2",
|
||||
"index_proximal",
|
||||
"middle_proximal",
|
||||
"ring_proximal",
|
||||
"pinky_proximal",
|
||||
):
|
||||
lines.append(f' <exclude body1="hand_base_link" body2="{other}"/>')
|
||||
lines.append(" </contact>")
|
||||
lines.append(" <actuator>")
|
||||
for j in joints:
|
||||
lines.append(
|
||||
f' <position name="{j["name"]}_pos" joint="{j["name"]}" '
|
||||
f'ctrlrange="{j["lo"]:.12g} {j["hi"]:.12g}"/>'
|
||||
)
|
||||
lines.append(" </actuator>")
|
||||
sdk_mapping = ET.fromstring(text).find('o30_sdk_mapping')
|
||||
if sdk_mapping is not None:
|
||||
if sdk_mapping.get('version') != '1' or sdk_mapping.get('interpolation') != 'linear':
|
||||
raise ValueError('Unsupported O30 SDK mapping format')
|
||||
lines.append(' <custom>')
|
||||
for item in sdk_mapping.findall('map'):
|
||||
name = item.get('joint', '')
|
||||
if name not in {j['name'] for j in joints}:
|
||||
raise ValueError(f'Unknown mapped joint: {name}')
|
||||
sdk = item.get('sdk', '').split()
|
||||
radians = item.get('radians', '').split()
|
||||
if len(sdk) != len(radians):
|
||||
raise ValueError(f'O30 mapping knot count mismatch: {name}')
|
||||
data = ' '.join(format(float(v), '.16g') for pair in zip(sdk, radians) for v in pair)
|
||||
lines.append(f' <numeric name="o30_sdk_map_{name}" data="{data}"/>')
|
||||
lines.append(' </custom>')
|
||||
lines.append("</mujoco>")
|
||||
xml_path.write_text("\n".join(lines) + "\n")
|
||||
model = mujoco.MjModel.from_xml_path(str(xml_path))
|
||||
from linker_hand_mujoco_ros2.utils.o30_right_joints import configure_o30_right_limits
|
||||
configure_o30_right_limits(xml_path)
|
||||
print(f"[o30-right] wrote {xml_path} njnt={model.njnt} nbody={model.nbody} ngeom={model.ngeom}")
|
||||
PY
|
||||
|
||||
if [[ "${O30_RIGHT_PREPARE_ONLY:-0}" == "1" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
# Keep this checkout ahead of installed copies after sourcing ROS workspaces.
|
||||
export PYTHONPATH="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o30-right] urdf=$URDF_PKG"
|
||||
echo "[o30-right] xml=$XML"
|
||||
echo "[o30-right] cmd-topic=/cb_right_hand_control_cmd (20ch SDK 0~255, JOINT_MAP 顺序)"
|
||||
echo "[o30-right] state-topic=/sim/mujoco/o30/right/joint_state"
|
||||
echo "[o30-right] order: thumb_roll,yaw, idx/mid/ring/little_yaw, thumb/idx/mid/ring/little_root1, idx/mid/ring/little_root2, thumb/idx/mid/ring/little_tip"
|
||||
echo "[o30-right] default mode=kinematic; 加 --pd-drive 看接触"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.o30_right_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name o30_mujoco_plan_bridge_right \
|
||||
--window-title "O30i right V10 zero calibrated" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/o30/right/joint_state \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
@@ -0,0 +1,10 @@
|
||||
# O6
|
||||
|
||||
[统一入口与映射说明](../README.md)
|
||||
|
||||
- `compare_left.sh`
|
||||
- `compare_right.sh`
|
||||
- `run_left.sh`
|
||||
- `run_right.sh`
|
||||
|
||||
`assets/` 是包内模型链接;`scripts/` 为内部实现及辅助工具。
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O6
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o6_left_dual_compare.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o6_right_dual_compare.sh" "$@"
|
||||
@@ -0,0 +1,666 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
|
||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||
<robot
|
||||
name="linkerhand_o6_left">
|
||||
<material name="silver">
|
||||
<color rgba="0.5 0.5 0.52 1.0"/>
|
||||
</material>
|
||||
|
||||
<material name="BlackAccent">
|
||||
<color rgba="0.15 0.15 0.15 1.0"/>
|
||||
</material>
|
||||
|
||||
<link
|
||||
name="lh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00157788568070457 -0.00034876725935859 0.0538452219801211"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0672935238166485" />
|
||||
<inertia
|
||||
ixx="5.22525212160954E-05"
|
||||
ixy="3.06955729584715E-07"
|
||||
ixz="-3.90341166950521E-07"
|
||||
iyy="3.33522349207724E-05"
|
||||
iyz="-7.76680063574627E-07"
|
||||
izz="2.28469461105385E-05" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_metacarpals_base2">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00162800681276937 -0.0027668017246415 -0.00184234438641236"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00138588296544333" />
|
||||
<inertia
|
||||
ixx="5.26292160685909E-08"
|
||||
ixy="-3.92888681640568E-09"
|
||||
ixz="-2.43767371295222E-09"
|
||||
iyy="4.82620491570326E-08"
|
||||
iyz="3.71869784206147E-09"
|
||||
izz="2.88550286112821E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
<material name="BlackAccent"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_yaw"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.011508 -0.022975 0.032794"
|
||||
rpy="0 0 0.167545678324764" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals_base2" />
|
||||
<axis
|
||||
xyz="0 0 1" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.2431454"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="4.24816204999817E-05 1.74183907812875E-05 0.0228341640631254"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0123381586619931" />
|
||||
<inertia
|
||||
ixx="1.10292537368909E-06"
|
||||
ixy="-5.99642232777877E-10"
|
||||
ixz="-1.14233573940545E-07"
|
||||
iyy="1.76757772551884E-06"
|
||||
iyz="-4.03963570823777E-10"
|
||||
izz="9.36347792411098E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0061649 -0.010678 -0.004891"
|
||||
rpy="0 -1.1529 2.0944" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals_base2" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.588901345"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00413725702921841 -5.90704520436747E-08 0.023011401589736"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00763332957284057" />
|
||||
<inertia
|
||||
ixx="1.3057487813702E-06"
|
||||
ixy="-1.19781508112714E-11"
|
||||
ixz="-7.19551697268541E-08"
|
||||
iyy="1.2248908905341E-06"
|
||||
iyz="4.55347974652679E-12"
|
||||
izz="2.77271910592615E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_ip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0037776 0 0.045368"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals" />
|
||||
<child
|
||||
link="lh_thumb_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.16064834"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_thumb_cmc_pitch"
|
||||
multiplier="1.96832996705076"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208656556336452 2.53838713251686E-06 0.0172734941980264"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253174651934627" />
|
||||
<inertia
|
||||
ixx="2.65988714157799E-07"
|
||||
ixy="-1.67174578825824E-11"
|
||||
ixz="-4.31047725546034E-08"
|
||||
iyy="2.72914069166233E-07"
|
||||
iyz="1.8756709532167E-10"
|
||||
izz="8.56017305636748E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 -0.02419 0.098779"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986616416549 5.13855642059191E-06 0.0194393600039178"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376951085886838" />
|
||||
<inertia
|
||||
ixx="3.22347106085043E-07"
|
||||
ixy="1.3801788663582E-11"
|
||||
ixz="1.14352857317951E-07"
|
||||
iyy="3.65328133721509E-07"
|
||||
iyz="-2.11505011705634E-10"
|
||||
izz="1.24287996386442E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_proximal" />
|
||||
<child
|
||||
link="lh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_index_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208660654138235 2.56918180119303E-06 0.0172735011723351"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253177375206983" />
|
||||
<inertia
|
||||
ixx="2.65989021304483E-07"
|
||||
ixy="-1.69816046635662E-11"
|
||||
ixz="-4.31046683215273E-08"
|
||||
iyy="2.72914402745606E-07"
|
||||
iyz="1.87484652324395E-10"
|
||||
izz="8.5602213431865E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00052576 -0.00634 0.1027"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986516319194 5.10862924271716E-06 0.0194393315699782"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376952789210256" />
|
||||
<inertia
|
||||
ixx="3.22348591068053E-07"
|
||||
ixy="1.37122394856588E-11"
|
||||
ixz="1.1435291391668E-07"
|
||||
iyy="3.65329535087755E-07"
|
||||
iyz="-2.10453810291991E-10"
|
||||
izz="1.24288425862546E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_proximal" />
|
||||
<child
|
||||
link="lh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_middle_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208667931345812 2.63000419462034E-06 0.0172734926448377"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253182223645066" />
|
||||
<inertia
|
||||
ixx="2.65989756076584E-07"
|
||||
ixy="-1.74912952703656E-11"
|
||||
ixz="-4.31043325594253E-08"
|
||||
iyy="2.7291510093393E-07"
|
||||
iyz="1.87158326740895E-10"
|
||||
izz="8.56031522765909E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0010258 0.011135 0.098767"
|
||||
rpy="-0.05236 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986648895491 5.05883528165163E-06 0.019439397215532"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376949588316609" />
|
||||
<inertia
|
||||
ixx="3.2234524157181E-07"
|
||||
ixy="1.35766976056011E-11"
|
||||
ixz="1.14353011012842E-07"
|
||||
iyy="3.65326570102147E-07"
|
||||
iyz="-2.08672149138738E-10"
|
||||
izz="1.24287770218135E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_proximal" />
|
||||
<child
|
||||
link="lh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_ring_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208673599799501 2.68062251165824E-06 0.0172734848131236"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253185993162408" />
|
||||
<inertia
|
||||
ixx="2.6599033687183E-07"
|
||||
ixy="-1.79030790016555E-11"
|
||||
ixz="-4.31040829565781E-08"
|
||||
iyy="2.72915617381577E-07"
|
||||
iyz="1.86906787420486E-10"
|
||||
izz="8.56039175034871E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 0.028372 0.092741"
|
||||
rpy="-0.087266 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658987588903027 5.03087534178825E-06 0.0194394491065091"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376948071276134" />
|
||||
<inertia
|
||||
ixx="3.22343583730488E-07"
|
||||
ixy="1.35768173270357E-11"
|
||||
ixz="1.14353289593012E-07"
|
||||
iyy="3.65325180884183E-07"
|
||||
iyz="-2.0744198062439E-10"
|
||||
izz="1.24287567374229E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_proximal" />
|
||||
<child
|
||||
link="lh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_pinky_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
</robot>
|
||||
@@ -0,0 +1,666 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
|
||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||
<robot
|
||||
name="linkerhand_o6_left">
|
||||
<material name="silver">
|
||||
<color rgba="0.5 0.5 0.52 1.0"/>
|
||||
</material>
|
||||
|
||||
<material name="BlackAccent">
|
||||
<color rgba="0.15 0.15 0.15 1.0"/>
|
||||
</material>
|
||||
|
||||
<link
|
||||
name="lh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00157788568070457 -0.00034876725935859 0.0538452219801211"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0672935238166485" />
|
||||
<inertia
|
||||
ixx="5.22525212160954E-05"
|
||||
ixy="3.06955729584715E-07"
|
||||
ixz="-3.90341166950521E-07"
|
||||
iyy="3.33522349207724E-05"
|
||||
iyz="-7.76680063574627E-07"
|
||||
izz="2.28469461105385E-05" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="lh_thumb_metacarpals_base2">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00162800681276937 -0.0027668017246415 -0.00184234438641236"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00138588296544333" />
|
||||
<inertia
|
||||
ixx="5.26292160685909E-08"
|
||||
ixy="-3.92888681640568E-09"
|
||||
ixz="-2.43767371295222E-09"
|
||||
iyy="4.82620491570326E-08"
|
||||
iyz="3.71869784206147E-09"
|
||||
izz="2.88550286112821E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
<material name="BlackAccent"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_yaw"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.011508 -0.022975 0.032794"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals_base2" />
|
||||
<axis
|
||||
xyz="0 0 1" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.3"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="4.24816204999817E-05 1.74183907812875E-05 0.0228341640631254"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0123381586619931" />
|
||||
<inertia
|
||||
ixx="1.10292537368909E-06"
|
||||
ixy="-5.99642232777877E-10"
|
||||
ixz="-1.14233573940545E-07"
|
||||
iyy="1.76757772551884E-06"
|
||||
iyz="-4.03963570823777E-10"
|
||||
izz="9.36347792411098E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0061649 -0.010678 -0.004891"
|
||||
rpy="0 -1.1529 2.0944" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals_base2" />
|
||||
<child
|
||||
link="lh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.58"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00413725702921841 -5.90704520436747E-08 0.023011401589736"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00763332957284057" />
|
||||
<inertia
|
||||
ixx="1.3057487813702E-06"
|
||||
ixy="-1.19781508112714E-11"
|
||||
ixz="-7.19551697268541E-08"
|
||||
iyy="1.2248908905341E-06"
|
||||
iyz="4.55347974652679E-12"
|
||||
izz="2.77271910592615E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_thumb_ip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0037776 0 0.045368"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_thumb_metacarpals" />
|
||||
<child
|
||||
link="lh_thumb_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.08"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_thumb_cmc_pitch"
|
||||
multiplier="2.29"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208656556336452 2.53838713251686E-06 0.0172734941980264"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253174651934627" />
|
||||
<inertia
|
||||
ixx="2.65988714157799E-07"
|
||||
ixy="-1.67174578825824E-11"
|
||||
ixz="-4.31047725546034E-08"
|
||||
iyy="2.72914069166233E-07"
|
||||
iyz="1.8756709532167E-10"
|
||||
izz="8.56017305636748E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 -0.02419 0.098779"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986616416549 5.13855642059191E-06 0.0194393600039178"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376951085886838" />
|
||||
<inertia
|
||||
ixx="3.22347106085043E-07"
|
||||
ixy="1.3801788663582E-11"
|
||||
ixz="1.14352857317951E-07"
|
||||
iyy="3.65328133721509E-07"
|
||||
iyz="-2.11505011705634E-10"
|
||||
izz="1.24287996386442E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_index_proximal" />
|
||||
<child
|
||||
link="lh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_index_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208660654138235 2.56918180119303E-06 0.0172735011723351"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253177375206983" />
|
||||
<inertia
|
||||
ixx="2.65989021304483E-07"
|
||||
ixy="-1.69816046635662E-11"
|
||||
ixz="-4.31046683215273E-08"
|
||||
iyy="2.72914402745606E-07"
|
||||
iyz="1.87484652324395E-10"
|
||||
izz="8.5602213431865E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00052576 -0.00634 0.1027"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986516319194 5.10862924271716E-06 0.0194393315699782"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376952789210256" />
|
||||
<inertia
|
||||
ixx="3.22348591068053E-07"
|
||||
ixy="1.37122394856588E-11"
|
||||
ixz="1.1435291391668E-07"
|
||||
iyy="3.65329535087755E-07"
|
||||
iyz="-2.10453810291991E-10"
|
||||
izz="1.24288425862546E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_middle_proximal" />
|
||||
<child
|
||||
link="lh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_middle_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208667931345812 2.63000419462034E-06 0.0172734926448377"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253182223645066" />
|
||||
<inertia
|
||||
ixx="2.65989756076584E-07"
|
||||
ixy="-1.74912952703656E-11"
|
||||
ixz="-4.31043325594253E-08"
|
||||
iyy="2.7291510093393E-07"
|
||||
iyz="1.87158326740895E-10"
|
||||
izz="8.56031522765909E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0010258 0.011135 0.098767"
|
||||
rpy="-0.05236 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658986648895491 5.05883528165163E-06 0.019439397215532"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376949588316609" />
|
||||
<inertia
|
||||
ixx="3.2234524157181E-07"
|
||||
ixy="1.35766976056011E-11"
|
||||
ixz="1.14353011012842E-07"
|
||||
iyy="3.65326570102147E-07"
|
||||
iyz="-2.08672149138738E-10"
|
||||
izz="1.24287770218135E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_ring_proximal" />
|
||||
<child
|
||||
link="lh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_ring_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208673599799501 2.68062251165824E-06 0.0172734848131236"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253185993162408" />
|
||||
<inertia
|
||||
ixx="2.6599033687183E-07"
|
||||
ixy="-1.79030790016555E-11"
|
||||
ixz="-4.31040829565781E-08"
|
||||
iyy="2.72915617381577E-07"
|
||||
iyz="1.86906787420486E-10"
|
||||
izz="8.56039175034871E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 0.028372 0.092741"
|
||||
rpy="-0.087266 0 0" />
|
||||
<parent
|
||||
link="lh_hand_base_link" />
|
||||
<child
|
||||
link="lh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
|
||||
</joint>
|
||||
<link
|
||||
name="lh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658987588903027 5.03087534178825E-06 0.0194394491065091"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376948071276134" />
|
||||
<inertia
|
||||
ixx="3.22343583730488E-07"
|
||||
ixy="1.35768173270357E-11"
|
||||
ixz="1.14353289593012E-07"
|
||||
iyy="3.65325180884183E-07"
|
||||
iyz="-2.0744198062439E-10"
|
||||
izz="1.24287567374229E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="lh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="lh_pinky_proximal" />
|
||||
<child
|
||||
link="lh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="lh_pinky_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
</robot>
|
||||
@@ -0,0 +1,664 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
|
||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||
<robot
|
||||
name="linkerhand_o6_right">
|
||||
<material name="silver">
|
||||
<color rgba="0.5 0.5 0.52 1.0"/>
|
||||
</material>
|
||||
|
||||
<material name="BlackAccent">
|
||||
<color rgba="0.15 0.15 0.15 1.0"/>
|
||||
</material>
|
||||
<link
|
||||
name="rh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00160320773490556 0.000358462699237561 0.0538002704027215"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.06740077960995" />
|
||||
<inertia
|
||||
ixx="5.22359941041901E-05"
|
||||
ixy="3.0391535852764E-07"
|
||||
ixz="3.88322215371643E-07"
|
||||
iyy="3.33473043513648E-05"
|
||||
iyz="-7.77555280794861E-07"
|
||||
izz="2.28342677422006E-05" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_metacarpals_base2">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00162795738393507 0.00276671978336815 -0.00184227725602707"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00138591070212997" />
|
||||
<inertia
|
||||
ixx="5.26294625624223E-08"
|
||||
ixy="-3.9288013799604E-09"
|
||||
ixz="2.43766268199571E-09"
|
||||
iyy="4.82623724532942E-08"
|
||||
iyz="3.71867754115443E-09"
|
||||
izz="2.88555522060562E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
<material name="BlackAccent"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_yaw"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.011508 0.022975 0.032794"
|
||||
rpy="0 0 -0.167545678324764" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals_base2" />
|
||||
<axis
|
||||
xyz="0 0 -1" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.2431454"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="4.24920612856275E-05 -1.67885666835232E-05 0.0228341522590467"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0123381607727595" />
|
||||
<inertia
|
||||
ixx="1.10292488693766E-06"
|
||||
ixy="-6.14241939151719E-10"
|
||||
ixz="1.14233108676795E-07"
|
||||
iyy="1.76757658485787E-06"
|
||||
iyz="-4.24576599367025E-10"
|
||||
izz="9.36348143657406E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0061649 0.010678 -0.004891"
|
||||
rpy="0 -1.1529 -2.0944" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals_base2" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.588901345"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00413690727496815 -4.54842793429222E-07 0.0230097179163771"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00763302603723749" />
|
||||
<inertia
|
||||
ixx="1.30546842791578E-06"
|
||||
ixy="-2.61617511029467E-12"
|
||||
ixz="7.19030685242407E-08"
|
||||
iyy="1.22457212713176E-06"
|
||||
iyz="1.66931068485225E-11"
|
||||
izz="2.7729897944409E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_ip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0037776 0 0.045368"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals" />
|
||||
<child
|
||||
link="rh_thumb_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.16064834"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_thumb_cmc_pitch"
|
||||
multiplier="1.96832996705076"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208665596033792 -4.8964990644329E-06 0.0172736718900068"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253178529301663" />
|
||||
<inertia
|
||||
ixx="2.65990159539482E-07"
|
||||
ixy="-3.55165625722842E-11"
|
||||
ixz="4.31046335852167E-08"
|
||||
iyy="2.72915460277804E-07"
|
||||
iyz="1.75935978708959E-10"
|
||||
izz="8.56026306687528E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 0.02419 0.098779"
|
||||
rpy="-0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940011630532 -4.59976557022623E-06 0.0194434136420913"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376787129082313" />
|
||||
<inertia
|
||||
ixx="3.22116619426455E-07"
|
||||
ixy="1.03152735699049E-11"
|
||||
ixz="-1.14363506430985E-07"
|
||||
iyy="3.65131844686317E-07"
|
||||
iyz="-1.97263639269362E-10"
|
||||
izz="1.24256890612907E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_proximal" />
|
||||
<child
|
||||
link="rh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_index_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208661081773556 -4.93451838476378E-06 0.0172736805321904"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253175497594429" />
|
||||
<inertia
|
||||
ixx="2.65989683690695E-07"
|
||||
ixy="-3.58343951791586E-11"
|
||||
ixz="4.31048601085216E-08"
|
||||
iyy="2.72915006047006E-07"
|
||||
iyz="1.75718024412593E-10"
|
||||
izz="8.56020467202518E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00052576 0.00634 0.1027"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940304809306 -4.5885743593238E-06 0.0194434523296449"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376786259758948" />
|
||||
<inertia
|
||||
ixx="3.221153658306E-07"
|
||||
ixy="1.02639617308432E-11"
|
||||
ixz="-1.14363547272711E-07"
|
||||
iyy="3.65130723083104E-07"
|
||||
iyz="-1.96904618797577E-10"
|
||||
izz="1.24256787913797E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_proximal" />
|
||||
<child
|
||||
link="rh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_middle_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208654311325356 -4.98538564003281E-06 0.0172736743497407"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253170963529411" />
|
||||
<inertia
|
||||
ixx="2.6598913795678E-07"
|
||||
ixy="-3.62757108675266E-11"
|
||||
ixz="4.31050611555507E-08"
|
||||
iyy="2.72914417061517E-07"
|
||||
iyz="1.75554984053478E-10"
|
||||
izz="8.56012458677515E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0010258 -0.011135 0.098767"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940273069729 -4.56628863591824E-06 0.0194435005686854"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0037678395356105" />
|
||||
<inertia
|
||||
ixx="3.22112632437858E-07"
|
||||
ixy="1.01848408913558E-11"
|
||||
ixz="-1.1436348915342E-07"
|
||||
iyy="3.65128262095686E-07"
|
||||
iyz="-1.96145632992445E-10"
|
||||
izz="1.24256284608064E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_proximal" />
|
||||
<child
|
||||
link="rh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_ring_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208649034130813 -5.02314582560837E-06 0.0172736680793697"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253167400540778" />
|
||||
<inertia
|
||||
ixx="2.65988718820404E-07"
|
||||
ixy="-3.66012295280295E-11"
|
||||
ixz="4.31052220484445E-08"
|
||||
iyy="2.72913936904813E-07"
|
||||
iyz="1.75447396222308E-10"
|
||||
izz="8.56006424720129E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 -0.028372 0.092741"
|
||||
rpy="0.087266 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.609333425"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940431519205 -4.55268314210333E-06 0.0194435341098305"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376782669873412" />
|
||||
<inertia
|
||||
ixx="3.22111112339498E-07"
|
||||
ixy="1.01707985908333E-11"
|
||||
ixz="-1.14363524419061E-07"
|
||||
iyy="3.65126916899176E-07"
|
||||
iyz="-1.95589215866356E-10"
|
||||
izz="1.24256004854426E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_proximal" />
|
||||
<child
|
||||
link="rh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.49597186651782"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_pinky_mcp_pitch"
|
||||
multiplier="0.904318245922221"
|
||||
offset="0" />
|
||||
</joint>
|
||||
</robot>
|
||||
@@ -0,0 +1,664 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
|
||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||
<robot
|
||||
name="linkerhand_o6_right">
|
||||
<material name="silver">
|
||||
<color rgba="0.5 0.5 0.52 1.0"/>
|
||||
</material>
|
||||
|
||||
<material name="BlackAccent">
|
||||
<color rgba="0.15 0.15 0.15 1.0"/>
|
||||
</material>
|
||||
<link
|
||||
name="rh_hand_base_link">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00160320773490556 0.000358462699237561 0.0538002704027215"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.06740077960995" />
|
||||
<inertia
|
||||
ixx="5.22359941041901E-05"
|
||||
ixy="3.0391535852764E-07"
|
||||
ixz="3.88322215371643E-07"
|
||||
iyy="3.33473043513648E-05"
|
||||
iyz="-7.77555280794861E-07"
|
||||
izz="2.28342677422006E-05" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/hand_base_link.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<link
|
||||
name="rh_thumb_metacarpals_base2">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00162795738393507 0.00276671978336815 -0.00184227725602707"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00138591070212997" />
|
||||
<inertia
|
||||
ixx="5.26294625624223E-08"
|
||||
ixy="-3.9288013799604E-09"
|
||||
ixz="2.43766268199571E-09"
|
||||
iyy="4.82623724532942E-08"
|
||||
iyz="3.71867754115443E-09"
|
||||
izz="2.88555522060562E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
<material name="BlackAccent"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals_base2.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_yaw"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.011508 0.022975 0.032794"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals_base2" />
|
||||
<axis
|
||||
xyz="0 0 -1" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.36"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_metacarpals">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="4.24920612856275E-05 -1.67885666835232E-05 0.0228341522590467"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0123381607727595" />
|
||||
<inertia
|
||||
ixx="1.10292488693766E-06"
|
||||
ixy="-6.14241939151719E-10"
|
||||
ixz="1.14233108676795E-07"
|
||||
iyy="1.76757658485787E-06"
|
||||
iyz="-4.24576599367025E-10"
|
||||
izz="9.36348143657406E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_metacarpals.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_cmc_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0061649 0.010678 -0.004891"
|
||||
rpy="0 -1.1529 -2.0944" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals_base2" />
|
||||
<child
|
||||
link="rh_thumb_metacarpals" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="0.58"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_thumb_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00413690727496815 -4.54842793429222E-07 0.0230097179163771"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00763302603723749" />
|
||||
<inertia
|
||||
ixx="1.30546842791578E-06"
|
||||
ixy="-2.61617511029467E-12"
|
||||
ixz="7.19030685242407E-08"
|
||||
iyy="1.22457212713176E-06"
|
||||
iyz="1.66931068485225E-11"
|
||||
izz="2.7729897944409E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/thumb_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_thumb_ip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0037776 0 0.045368"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_thumb_metacarpals" />
|
||||
<child
|
||||
link="rh_thumb_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.08"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_thumb_cmc_pitch"
|
||||
multiplier="1.86"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208665596033792 -4.8964990644329E-06 0.0172736718900068"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253178529301663" />
|
||||
<inertia
|
||||
ixx="2.65990159539482E-07"
|
||||
ixy="-3.55165625722842E-11"
|
||||
ixz="4.31046335852167E-08"
|
||||
iyy="2.72915460277804E-07"
|
||||
iyz="1.75935978708959E-10"
|
||||
izz="8.56026306687528E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 0.02419 0.098779"
|
||||
rpy="-0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_index_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_index_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940011630532 -4.59976557022623E-06 0.0194434136420913"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376787129082313" />
|
||||
<inertia
|
||||
ixx="3.22116619426455E-07"
|
||||
ixy="1.03152735699049E-11"
|
||||
ixz="-1.14363506430985E-07"
|
||||
iyy="3.65131844686317E-07"
|
||||
iyz="-1.97263639269362E-10"
|
||||
izz="1.24256890612907E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/index_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_index_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_index_proximal" />
|
||||
<child
|
||||
link="rh_index_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_index_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208661081773556 -4.93451838476378E-06 0.0172736805321904"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253175497594429" />
|
||||
<inertia
|
||||
ixx="2.65989683690695E-07"
|
||||
ixy="-3.58343951791586E-11"
|
||||
ixz="4.31048601085216E-08"
|
||||
iyy="2.72915006047006E-07"
|
||||
iyz="1.75718024412593E-10"
|
||||
izz="8.56020467202518E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.00052576 0.00634 0.1027"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_middle_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_middle_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940304809306 -4.5885743593238E-06 0.0194434523296449"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376786259758948" />
|
||||
<inertia
|
||||
ixx="3.221153658306E-07"
|
||||
ixy="1.02639617308432E-11"
|
||||
ixz="-1.14363547272711E-07"
|
||||
iyy="3.65130723083104E-07"
|
||||
iyz="-1.96904618797577E-10"
|
||||
izz="1.24256787913797E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/middle_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_middle_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_middle_proximal" />
|
||||
<child
|
||||
link="rh_middle_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_middle_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208654311325356 -4.98538564003281E-06 0.0172736743497407"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253170963529411" />
|
||||
<inertia
|
||||
ixx="2.6598913795678E-07"
|
||||
ixy="-3.62757108675266E-11"
|
||||
ixz="4.31050611555507E-08"
|
||||
iyy="2.72914417061517E-07"
|
||||
iyz="1.75554984053478E-10"
|
||||
izz="8.56012458677515E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0010258 -0.011135 0.098767"
|
||||
rpy="0.05236 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_ring_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_ring_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940273069729 -4.56628863591824E-06 0.0194435005686854"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.0037678395356105" />
|
||||
<inertia
|
||||
ixx="3.22112632437858E-07"
|
||||
ixy="1.01848408913558E-11"
|
||||
ixz="-1.1436348915342E-07"
|
||||
iyy="3.65128262095686E-07"
|
||||
iyz="-1.96145632992445E-10"
|
||||
izz="1.24256284608064E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/ring_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_ring_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_ring_proximal" />
|
||||
<child
|
||||
link="rh_ring_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_ring_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_proximal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="-0.00208649034130813 -5.02314582560837E-06 0.0172736680793697"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00253167400540778" />
|
||||
<inertia
|
||||
ixx="2.65988718820404E-07"
|
||||
ixy="-3.66012295280295E-11"
|
||||
ixz="4.31052220484445E-08"
|
||||
iyy="2.72913936904813E-07"
|
||||
iyz="1.75447396222308E-10"
|
||||
izz="8.56006424720129E-08" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_proximal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_mcp_pitch"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="0.0024758 -0.028372 0.092741"
|
||||
rpy="0.087266 0 0" />
|
||||
<parent
|
||||
link="rh_hand_base_link" />
|
||||
<child
|
||||
link="rh_pinky_proximal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.60"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
</joint>
|
||||
<link
|
||||
name="rh_pinky_distal">
|
||||
<inertial>
|
||||
<origin
|
||||
xyz="0.00658940431519205 -4.55268314210333E-06 0.0194435341098305"
|
||||
rpy="0 0 0" />
|
||||
<mass
|
||||
value="0.00376782669873412" />
|
||||
<inertia
|
||||
ixx="3.22111112339498E-07"
|
||||
ixy="1.01707985908333E-11"
|
||||
ixz="-1.14363524419061E-07"
|
||||
iyy="3.65126916899176E-07"
|
||||
iyz="-1.95589215866356E-10"
|
||||
izz="1.24256004854426E-07" />
|
||||
</inertial>
|
||||
<visual>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
<material name="silver"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<origin
|
||||
xyz="0 0 0"
|
||||
rpy="0 0 0" />
|
||||
<geometry>
|
||||
<mesh
|
||||
filename="meshes/pinky_distal.STL" />
|
||||
</geometry>
|
||||
</collision>
|
||||
</link>
|
||||
<joint
|
||||
name="rh_pinky_dip"
|
||||
type="revolute">
|
||||
<origin
|
||||
xyz="-0.0052516 0 0.036625"
|
||||
rpy="0 0 0" />
|
||||
<parent
|
||||
link="rh_pinky_proximal" />
|
||||
<child
|
||||
link="rh_pinky_distal" />
|
||||
<axis
|
||||
xyz="0 1 0" />
|
||||
<limit
|
||||
lower="0"
|
||||
upper="1.43"
|
||||
effort="100"
|
||||
velocity="1" />
|
||||
<mimic
|
||||
joint="rh_pinky_mcp_pitch"
|
||||
multiplier="0.89"
|
||||
offset="0" />
|
||||
</joint>
|
||||
</robot>
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../outputs/reports/O6
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o6_left_mujoco_plan.sh" "$@"
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
exec "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/scripts/run_o6_right_mujoco_plan.sh" "$@"
|
||||
Executable
+200
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:O6 左手标定 vs 未标定 URDF
|
||||
#
|
||||
# 未标定: /home/lxqs/linkerhand-urdf/o6/left
|
||||
# 标定: /home/lxqs/Linkerbot_URDF/06/LEFT(9/3 版,直接用 linker_hand_o6_left.xml)
|
||||
#
|
||||
# 两个窗口共用同一条 6 维 SDK 控制话题(默认 /cb_left_hand_control_cmd)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O6/scripts/run_o6_left_dual_compare.sh
|
||||
# ./hands/O6/scripts/run_o6_left_dual_compare.sh --pd-drive
|
||||
# ./hands/O6/scripts/run_o6_left_dual_compare.sh --cmd-topic /cb_left_hand_control_cmd --speed 1.0
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_UNCALIBRATED="$ROOT/hands/O6/reference/left_uncalibrated.urdf"
|
||||
URDF_CALIBRATED="$ROOT/hands/O6/reference/left_calibrated.urdf"
|
||||
PKG_O6="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_left"
|
||||
# 9/3 标定 MJCF:与 ./hands/O6/scripts/run_o6_left_mujoco_plan.sh 单开完全相同
|
||||
CALIB_XML="$PKG_O6/linker_hand_o6_left.xml"
|
||||
STOCK_XML="$PKG_O6/linker_hand_o6_left_stock.xml"
|
||||
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF (9/3): $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o6-dual] calibrated xml=$CALIB_XML (9/3, same as single-run)"
|
||||
echo "[o6-dual] build uncalibrated MJCF from $URDF_UNCALIBRATED"
|
||||
python3 - "$CALIB_XML" "$URDF_UNCALIBRATED" "$STOCK_XML" <<'PY'
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
template_xml = Path(sys.argv[1])
|
||||
urdf_uncal = Path(sys.argv[2])
|
||||
out_uncal = Path(sys.argv[3])
|
||||
|
||||
joint_body = {"lh_thumb_cmc_yaw": "lh_thumb_metacarpals_base2"}
|
||||
|
||||
|
||||
def parse_urdf_limits(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
jtype_m = re.search(r'type="([^"]+)"', attrs)
|
||||
if not jtype_m or jtype_m.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"rpy": rpy,
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, urdf_path: Path, model_name: str) -> str:
|
||||
joints = parse_urdf_limits(urdf_path)
|
||||
xml = template.replace(
|
||||
'model="linkerhand_o6_left"',
|
||||
f'model="{model_name}"',
|
||||
1,
|
||||
)
|
||||
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
r, p, y = info["rpy"]
|
||||
bname = joint_body.get(jname)
|
||||
if bname and abs(r) + abs(p) + abs(y) > 1e-9:
|
||||
w = math.cos(r * 0.5) * math.cos(p * 0.5) * math.cos(y * 0.5) + math.sin(
|
||||
r * 0.5
|
||||
) * math.sin(p * 0.5) * math.sin(y * 0.5)
|
||||
x = math.sin(r * 0.5) * math.cos(p * 0.5) * math.cos(y * 0.5) - math.cos(
|
||||
r * 0.5
|
||||
) * math.sin(p * 0.5) * math.sin(y * 0.5)
|
||||
yq = math.cos(r * 0.5) * math.sin(p * 0.5) * math.cos(y * 0.5) + math.sin(
|
||||
r * 0.5
|
||||
) * math.cos(p * 0.5) * math.sin(y * 0.5)
|
||||
z = math.cos(r * 0.5) * math.cos(p * 0.5) * math.sin(y * 0.5) - math.sin(
|
||||
r * 0.5
|
||||
) * math.sin(p * 0.5) * math.cos(y * 0.5)
|
||||
quat = f"{w:.9f} {x:.9f} {yq:.9f} {z:.9f}"
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)(>)'
|
||||
|
||||
def add_quat(m, quat=quat):
|
||||
tag = m.group(1)
|
||||
if 'quat="' in tag:
|
||||
tag = re.sub(r'quat="[^"]+"', f'quat="{quat}"', tag, count=1)
|
||||
else:
|
||||
tag = tag + f' quat="{quat}"'
|
||||
return tag + m.group(2)
|
||||
|
||||
xml = re.sub(bpat, add_quat, xml, count=1)
|
||||
elif bname:
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)\squat="[^"]+"([^>]*>)'
|
||||
xml = re.sub(bpat, r"\1\2", xml, count=1)
|
||||
|
||||
act_map = {
|
||||
"lh_thumb_cmc_yaw_pos": "lh_thumb_cmc_yaw",
|
||||
"lh_thumb_cmc_pitch_pos": "lh_thumb_cmc_pitch",
|
||||
"lh_index_mcp_pitch_pos": "lh_index_mcp_pitch",
|
||||
"lh_middle_mcp_pitch_pos": "lh_middle_mcp_pitch",
|
||||
"lh_ring_mcp_pitch_pos": "lh_ring_mcp_pitch",
|
||||
"lh_pinky_mcp_pitch_pos": "lh_pinky_mcp_pitch",
|
||||
}
|
||||
for act, jname in act_map.items():
|
||||
lo, hi = joints[jname]["lo"], joints[jname]["hi"]
|
||||
pat = rf'(<position name="{act}"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
return xml
|
||||
|
||||
|
||||
import mujoco
|
||||
|
||||
out_uncal.write_text(
|
||||
apply_urdf_to_mjcf(template_xml.read_text(), urdf_uncal, "linkerhand_o6_left_uncalibrated")
|
||||
)
|
||||
mujoco.MjModel.from_xml_path(str(out_uncal))
|
||||
print(f"[o6-dual] uncalibrated MJCF -> {out_uncal}")
|
||||
PY
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_UNCAL:-}" ]] && kill "$PID_UNCAL" 2>/dev/null || true
|
||||
[[ -n "${PID_CALIB:-}" ]] && kill "$PID_CALIB" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[o6-dual] launch uncalibrated window"
|
||||
"$ROOT/hands/O6/scripts/run_o6_left_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name o6_left_uncalibrated \
|
||||
--window-title "O6 left 未标定 (linkerhand-urdf)" \
|
||||
--sim-state-topic /sim/mujoco/o6/left/uncalibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_UNCAL=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[o6-dual] launch calibrated window (9/3 MJCF)"
|
||||
"$ROOT/hands/O6/scripts/run_o6_left_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name o6_left_calibrated \
|
||||
--window-title "O6 left 标定 (Linkerbot_URDF 9/3)" \
|
||||
--sim-state-topic /sim/mujoco/o6/left/calibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_CALIB=$!
|
||||
|
||||
echo "[o6-dual] both started. same cmd topic (default /cb_left_hand_control_cmd)."
|
||||
echo "[o6-dual] Ctrl+C stops both."
|
||||
wait "$PID_UNCAL" "$PID_CALIB"
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo O6 左手仿真桥
|
||||
# URDF/MJCF 来源: /home/lxqs/Linkerbot_URDF/06/LEFT(9/3 标定版)
|
||||
# 默认订阅 /cb_left_hand_control_cmd(6 维 SDK 0~255)
|
||||
# 发布 /sim/mujoco/o6/left/joint_state
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O6/scripts/run_o6_left_mujoco_plan.sh
|
||||
# ./hands/O6/scripts/run_o6_left_mujoco_plan.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_left/linker_hand_o6_left.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_left/linkerhand_o6_left.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing O6 left MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[o6-left] urdf=$URDF"
|
||||
echo "[o6-left] xml=$XML"
|
||||
echo "[o6-left] cmd-topic=/cb_left_hand_control_cmd"
|
||||
echo "[o6-left] sim-state=/sim/mujoco/o6/left/joint_state"
|
||||
echo "[o6-left] SDK 6ch: pitch, yaw, index, middle, ring, pinky"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.o6_left_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name o6_mujoco_plan_bridge_left \
|
||||
--window-title "O6 left" \
|
||||
--cmd-topic /cb_left_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/o6/left/joint_state \
|
||||
--nominal-topic /retarget/o6/left/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
# 同时开两个 MuJoCo:O6 右手标定 vs 未标定 URDF
|
||||
#
|
||||
# 未标定: /home/lxqs/linkerhand-urdf/o6/right
|
||||
# 标定: /home/lxqs/Linkerbot_URDF/06/RIGHT(直接用 linker_hand_o6_right.xml,与单开相同)
|
||||
#
|
||||
# 两个窗口共用同一条 6 维 SDK 控制话题(默认 /cb_right_hand_control_cmd)。
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O6/scripts/run_o6_right_dual_compare.sh
|
||||
# ./hands/O6/scripts/run_o6_right_dual_compare.sh --pd-drive
|
||||
# ./hands/O6/scripts/run_o6_right_dual_compare.sh --cmd-topic /cb_right_hand_control_cmd --speed 1.0
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
URDF_UNCALIBRATED="$ROOT/hands/O6/reference/right_uncalibrated.urdf"
|
||||
URDF_CALIBRATED="$ROOT/hands/O6/reference/right_calibrated.urdf"
|
||||
PKG_O6="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_right"
|
||||
CALIB_XML="$PKG_O6/linker_hand_o6_right.xml"
|
||||
STOCK_XML="$PKG_O6/linker_hand_o6_right_stock.xml"
|
||||
|
||||
if [[ ! -f "$URDF_UNCALIBRATED" ]]; then
|
||||
echo "[error] missing uncalibrated URDF: $URDF_UNCALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$URDF_CALIBRATED" ]]; then
|
||||
echo "[error] missing calibrated URDF: $URDF_CALIBRATED" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$CALIB_XML" ]]; then
|
||||
echo "[error] missing calibrated MJCF: $CALIB_XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
echo "[o6-right-dual] calibrated xml=$CALIB_XML (same as single-run)"
|
||||
echo "[o6-right-dual] build uncalibrated MJCF from $URDF_UNCALIBRATED"
|
||||
python3 - "$CALIB_XML" "$URDF_UNCALIBRATED" "$STOCK_XML" <<'PY'
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
template_xml = Path(sys.argv[1])
|
||||
urdf_uncal = Path(sys.argv[2])
|
||||
out_uncal = Path(sys.argv[3])
|
||||
|
||||
joint_body = {"rh_thumb_cmc_yaw": "rh_thumb_metacarpals_base2"}
|
||||
|
||||
|
||||
def parse_urdf_limits(path: Path) -> dict[str, dict]:
|
||||
text = path.read_text()
|
||||
joints: dict[str, dict] = {}
|
||||
for m in re.finditer(r"<joint\b([^>]*)>(.*?)</joint>", text, re.S):
|
||||
attrs, body = m.group(1), m.group(2)
|
||||
name_m = re.search(r'name="([^"]+)"', attrs)
|
||||
if not name_m:
|
||||
continue
|
||||
name = name_m.group(1)
|
||||
jtype_m = re.search(r'type="([^"]+)"', attrs)
|
||||
if not jtype_m or jtype_m.group(1) != "revolute":
|
||||
continue
|
||||
origin = re.search(r'<origin[^>]*xyz="([^"]+)"[^>]*rpy="([^"]+)"', body)
|
||||
lim = re.search(r'lower="([^"]+)"[^>]*upper="([^"]+)"', body)
|
||||
rpy = [float(x) for x in origin.group(2).split()] if origin else [0.0, 0.0, 0.0]
|
||||
joints[name] = {
|
||||
"lo": float(lim.group(1)),
|
||||
"hi": float(lim.group(2)),
|
||||
"rpy": rpy,
|
||||
}
|
||||
return joints
|
||||
|
||||
|
||||
def rpy_to_quat(r: float, p: float, y: float) -> tuple[float, float, float, float]:
|
||||
cr, sr = math.cos(r * 0.5), math.sin(r * 0.5)
|
||||
cp, sp = math.cos(p * 0.5), math.sin(p * 0.5)
|
||||
cy, sy = math.cos(y * 0.5), math.sin(y * 0.5)
|
||||
w = cr * cp * cy + sr * sp * sy
|
||||
x = sr * cp * cy - cr * sp * sy
|
||||
yq = cr * sp * cy + sr * cp * sy
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
return w, x, yq, z
|
||||
|
||||
|
||||
def apply_urdf_to_mjcf(template: str, urdf_path: Path, model_name: str) -> str:
|
||||
joints = parse_urdf_limits(urdf_path)
|
||||
xml = template.replace(
|
||||
'model="linkerhand_o6_right"',
|
||||
f'model="{model_name}"',
|
||||
1,
|
||||
)
|
||||
|
||||
for jname, info in joints.items():
|
||||
lo, hi = info["lo"], info["hi"]
|
||||
pat = rf'(<joint name="{re.escape(jname)}"[^>]*\srange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
r, p, y = info["rpy"]
|
||||
bname = joint_body.get(jname)
|
||||
if bname and abs(r) + abs(p) + abs(y) > 1e-9:
|
||||
w, x, yq, z = rpy_to_quat(r, p, y)
|
||||
quat = f"{w:.9f} {x:.9f} {yq:.9f} {z:.9f}"
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)(>)'
|
||||
|
||||
def add_quat(m, quat=quat):
|
||||
tag = m.group(1)
|
||||
if 'quat="' in tag:
|
||||
tag = re.sub(r'quat="[^"]+"', f'quat="{quat}"', tag, count=1)
|
||||
else:
|
||||
tag = tag + f' quat="{quat}"'
|
||||
return tag + m.group(2)
|
||||
|
||||
xml = re.sub(bpat, add_quat, xml, count=1)
|
||||
elif bname:
|
||||
bpat = rf'(<body name="{re.escape(bname)}"[^>]*)\squat="[^"]+"([^>]*>)'
|
||||
xml = re.sub(bpat, r"\1\2", xml, count=1)
|
||||
|
||||
act_map = {
|
||||
"rh_thumb_cmc_yaw_pos": "rh_thumb_cmc_yaw",
|
||||
"rh_thumb_cmc_pitch_pos": "rh_thumb_cmc_pitch",
|
||||
"rh_index_mcp_pitch_pos": "rh_index_mcp_pitch",
|
||||
"rh_middle_mcp_pitch_pos": "rh_middle_mcp_pitch",
|
||||
"rh_ring_mcp_pitch_pos": "rh_ring_mcp_pitch",
|
||||
"rh_pinky_mcp_pitch_pos": "rh_pinky_mcp_pitch",
|
||||
}
|
||||
for act, jname in act_map.items():
|
||||
lo, hi = joints[jname]["lo"], joints[jname]["hi"]
|
||||
pat = rf'(<position name="{act}"[^>]*\sctrlrange=")([^"]+)(")'
|
||||
xml = re.sub(
|
||||
pat,
|
||||
lambda m, lo=lo, hi=hi: f"{m.group(1)}{lo} {hi}{m.group(3)}",
|
||||
xml,
|
||||
count=1,
|
||||
)
|
||||
return xml
|
||||
|
||||
|
||||
import mujoco
|
||||
|
||||
out_uncal.write_text(
|
||||
apply_urdf_to_mjcf(template_xml.read_text(), urdf_uncal, "linkerhand_o6_right_uncalibrated")
|
||||
)
|
||||
mujoco.MjModel.from_xml_path(str(out_uncal))
|
||||
print(f"[o6-right-dual] uncalibrated MJCF -> {out_uncal}")
|
||||
PY
|
||||
|
||||
EXTRA=("$@")
|
||||
|
||||
cleanup() {
|
||||
[[ -n "${PID_UNCAL:-}" ]] && kill "$PID_UNCAL" 2>/dev/null || true
|
||||
[[ -n "${PID_CALIB:-}" ]] && kill "$PID_CALIB" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[o6-right-dual] launch uncalibrated window"
|
||||
"$ROOT/hands/O6/scripts/run_o6_right_mujoco_plan.sh" \
|
||||
--xml "$STOCK_XML" \
|
||||
--mapping-urdf "$URDF_UNCALIBRATED" \
|
||||
--node-name o6_right_uncalibrated \
|
||||
--window-title "O6 right 未标定 (linkerhand-urdf)" \
|
||||
--sim-state-topic /sim/mujoco/o6/right/uncalibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_UNCAL=$!
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "[o6-right-dual] launch calibrated window"
|
||||
"$ROOT/hands/O6/scripts/run_o6_right_mujoco_plan.sh" \
|
||||
--xml "$CALIB_XML" \
|
||||
--mapping-urdf "$URDF_CALIBRATED" \
|
||||
--node-name o6_right_calibrated \
|
||||
--window-title "O6 right 标定 (Linkerbot_URDF)" \
|
||||
--sim-state-topic /sim/mujoco/o6/right/calibrated/joint_state \
|
||||
"${EXTRA[@]}" &
|
||||
PID_CALIB=$!
|
||||
|
||||
echo "[o6-right-dual] both started. same cmd topic (default /cb_right_hand_control_cmd)."
|
||||
echo "[o6-right-dual] Ctrl+C stops both."
|
||||
wait "$PID_UNCAL" "$PID_CALIB"
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# MuJoCo O6 右手仿真桥
|
||||
# URDF 来源: /home/lxqs/下载/linkerhand_o6_right_O6_RIGHT_001_partial_zero_calibrated+copy.urdf
|
||||
# 默认订阅 /cb_right_hand_control_cmd(与 SDK / GUI 一致,6 维 SDK 0~255)
|
||||
# 发布 /sim/mujoco/o6/right/joint_state
|
||||
#
|
||||
# 用法:
|
||||
# ./hands/O6/scripts/run_o6_right_mujoco_plan.sh
|
||||
# ./hands/O6/scripts/run_o6_right_mujoco_plan.sh --pd-drive
|
||||
set -eo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
if [[ -f "$ROOT/install/setup.bash" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
fi
|
||||
set -u
|
||||
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
PKG_SRC="$ROOT/src/linkerhand-sim/linker_hand_mujoco_ros2"
|
||||
export PYTHONPATH="$PKG_SRC${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
XML="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_right/linker_hand_o6_right.xml"
|
||||
URDF="$PKG_SRC/linker_hand_mujoco_ros2/urdf/O6/linker_hand_o6_right/linkerhand_o6_right.urdf"
|
||||
if [[ ! -f "$XML" ]]; then
|
||||
echo "[error] missing O6 MJCF: $XML" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[o6-right] urdf=$URDF"
|
||||
echo "[o6-right] xml=$XML"
|
||||
echo "[o6-right] cmd-topic=/cb_right_hand_control_cmd"
|
||||
echo "[o6-right] sim-state=/sim/mujoco/o6/right/joint_state"
|
||||
echo "[o6-right] SDK 6ch: pitch, yaw, index, middle, ring, pinky"
|
||||
|
||||
exec python3 -m linker_hand_mujoco_ros2.o6_plan_bridge \
|
||||
--xml "$XML" \
|
||||
--node-name o6_mujoco_plan_bridge_right \
|
||||
--window-title "O6 right" \
|
||||
--cmd-topic /cb_right_hand_control_cmd \
|
||||
--sim-state-topic /sim/mujoco/o6/right/joint_state \
|
||||
--nominal-topic /retarget/o6/right/joint_target_nominal \
|
||||
--mapping g20_urdf \
|
||||
"$@"
|
||||
@@ -0,0 +1,69 @@
|
||||
# 按手型启动 MuJoCo
|
||||
|
||||
这里是新的日常使用入口。根目录统一使用 `run.sh`;旧 `run_*.sh` 已归档到 `archive/launchers/`。URDF、网格不复制成第二份运行资产:各目录的 `assets` 是指向包内原资产的相对符号链接。
|
||||
|
||||
## 启动
|
||||
|
||||
在工程根目录执行:
|
||||
|
||||
```bash
|
||||
./hands/G20/run_left.sh
|
||||
./hands/G20/run_right.sh
|
||||
./hands/O6/run_left.sh
|
||||
./hands/O6/run_right.sh
|
||||
./hands/L6/run_left.sh
|
||||
./hands/L6/run_right.sh
|
||||
./hands/O12/run_right.sh
|
||||
./hands/O30/run_left.sh
|
||||
./hands/O30/run_right.sh
|
||||
```
|
||||
|
||||
常用双窗入口为各手型的 `compare_left.sh` / `compare_right.sh`。完整实现及关节监视脚本放在各手型 `scripts/` 中。G20/O6/L6 双窗所需原始对照 URDF 已快照到各自 `reference/`,来源和散列见 `reference_sources.json`;这些文件用于配合包内模板生成对照窗口,不是独立网格资产包。G20 的 L20 对照改用包内已有资产,O12 对照改用工程内 `assets/vendor/Linkerbot_URDF/012/right`。O12 当前只有右手入口。
|
||||
`hands/L20_V10.1/assets` 是 G20 双窗对照所用的原版 L20 模型。
|
||||
O30 V5~V9 旧入口放在 `hands/O30/legacy`;历史 URDF 保留,但历史主动分段映射不再执行。
|
||||
`hands/legacy/run_sim.sh` 保留旧 ROS launch 接口;日常使用优先选择上方按手型的桥接器。
|
||||
|
||||
## 映射规则
|
||||
|
||||
- 主动关节不查 JSON 角度表,使用实际加载的 URDF 派生 MJCF 关节限位线性换算。通道顺序、正反方向属于 SDK 协议,继续保留。
|
||||
- G20/O6/L6/O30 的 SDK 输入仍为 0~255;O12 `/o12/right/joint_cmd` 仍为 12 路 SDK 弧度,不要发送 0~255 数组。
|
||||
- 被动关节默认读取对应 URDF 的 `mimic` 比例和偏移。
|
||||
- G20 左手默认额外使用 `G20/calibration/left_passive.json`:文件只包含被动关节相对于主关节角度的曲线,没有主动命令查表。缺失时明确提示并回退到 URDF mimic。
|
||||
- G20 右手保持默认 URDF 线性 mimic;如需现有右手被动曲线,可以显式指定 `--passive-json`。
|
||||
- O30 没有被动关节,保持全主动线性;V10 几何和关节参数未修改。
|
||||
- 运行时不再因为导入公共函数而读取 G20 JSON。其余手型不需要 G20 的标定文件。
|
||||
|
||||
G20 被动曲线开关示例:
|
||||
|
||||
```bash
|
||||
# 左手全部采用 URDF 线性关系,包括被动关节
|
||||
./hands/G20/run_left.sh --passive-json none
|
||||
|
||||
# 右手主动线性,被动使用已有标定联动曲线
|
||||
./hands/G20/run_right.sh --passive-json "$PWD/hands/G20/calibration/right_passive.json"
|
||||
```
|
||||
|
||||
旧 `--mapping g20_calibrated` 等名称作为兼容别名保留,含义已调整为“主动线性 + 可选被动曲线”,不再代表主动查表。切换后 G20 左手同一 SDK 指令的姿态可能不同于旧标定查表结果。
|
||||
|
||||
## 资产与配置
|
||||
|
||||
`assets` 中有历史版本;正常单窗使用所在手型当前 MJCF 和对应的标准 URDF 文件,不按修改时间猜测“最新版本”。O30 当前仍由其启动脚本从指定 V10 URDF 生成模型。
|
||||
其他手型现有单窗读取已经生成的 MJCF;修改 URDF 后需同步生成 MJCF,不能只改 URDF 文本就期待已有 XML 自动变化。此次已核对常用 SDK 手型当前 URDF 与 MJCF 关节限位一致。
|
||||
|
||||
自定义/双窗模型通过 `--mapping-urdf PATH` 明确指定 passive mimic 来源;主动限位始终与实际仿真的模型一致。双窗脚本已传入各自 URDF,避免套用另一窗口的联动比例。O12 旧 `--o12-urdf` 参数继续兼容。
|
||||
|
||||
被动 JSON 的精简格式为 `schema_version: 1`、`passive_maps`;每个条目包含 `master`、`master_rad`、`passive_rad`。只允许描述 URDF 中的被动关节。旧 JSON 的显式导入仍可用于转换被动联动:其中主关节曲线只用作被动曲线横坐标,绝不用于主动命令映射。
|
||||
|
||||
## 备份与测试
|
||||
|
||||
本轮前的启动脚本、Python 驱动及完整包内 URDF/网格保存在:
|
||||
`archive/backups/before_hand_layout_20260928_102428/`。
|
||||
历史测试文件也已保存。备份用于恢复旧行为,不建议与新映射代码混用。
|
||||
|
||||
```bash
|
||||
PYTHONDONTWRITEBYTECODE=1 venv/bin/python -B tests/test_hand_mapping_policy.py
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
PYTHONPATH="$PWD/venv/lib/python3.12/site-packages:$PYTHONPATH" python3 tools/o30_right_calibration/test_calibration.py
|
||||
```
|
||||
|
||||
本轮是驱动与目录整理,不是重新标定真机。没有向真机话题发指令。
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# 本机启动左手 O6 MuJoCo 仿真(ROS2 用系统 Python,依赖从 venv/user site 补齐)
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
# ROS2
|
||||
# shellcheck disable=SC1091
|
||||
source /opt/ros/jazzy/setup.bash
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT/install/setup.bash"
|
||||
|
||||
# 多机通信
|
||||
export ROS_DOMAIN_ID="${ROS_DOMAIN_ID:-30}"
|
||||
export ROS_LOCALHOST_ONLY=0
|
||||
|
||||
# ros2 launch 走系统 python3;把 venv 的 site-packages 挂上(含 mujoco/PyQt5)
|
||||
VENV_SITE="$ROOT/venv/lib/python3.12/site-packages"
|
||||
if [[ -d "$VENV_SITE" ]]; then
|
||||
export PYTHONPATH="$VENV_SITE${PYTHONPATH:+:$PYTHONPATH}"
|
||||
fi
|
||||
|
||||
exec ros2 launch linker_hand_mujoco_ros2 linker_hand_mujoco_ros2.launch.py "$@"
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"hands/O6/reference/left_uncalibrated.urdf": {
|
||||
"source": "/home/lxqs/linkerhand-urdf/o6/left/linkerhand_o6_left.urdf",
|
||||
"sha256": "0bc0162a9dc0c2d57f68477a67e5ba88d1baf0b67eb8ad2de8556ed7b62114de"
|
||||
},
|
||||
"hands/O6/reference/left_calibrated.urdf": {
|
||||
"source": "/home/lxqs/Linkerbot_URDF/06/LEFT/linkerhand_o6_left.urdf",
|
||||
"sha256": "35b6a350119fc4c8162f8a1c40aa515e6a9f0562e8349cfcc0214c7dd02a884e"
|
||||
},
|
||||
"hands/O6/reference/right_uncalibrated.urdf": {
|
||||
"source": "/home/lxqs/linkerhand-urdf/o6/right/linkerhand_o6_right.urdf",
|
||||
"sha256": "8f184faad699fbf771e388f109a4e8793b5cb190c33a87b2eba8491a3a37dd62"
|
||||
},
|
||||
"hands/O6/reference/right_calibrated.urdf": {
|
||||
"source": "/home/lxqs/Linkerbot_URDF/06/RIGHT/linkerhand_o6_right.urdf",
|
||||
"sha256": "aa07cb443d085dade54069cd487c3d1bfc4aac9da54f9880adf33c1923a43aaa"
|
||||
},
|
||||
"hands/L6/reference/left_uncalibrated.urdf": {
|
||||
"source": "/home/lxqs/linkerhand-urdf/l6/left/linkerhand_l6v3.1_left.urdf",
|
||||
"sha256": "b7d83f5423c64d62c50bf5ca73f96210e2032b9531c816a3955bab7a51d13c54"
|
||||
},
|
||||
"hands/L6/reference/left_calibrated.urdf": {
|
||||
"source": "/home/lxqs/Linkerbot_URDF/L6/LEFT/linkerhand_l6_left.urdf",
|
||||
"sha256": "23110486b970604ca6d88bb29a5e6543d3f66361ce528cf767cbe41e6751443c"
|
||||
},
|
||||
"hands/L6/reference/right_uncalibrated.urdf": {
|
||||
"source": "/home/lxqs/linkerhand-urdf/l6/right/linkerhand_l6v3.1_right.urdf",
|
||||
"sha256": "298c1fbf5189648911426f530b50bdbeea4830cab9c54e20f46c532485df4666"
|
||||
},
|
||||
"hands/L6/reference/right_calibrated.urdf": {
|
||||
"source": "/home/lxqs/Linkerbot_URDF/L6/RIGHT/linkerhand_l6_right.urdf",
|
||||
"sha256": "614fc9df0d44fa0cc66770b0361c5037fc56c4dd5e59176204f9b29dc99b387d"
|
||||
},
|
||||
"hands/G20/reference/left_calibrated.urdf": {
|
||||
"source": "/home/lxqs/图片/linkerhand_g20_left_tag.urdf",
|
||||
"sha256": "93ef571430a15a229f221b53c09747c1c94a5c8d228ababd979c717f1d5f1a5a"
|
||||
},
|
||||
"hands/G20/reference/right_calibrated.urdf": {
|
||||
"source": "/home/lxqs/音乐/linkerhand_G20_RIGHT_tag.urdf",
|
||||
"sha256": "d46d3ca2f51f8932854f5090d0bf7f813ffa41501f68e534fc4f760e959cb496"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user