Skip to content

Commit fa202b4

Browse files
committed
Add as_rotation_matrix argument; allow tool joint to be fixed.
1 parent b4944fa commit fa202b4

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

pyb_utils/robots.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class Robot:
2121
The number of actuated (i.e., controlled) joints. This should never be
2222
more than `num_joints`.
2323
tool_idx : int
24-
The index of the tool joint.
24+
The index of the tool joint. Note that this corresponds to the tool
25+
link, since each link has the same index as its parent joint.
2526
2627
Parameters
2728
----------
@@ -48,15 +49,19 @@ def __init__(
4849

4950
n = pyb.getNumJoints(uid)
5051

51-
# first build a dict of the non-fixed joints' info
52-
self._joint_indices = []
52+
# build a dict of all joint info
5353
joint_info = {}
5454
for i in range(n):
5555
info = getJointInfo(uid, i, decode="utf-8")
56+
joint_info[info.jointName] = info
57+
58+
# record indices of all non-fixed joints
59+
self._joint_indices = []
60+
for name in joint_info:
61+
info = joint_info[name]
5662
if info.jointType == pyb.JOINT_FIXED:
5763
continue
58-
joint_info[info.jointName] = info
59-
self._joint_indices.append(i)
64+
self._joint_indices.append(info.jointIndex)
6065
self.num_joints = len(self._joint_indices)
6166

6267
if actuated_joints is None:
@@ -173,7 +178,7 @@ def command_effort(self, u):
173178
forces=list(u),
174179
)
175180

176-
def get_link_com_pose(self, link_idx=None):
181+
def get_link_com_pose(self, link_idx=None, as_rotation_matrix=False):
177182
"""Get the pose of a link's center of mass.
178183
179184
The pose is computed about the link's center of mass with respect to
@@ -204,22 +209,29 @@ def get_link_com_pose(self, link_idx=None):
204209
link_idx :
205210
Index of the link to use. If not provided, defaults to the end
206211
effector ``self.tool_idx``.
212+
as_rotation_matrix : bool
213+
Set to ``True`` to return the orientation as a rotation matrix,
214+
``False`` to return a quaternion.
207215
208216
Returns
209217
-------
210218
:
211-
A tuple containing the position and orientation quaternion of the
212-
link's center of mass in the world frame. The quaternion is
213-
represented in xyzw order.
219+
A tuple containing the position and orientation of the link's
220+
center of mass in the world frame. If ``as_rotation_matrix=True``,
221+
then the orientation is represented as a :math:`3\\times3` rotation
222+
matrix. If ``False``, then it is represented as a quaternion in
223+
xyzw order.
214224
"""
215225
if link_idx is None:
216226
link_idx = self.tool_idx
217227
state = getLinkState(self.uid, link_idx, computeForwardKinematics=True)
218-
return np.array(state.linkWorldPosition), np.array(
219-
state.linkWorldOrientation
220-
)
228+
position = np.array(state.linkWorldPosition)
229+
orientation = np.array(state.linkWorldOrientation)
230+
if as_rotation_matrix:
231+
orientation = quaternion_to_matrix(orientation)
232+
return position, orientation
221233

222-
def get_link_frame_pose(self, link_idx=None):
234+
def get_link_frame_pose(self, link_idx=None, as_rotation_matrix=False):
223235
"""Get the pose of a link's URDF frame.
224236
225237
The pose is computed about the link's parent joint position, which is
@@ -230,20 +242,26 @@ def get_link_frame_pose(self, link_idx=None):
230242
link_idx :
231243
Index of the link to use. If not provided, defaults to the end
232244
effector ``self.tool_idx``.
245+
as_rotation_matrix : bool
246+
Set to ``True`` to return the orientation as a rotation matrix,
247+
``False`` to return a quaternion.
233248
234249
Returns
235250
-------
236251
:
237-
A tuple containing the position and orientation quaternion of the
238-
link's frame with respect to the world. The quaternion is
239-
represented in xyzw order.
252+
A tuple containing the position and orientation of the link's frame
253+
with respect to the world. If ``as_rotation_matrix=True``, then the
254+
orientation is represented as a :math:`3\\times3` rotation matrix.
255+
If ``False``, then it is represented as a quaternion in xyzw order.
240256
"""
241257
if link_idx is None:
242258
link_idx = self.tool_idx
243259
state = getLinkState(self.uid, link_idx, computeForwardKinematics=True)
244-
return np.array(state.worldLinkFramePosition), np.array(
245-
state.worldLinkFrameOrientation
246-
)
260+
position = np.array(state.worldLinkFramePosition)
261+
orientation = np.array(state.worldLinkFrameOrientation)
262+
if as_rotation_matrix:
263+
orientation = quaternion_to_matrix(orientation)
264+
return position, orientation
247265

248266
def get_link_com_velocity(self, link_idx=None):
249267
"""Get the velocity of a link's center of mass with respect to the world.

tests/test_robot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,10 @@ def test_robot_link_pose():
9797
robot.reset_joint_configuration([np.pi / 2, 0, 0, 0, 0, 0, 0])
9898
r1, Q1 = robot.get_link_frame_pose()
9999
C1 = pyb_utils.quaternion_to_matrix(Q1)
100+
C1_0 = robot.get_link_frame_pose(as_rotation_matrix=True)[1]
100101
assert np.allclose(r0, r1)
101102
assert np.allclose(Q1, pyb_utils.quaternion_multiply(Qz, Q0))
103+
assert np.allclose(C1, C1_0)
102104

103105
r1_com = robot.get_link_com_pose()[0]
104106
assert np.allclose(r1_com, r1 + C1 @ offset)

0 commit comments

Comments
 (0)