Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions python/py_package/wrapper/articulation_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ def build(
root = joint.parent_link
articulation.create_fixed_tendon(
[root, joint.child_link, mimic_joint.child_link],
[0, -multiplier, 1],
[0, -1 / multiplier, 1],
[0, 1, -multiplier],
[0, 1, -1 / multiplier],
rest_length=offset,
stiffness=1e5,
)
Expand Down
51 changes: 51 additions & 0 deletions unittest/test_physx/test_articulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import tempfile
import unittest
from pathlib import Path

Expand Down Expand Up @@ -72,6 +73,56 @@ def test_urdf_loader(self):
robot.set_qf(q)
self.assertTrue(np.allclose(robot.get_qf(), q))

def test_urdf_mimic_sibling_multiplier_offset(self):
inertial = (
'<inertial><mass value="0.1"/><origin xyz="0 0 0"/>'
'<inertia ixx="0.001" iyy="0.001" izz="0.001" ixy="0" ixz="0" iyz="0"/>'
"</inertial>"
)
limit = '<limit lower="-10" upper="10" effort="100" velocity="100"/>'
urdf = f"""<robot name="mimic_sibling">
<link name="base">{inertial}</link>
<link name="source_link">{inertial}</link>
<link name="follower_link">{inertial}</link>
<joint name="source" type="revolute">
<parent link="base"/><child link="source_link"/>
<axis xyz="0 0 1"/>{limit}
</joint>
<joint name="follower" type="revolute">
<parent link="base"/><child link="follower_link"/>
<axis xyz="0 0 1"/>{limit}
<mimic joint="source" multiplier="2.0" offset="0.1"/>
</joint>
</robot>"""
with tempfile.TemporaryDirectory() as d:
path = Path(d) / "mimic_sibling.urdf"
path.write_text(urdf)

scene = sapien.Scene()
scene.set_timestep(1 / 240)
loader = scene.create_urdf_loader()
loader.fix_root_link = True
robot = loader.load(str(path))

joints = {j.get_name(): j for j in robot.get_active_joints()}
joints["source"].set_drive_property(
stiffness=5000, damping=500, force_limit=100000
)
joints["source"].set_drive_target(0.4)
joints["follower"].set_drive_property(stiffness=0, damping=0, force_limit=0)
for _ in range(720):
scene.step()

qpos = {
j.get_name(): robot.get_qpos()[i]
for i, j in enumerate(robot.get_active_joints())
}
self.assertAlmostEqual(
qpos["follower"],
2.0 * qpos["source"] + 0.1,
delta=1e-3,
)

def test_kinematics_dynamics(self):
scene = sapien.Scene()
loader = scene.create_urdf_loader()
Expand Down