@@ -423,6 +423,8 @@ def urdf_to_ets_args(self, file_path, tld=None):
423
423
:type tld: str, optional
424
424
:return: Links and robot name
425
425
:rtype: tuple(ELink list, str)
426
+
427
+ File should be specified relative to ``RTBDATA/URDF/xacro``
426
428
"""
427
429
428
430
# get the path to the class that defines the robot
@@ -1054,11 +1056,11 @@ def fkine(self, q, end=None, start=None, tool=None):
1054
1056
Tk = self .base .A @ Tk
1055
1057
1056
1058
# cast to pose class and append
1057
- T .append (T .__class__ (Tk ))
1059
+ T .append (T .__class__ (Tk , check = False ))
1058
1060
1059
1061
return T
1060
1062
1061
- def fkine_all (self , q ):
1063
+ def fkine_all (self , q , old = None ):
1062
1064
'''
1063
1065
Tall = robot.fkine_all(q) evaluates fkine for each joint within a
1064
1066
robot and returns a trajecotry of poses.
@@ -1070,6 +1072,7 @@ def fkine_all(self, q):
1070
1072
if not supplied will use the stored q values).
1071
1073
:type q: float ndarray(n)
1072
1074
1075
+ :param old: for compatibility with DHRobot version, ignored.
1073
1076
:return T: Homogeneous transformation trajectory
1074
1077
:rtype T: SE3 list
1075
1078
@@ -1123,6 +1126,9 @@ def fkine_all(self, q):
1123
1126
for gi in link .geometry :
1124
1127
gi .wT = link ._fk
1125
1128
1129
+ # HACK, inefficient to convert back to SE3
1130
+ return [SE3 (link ._fk ) for link in self .elinks ]
1131
+
1126
1132
# def jacob0(self, q=None):
1127
1133
# """
1128
1134
# J0 = jacob0(q) is the manipulator Jacobian matrix which maps joint
@@ -1395,7 +1401,7 @@ def jacob0(self, q, end=None, start=None, tool=None, T=None, half=None, analytic
1395
1401
.. warning:: ``start`` and ``end`` must be on the same branch,
1396
1402
with ``start`` closest to the base.
1397
1403
""" # noqa
1398
-
1404
+
1399
1405
if tool is None :
1400
1406
tool = SE3 ()
1401
1407
@@ -1697,6 +1703,8 @@ def add_pdi(pdi):
1697
1703
1698
1704
def hessian0 (self , q = None , J0 = None , end = None , start = None ):
1699
1705
r"""
1706
+ Manipulator Hessian
1707
+
1700
1708
The manipulator Hessian tensor maps joint acceleration to end-effector
1701
1709
spatial acceleration, expressed in the world-coordinate frame. This
1702
1710
function calulcates this based on the ETS of the robot. One of J0 or q
@@ -1715,7 +1723,7 @@ def hessian0(self, q=None, J0=None, end=None, start=None):
1715
1723
:return: The manipulator Hessian in 0 frame
1716
1724
:rtype: float ndarray(6,n,n)
1717
1725
1718
- This method computes the manipulator Hessian. If we take the
1726
+ This method computes the manipulator Hessian in the base frame . If we take the
1719
1727
time derivative of the differential kinematic relationship
1720
1728
1721
1729
.. math::
@@ -1886,7 +1894,10 @@ def __str__(self):
1886
1894
color = "" if link .isjoint else "<<blue>>"
1887
1895
ee = "@" if link in self .ee_links else ""
1888
1896
ets = link .ets ()
1889
- parent_name = link .parent .name if link .parent is not None else "_O_"
1897
+ if link .parent is None :
1898
+ parent_name = "BASE"
1899
+ else :
1900
+ parent_name = '{' + link .parent .name + '}'
1890
1901
s = ets .__str__ (f"q{ link ._jindex } " )
1891
1902
if len (s ) > 0 :
1892
1903
s = " * " + s
@@ -1895,10 +1906,10 @@ def __str__(self):
1895
1906
color + ee + link .name ,
1896
1907
parent_name ,
1897
1908
link ._joint_name if link .parent is not None else "" ,
1898
- f"{{{ link .name } }} = {{ { parent_name } } }{ s } "
1909
+ f"{{{ link .name } }} = { parent_name } { s } "
1899
1910
)
1900
1911
1901
- if self .manufacturer is None :
1912
+ if self .manufacturer is None or len ( self . manufacturer ) == 0 :
1902
1913
manuf = ""
1903
1914
else :
1904
1915
manuf = f" (by { self .manufacturer } )"
@@ -2110,7 +2121,7 @@ def indiv_calculation(link, link_col, q):
2110
2121
return Ain , bin
2111
2122
2112
2123
# inverse dynamics (recursive Newton-Euler) using spatial vector notation
2113
- def rne (robot , q , qd , qdd , gravity = None ):
2124
+ def rne (robot , q , qd , qdd , symbolic = False , gravity = None ):
2114
2125
2115
2126
n = robot .n
2116
2127
@@ -2123,12 +2134,18 @@ def rne(robot, q, qd, qdd, gravity=None):
2123
2134
f = SpatialForce .Alloc (n )
2124
2135
I = SpatialInertia .Alloc (n ) # noqa
2125
2136
s = [None for i in range (n )] # joint motion subspace
2126
- Q = np .zeros ((n ,)) # joint torque/force
2137
+ if symbolic :
2138
+ Q = np .empty ((n ,), dtype = 'O' ) # joint torque/force
2139
+ else :
2140
+ Q = np .empty ((n ,)) # joint torque/force
2127
2141
2128
2142
# initialize intermediate variables
2129
2143
for j , link in enumerate (robot ):
2130
2144
I [j ] = SpatialInertia (m = link .m , r = link .r )
2131
- Xtree [j ] = SE3 (link .Ts )
2145
+ if symbolic and link .Ts is None :
2146
+ Xtree [j ] = SE3 (np .eye (4 , dtype = 'O' ), check = False )
2147
+ else :
2148
+ Xtree [j ] = SE3 (link .Ts , check = False )
2132
2149
s [j ] = link .v .s
2133
2150
2134
2151
if gravity is None :
@@ -2157,7 +2174,9 @@ def rne(robot, q, qd, qdd, gravity=None):
2157
2174
2158
2175
# backward recursion
2159
2176
for j in reversed (range (0 , n )):
2160
- Q [j ] = f [j ].dot (s [j ])
2177
+
2178
+ # next line could be np.dot(), but fails for symbolic arguments
2179
+ Q [j ] = np .sum (f [j ].A * s [j ])
2161
2180
2162
2181
if robot [j ].parent is not None :
2163
2182
jp = robot [j ].parent .jindex
0 commit comments