Skip to content

Commit cc1851a

Browse files
committed
Merge branch 'master' of https://github.com/petercorke/robotics-toolbox-python into micah-dev
2 parents b2cda42 + 9883202 commit cc1851a

File tree

6 files changed

+402
-110
lines changed

6 files changed

+402
-110
lines changed

roboticstoolbox/models/URDF/UR3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ def __init__(self):
3232
"ur_description/urdf/ur3_joint_limited_robot.urdf.xacro")
3333

3434
super().__init__(
35-
args[0].upper(),
36-
name=args[1],
35+
args[0],
36+
name=args[1].upper(),
3737
manufacturer='Universal Robotics'
3838
)
3939

roboticstoolbox/robot/ELink.py

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
"""
55

66
# import numpy as np
7-
from spatialmath import SE3
7+
from spatialmath import SE3, SE2, SMPose
88
# from spatialmath.base.argcheck import getvector, verifymatrix, isscalar
99
import roboticstoolbox as rp
10-
from roboticstoolbox.robot.ETS import ETS
10+
from roboticstoolbox.robot.ETS import ETS, SuperETS
1111
from roboticstoolbox.robot.Link import Link
1212

1313

@@ -41,7 +41,15 @@ class ELink(Link):
4141
4242
It inherits from the Link class which provides common functionality such
4343
as joint and link such as kinematics parameters,
44-
.
44+
45+
46+
The transform to the next link is given as an ETS with the joint
47+
variable, if present, as the last term. This is preprocessed and
48+
the object stores:
49+
50+
* ``Ts`` the constant part as a NumPy array, or None
51+
* ``v`` a pointer to an ETS object representing the joint variable.
52+
or None
4553
4654
:references:
4755
- Kinematic Derivatives using the Elementary Transform Sequence,
@@ -62,11 +70,12 @@ def __init__(
6270
super(ELink, self).__init__(**kwargs)
6371

6472
# check we have an ETS
65-
if isinstance(ets, ETS):
66-
self._ets = ets
67-
else:
73+
if not isinstance(ets, SuperETS):
6874
raise TypeError(
6975
'The ets argument must be of type ETS')
76+
self._ndims = ets._ndims
77+
78+
self._ets = ets
7079

7180
if v is None and len(ets) > 0 and ets[-1].isjoint:
7281
v = ets.pop()
@@ -76,10 +85,10 @@ def __init__(
7685
jindex = v.jindex
7786

7887
# TODO simplify this logic, can be ELink class or None
79-
if isinstance(parent, list):
80-
raise TypeError(
81-
'Only one parent link can be present')
82-
elif not isinstance(parent, ELink) and parent is not None:
88+
# if isinstance(parent, list):
89+
# raise TypeError(
90+
# 'Only one parent link can be present')
91+
if not isinstance(parent, ELink) and parent is not None:
8392
raise TypeError(
8493
'Parent must be of type ELink')
8594

@@ -95,7 +104,7 @@ def __init__(
95104
# Check the variable joint
96105
if v is None:
97106
self._joint = False
98-
elif not isinstance(v, ETS):
107+
elif not isinstance(v, SuperETS):
99108
raise TypeError('v must be of type ETS')
100109
elif not v[0].isjoint:
101110
raise ValueError('v must be a variable ETS')
@@ -111,20 +120,28 @@ def _init_Ts(self):
111120
# Number of transforms in the ETS excluding the joint variable
112121
self._M = len(self._ets)
113122

114-
# Initialise joints
115-
if isinstance(self._ets, ETS):
116-
self._Ts = SE3()
117-
for i in range(self.M):
118-
if self._ets[i].isjoint:
123+
# Compute the leading, constant, part of the ETS
124+
# TODO probably should use ETS.compile()
125+
126+
if isinstance(self._ets, SuperETS):
127+
first = True
128+
T = None
129+
130+
for et in self._ets:
131+
# constant transforms only
132+
if et.isjoint:
119133
raise ValueError('The transforms in ets must be constant')
120134

121-
if not isinstance(self._ets[i].T(), SE3):
122-
self._Ts *= SE3(self._ets[i].T())
135+
if first:
136+
T = et.T()
137+
first = False
123138
else:
124-
self._Ts *= self._ets[i].T()
139+
T = T @ et.T()
140+
self._Ts = T
125141

126142
elif isinstance(self._ets, SE3):
127143
self._Ts = self._ets
144+
raise RuntimeError('this shouldnt happen')
128145

129146
def __repr__(self):
130147
name = self.__class__.__name__
@@ -365,21 +382,43 @@ def A(self, q=None, fast=False):
365382
transformation from the previous to the current link frame to
366383
the next, which depends on the joint coordinate ``q``.
367384
385+
If ``fast`` is True return a NumPy array, either SE(2) or SE(3).
386+
A value of None means that it is the identity matrix.
387+
388+
If ``fast`` is False return an ``SE2`` or ``SE3`` instance.
389+
368390
"""
369391

392+
# we work with NumPy arrays for speed
370393
if self.isjoint:
371394
# a variable joint
372395
if q is None:
373396
raise ValueError("q is required for variable joints")
374-
T = self.Ts.A @ self.v.T(q)
397+
398+
# premultiply variable part by constant part if present
399+
Ts = self.Ts
400+
if Ts is None:
401+
T = self.v.T(q)
402+
else:
403+
T = Ts @ self.v.T(q)
375404
else:
376405
# a fixed joint
377-
T = self.Ts.A
406+
T = self.Ts
378407

379408
if fast:
380409
return T
410+
411+
if T is None:
412+
if self._ndims == 3:
413+
return SE3()
414+
elif self._ndims == 2:
415+
return SE2()
381416
else:
382-
return SE3(T, check=False)
417+
if self._ndims == 3:
418+
return SE3(T, check=False)
419+
elif self._ndims == 2:
420+
return SE2(T, check=False)
421+
383422

384423
def ets(self):
385424
if self.v is None:

0 commit comments

Comments
 (0)