I am trying to add a model of a wsg-like gripper in Drake from an SDF file. The gripper has 2 joints:
My goal is to make this model have 1 DOF:
That is, when I add only this SDF model to my plant, I want plant.num_position()
to return 1, and when I edit the joint value for the left finger, I want the right finger to be displaced by the same value times -1.
How do I do this in Drake?
Is it something I need to set up in the .sdf file or with additional programming and constraints?
I have tried to use the <mimic> tag in the sdf file, but when running plant.num_positions(), it still counts both finger joints.
These are the joints I have defined in my .sdf file:
<joint name="left_finger_sliding_joint" type="prismatic">
<parent>body</parent>
<child>left_finger</child>
<axis>
<xyz>-1 0 0</xyz>
<!-- Drake attaches an actuator to all and only joints with a nonzero
effort limit. -->
<limit>
<lower>-0.055</lower>
<upper>0</upper>
<effort>80</effort>
<stiffness>15000</stiffness>
</limit>
<dynamics>
<spring_reference>0</spring_reference>
<spring_stiffness>0</spring_stiffness>
<damping>0</damping>
<friction>0</friction>
</dynamics>
</axis>
</joint>
<joint name="right_finger_sliding_joint" type="prismatic">
<parent>body</parent>
<child>right_finger</child>
<axis>
<xyz>1 0 0</xyz>
<!-- Drake attaches an actuator to all and only joints with a nonzero
effort limit. -->
<limit>
<lower>0</lower>
<upper>0.055</upper>
<effort>80</effort>
<stiffness>15000</stiffness>
</limit>
<!-- Mimic the left finger sliding joint. This will make the right
finger move in the opposite direction of the left finger.
This will reduce the dimensionality of the gripper's configuration -->
<mimic joint="left_finger_sliding_joint">
<multiplier>-1.</multiplier>
<offset>0.</offset>
<reference>0.</reference>
</mimic>
<dynamics>
<spring_reference>0</spring_reference>
<spring_stiffness>0</spring_stiffness>
<damping>0</damping>
<friction>0</friction>
</dynamics>
</axis>
</joint>
Another option I have considered is welding the right_finger joint to the main body, but this would not achieve the symmetry with the left_finger.
Using the <mimic>
tag (in sdf, or we also support it in urdf) is the recommended approach, and should give you the dynamics that you want. But you are correct that it does not reduce the num_positions()
. The implementation creates both joints but implements the mimic as a constraint which the dynamics engine enforces when you step the dynamics.
You can use MultibodyPlant::GetPositionNames()
and the similar accessors for velocities and actuators to help index in and find the subset of the positions that you need.