8000 add rne back to Robot · naren200/robotics-toolbox-python@4cacde2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4cacde2

Browse files
committed
add rne back to Robot
1 parent e1a28cb commit 4cacde2

File tree

1 file changed

+142
-1
lines changed

1 file changed

+142
-1
lines changed

roboticstoolbox/robot/Robot.py

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@
3737
from swift import Swift
3838
from spatialgeometry import Shape, CollisionShape, Cylinder, SceneNode
3939

40-
from spatialmath import SE3
40+
from spatialmath import (
41+
SE3,
42+
SpatialAcceleration,
43+
SpatialVelocity,
44+
SpatialInertia,
45+
SpatialForce,
46+
)
4147
import spatialmath.base as smb
4248
from spatialmath.base.argcheck import (
4349
isvector,
@@ -4404,3 +4410,138 @@ def indiv_calculation(link: Link, link_col: CollisionShape, q: NDArray):
44044410
bin = np.concatenate((bin, l_bin))
44054411

44064412
return Ain, bin
4413+
4414+
# --------------------------------------------------------------------- #
4415+
# --------- Dynamics Methods ------------------------------------------ #
4416+
# --------------------------------------------------------------------- #
4417+
4418+
def rne(
4419+
self,
4420+
q: NDArray,
4421+
qd: NDArray,
4422+
qdd: NDArray,
4423+
symbolic: bool = False,
4424+
gravity: Union[ArrayLike, None] = None,
4425+
):
4426+
"""
4427+
Compute inverse dynamics via recursive Newton-Euler formulation
4428+
4429+
``rne_dh(q, qd, qdd)`` where the arguments have shape (n,) where n is
4430+
the number of robot joints. The result has shape (n,).
4431+
4432+
``rne_dh(q, qd, qdd)`` where the arguments have shape (m,n) where n
4433+
is the number of robot joints and where m is the number of steps in
4434+
the joint trajectory. The result has shape (m,n).
4435+
4436+
``rne_dh(p)`` where the input is a 1D array ``p`` = [q, qd, qdd] with
4437+
shape (3n,), and the result has shape (n,).
4438+
4439+
``rne_dh(p)`` where the input is a 2D array ``p`` = [q, qd, qdd] with
4440+
shape (m,3n) and the result has shape (m,n).
4441+
4442+
Parameters
4443+
----------
4444+
q
4445+
Joint coordinates
4446+
qd
4447+
Joint velocity
4448+
qdd
4449+
Joint acceleration
4450+
symbolic
4451+
If True, supports symbolic expressions
4452+
gravity
4453+
Gravitational acceleration, defaults to attribute
4454+
of self
4455+
4456+
Returns
4457+
-------
4458+
tau
4459+
Joint force/torques
4460+
4461+
Notes
4462+
-----
4463+
- This version supports symbolic model parameters
4464+
- Verified against MATLAB code
4465+
4466+
"""
4467+
4468+
n = self.n
4469+
4470+
# allocate intermediate variables
4471+
Xup = SE3.Alloc(n)
4472+
Xtree = SE3.Alloc(n)
4473+
4474+
v = SpatialVelocity.Alloc(n)
4475+
a = SpatialAcceleration.Alloc(n)
4476+
f = SpatialForce.Alloc(n)
4477+
I = SpatialInertia.Alloc(n) # noqa
4478+
s = [] # joint motion subspace
4479+
4480+
if symbolic:
4481+
Q = np.empty((n,), dtype="O") # joint torque/force
4482+
else:
4483+
Q = np.empty((n,)) # joint torque/force
4484+
4485+
# TODO Should the dynamic parameters of static links preceding joint be
4486+
# somehow merged with the joint?
4487+
4488+
# A temp variable to handle static joints
4489+
Ts = SE3()
4490+
4491+
# A counter through joints
4492+
j = 0
4493+
4494+
# initialize intermediate variables
4495+
for link in self.links:
4496+
if link.isjoint:
4497+
I[j] = SpatialInertia(m=link.m, r=link.r)
4498+
if symbolic and link.Ts is None:
4499+
Xtree[j] = SE3(np.eye(4, dtype="O"), check=False)
4500+
else:
4501+
Xtree[j] = Ts * SE3(link.Ts, check=False)
4502+
4503+
if link.v is not None:
4504+
s.append(link.v.s)
4505+
4506+
# Increment the joint counter
4507+
j += 1
4508+
4509+
# Reset the Ts tracker
4510+
Ts = SE3()
4511+
else:
4512+
# TODO Keep track of inertia and transform???
4513+
Ts *= SE3(link.Ts, check=False)
4514+
4515+
if gravity is None:
4516+
a_grav = -SpatialAcceleration(self.gravity)
4517+
else:
4518+
a_grav = -SpatialAcceleration(gravity)
4519+
4520+
# forward recursion
4521+
for j in range(0, n):
4522+
vJ = SpatialVelocity(s[j] * qd[j])
4523+
4524+
# transform from parent(j) to j
4525+
Xup[j] = SE3(self.links[j].A(q[j])).inv()
4526+
4527+
if self.links[j].parent is None:
4528+
v[j] = vJ
4529+
a[j] = Xup[j] * a_grav + SpatialAcceleration(s[j] * qdd[j])
4530+
else:
4531+
jp = self.links[j].parent.jindex # type: ignore
4532+
v[j] = Xup[j] * v[jp] + vJ
4533+
a[j] = Xup[j] * a[jp] + SpatialAcceleration(s[j] * qdd[j]) + v[j] @ vJ
4534+
4535+
f[j] = I[j] * a[j] + v[j] @ (I[j] * v[j])
4536+
4537+
# backward recursion
4538+
for j in reversed(range(0, n)):
4539+
4540+
# next line could be dot(), but fails for symbolic arguments
4541+
Q[j] = sum(f[j].A * s[j])
4542+
4543+
if self.links[j].parent is not None:
4544+
jp = self.links[j].parent.jindex # type: ignore
4545+
f[jp] = f[jp] + Xup[j] * f[j]
4546+
4547+
return Q

0 commit comments

Comments
 (0)
0