roboticstoolbox-python 1.4.3__py3-none-any.whl → 1.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- roboticstoolbox/bin/rtbtool.py +1 -1
- roboticstoolbox/ets/cpp-extensions/ik.cpp +47 -3
- roboticstoolbox/models/DH/UR10.py +5 -0
- roboticstoolbox/models/URDF/Fetch.py +3 -0
- roboticstoolbox/models/URDF/Frankie.py +11 -2
- roboticstoolbox/models/URDF/FrankieOmni.py +10 -2
- roboticstoolbox/models/URDF/Jaco.py +3 -0
- roboticstoolbox/models/URDF/PR2.py +3 -0
- roboticstoolbox/models/URDF/Panda.py +29 -9
- roboticstoolbox/models/URDF/UR10.py +3 -0
- roboticstoolbox/models/URDF/UR3.py +3 -0
- roboticstoolbox/models/URDF/UR5.py +13 -1
- roboticstoolbox/models/URDF/URDFRobot.py +28 -2
- roboticstoolbox/models/URDF/Valkyrie.py +3 -0
- roboticstoolbox/models/URDF/YuMi.py +3 -0
- roboticstoolbox/robot/DHRobot.py +1 -1
- roboticstoolbox/robot/IK.py +42 -5
- roboticstoolbox/robot/Robot.py +117 -65
- roboticstoolbox/robot/RobotKinematics.py +59 -16
- {roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/METADATA +3 -43
- {roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/RECORD +24 -24
- {roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/WHEEL +0 -0
- {roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/entry_points.txt +0 -0
- {roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/licenses/LICENSE +0 -0
roboticstoolbox/bin/rtbtool.py
CHANGED
|
@@ -51,8 +51,52 @@ static void _IK_loop(
|
|
|
51
51
|
|
|
52
52
|
if (*E < tol)
|
|
53
53
|
{
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
// Preserve translations and coordinates already within their limits.
|
|
55
|
+
// Other revolute coordinates may move only by whole turns, so the
|
|
56
|
+
// converged end-effector pose is unchanged (see IKSolver._normalise_q).
|
|
57
|
+
int j = 0;
|
|
58
|
+
for (int i = 0; i < ets->m; i++)
|
|
59
|
+
{
|
|
60
|
+
ET *et = ets->ets[i];
|
|
61
|
+
if (!et->isjoint)
|
|
62
|
+
continue;
|
|
63
|
+
|
|
64
|
+
double lower = ets->qlim_l[j];
|
|
65
|
+
double upper = ets->qlim_h[j];
|
|
66
|
+
if (et->axis < 3 && !(lower <= q(j) && q(j) <= upper))
|
|
67
|
+
{
|
|
68
|
+
// Avoid rounding a principal angle across a nearby limit.
|
|
69
|
+
double angle = q(j);
|
|
70
|
+
if (!(angle >= -PI && angle < PI))
|
|
71
|
+
{
|
|
72
|
+
// Unlike Python's %, fmod can return a negative remainder.
|
|
73
|
+
angle = std::fmod(angle + PI, PI_x2);
|
|
74
|
+
if (angle < 0)
|
|
75
|
+
angle += PI_x2;
|
|
76
|
+
angle -= PI;
|
|
77
|
+
}
|
|
78
|
+
if (angle < lower)
|
|
79
|
+
angle += PI_x2 * std::ceil((lower - angle) / PI_x2);
|
|
80
|
+
else if (angle > upper)
|
|
81
|
+
angle -= PI_x2 * std::ceil((angle - upper) / PI_x2);
|
|
82
|
+
if (!(lower <= angle && angle <= upper))
|
|
83
|
+
{
|
|
84
|
+
// Recover rounded endpoints only if whole turns
|
|
85
|
+
// reconstruct the original coordinate exactly.
|
|
86
|
+
for (double bound : {lower, upper})
|
|
87
|
+
{
|
|
88
|
+
double turns = std::round((q(j) - bound) / PI_x2);
|
|
89
|
+
if (turns != 0 && bound + turns * PI_x2 == q(j))
|
|
90
|
+
{
|
|
91
|
+
angle = bound;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
q(j) = angle;
|
|
97
|
+
}
|
|
98
|
+
j++;
|
|
99
|
+
}
|
|
56
100
|
*solution = reject_jl ? _check_lim(ets, q) : 1;
|
|
57
101
|
break;
|
|
58
102
|
}
|
|
@@ -315,4 +359,4 @@ extern "C"
|
|
|
315
359
|
// return q;
|
|
316
360
|
}
|
|
317
361
|
|
|
318
|
-
} /* extern "C" */
|
|
362
|
+
} /* extern "C" */
|
|
@@ -27,6 +27,11 @@ class UR10(DHRobot):
|
|
|
27
27
|
|
|
28
28
|
.. note::
|
|
29
29
|
- SI units are used.
|
|
30
|
+
- The last link's inertia tensor has :math:`I_{xx} = 0` -- that's not
|
|
31
|
+
a bug in this model, it's what the manufacturer's own reference
|
|
32
|
+
(below) publishes. It makes the robot's inertia matrix near-singular
|
|
33
|
+
(``det(robot.inertia(q)) ~ 2e-6``), so dynamics work that needs a
|
|
34
|
+
well-conditioned inertia matrix should account for this.
|
|
30
35
|
|
|
31
36
|
:References:
|
|
32
37
|
|
|
@@ -47,6 +47,9 @@ class Fetch(URDFRobot):
|
|
|
47
47
|
from a URDF file. The model describes its kinematic and graphical
|
|
48
48
|
characteristics.
|
|
49
49
|
|
|
50
|
+
The model is loaded via the `robot_descriptions
|
|
51
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
52
|
+
|
|
50
53
|
.. runblock:: pycon
|
|
51
54
|
|
|
52
55
|
>>> import roboticstoolbox as rtb
|
|
@@ -13,6 +13,9 @@ class Frankie(URDFRobot):
|
|
|
13
13
|
from a URDF file. The model describes its kinematic and graphical
|
|
14
14
|
characteristics.
|
|
15
15
|
|
|
16
|
+
The model is loaded via the `robot_descriptions
|
|
17
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
18
|
+
|
|
16
19
|
.. runblock:: pycon
|
|
17
20
|
|
|
18
21
|
>>> import roboticstoolbox as rtb
|
|
@@ -23,8 +26,14 @@ class Frankie(URDFRobot):
|
|
|
23
26
|
|
|
24
27
|
- qz, zero joint angle configuration, 'L' shaped configuration
|
|
25
28
|
- qr, vertical 'READY' configuration
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
|
|
30
|
+
Loaded via the `robot_descriptions
|
|
31
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package
|
|
32
|
+
(real inertial data, plain-mesh collision geometry), unlike
|
|
33
|
+
:class:`~roboticstoolbox.models.URDF.Panda.Panda`'s bundled default. See
|
|
34
|
+
the wiki's `Panda models
|
|
35
|
+
<https://github.com/petercorke/robotics-toolbox-python/wiki/Panda-models>`_
|
|
36
|
+
page for why the two differ.
|
|
28
37
|
|
|
29
38
|
.. codeauthor:: Jesse Haviland
|
|
30
39
|
.. sectionauthor:: Peter Corke
|
|
@@ -27,8 +27,16 @@ class FrankieOmni(Robot):
|
|
|
27
27
|
|
|
28
28
|
- qz, zero joint angle configuration, 'L' shaped configuration
|
|
29
29
|
- qr, vertical 'READY' configuration
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
The arm is loaded from the same bundled ``qut_frankie_description`` xacro
|
|
32
|
+
as :class:`~roboticstoolbox.models.URDF.Panda.Panda`'s default (no
|
|
33
|
+
inertial data), spliced by hand onto a separately-loaded
|
|
34
|
+
``clearpath_ridgeback_description`` mobile base -- it has no
|
|
35
|
+
``use_robot_descriptions``-style option, since the base+arm splice is
|
|
36
|
+
done manually rather than through :class:`URDFRobot`'s own loader. See
|
|
37
|
+
the wiki's `Panda models
|
|
38
|
+
<https://github.com/petercorke/robotics-toolbox-python/wiki/Panda-models>`_
|
|
39
|
+
page for the full picture.
|
|
32
40
|
|
|
33
41
|
.. codeauthor:: Jesse Haviland
|
|
34
42
|
.. sectionauthor:: Peter Corke
|
|
@@ -12,6 +12,9 @@ class Jaco(URDFRobot):
|
|
|
12
12
|
from a URDF file. The model describes its kinematic and graphical
|
|
13
13
|
characteristics.
|
|
14
14
|
|
|
15
|
+
The model is loaded via the `robot_descriptions
|
|
16
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
17
|
+
|
|
15
18
|
.. runblock:: pycon
|
|
16
19
|
|
|
17
20
|
>>> import roboticstoolbox as rtb
|
|
@@ -12,6 +12,9 @@ class PR2(URDFRobot):
|
|
|
12
12
|
from a URDF file. The model describes its kinematic and graphical
|
|
13
13
|
characteristics.
|
|
14
14
|
|
|
15
|
+
The model is loaded via the `robot_descriptions
|
|
16
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
17
|
+
|
|
15
18
|
.. runblock:: pycon
|
|
16
19
|
|
|
17
20
|
>>> import roboticstoolbox as rtb
|
|
@@ -23,20 +23,40 @@ class Panda(URDFRobot):
|
|
|
23
23
|
|
|
24
24
|
- qz, zero joint angle configuration, 'L' shaped configuration
|
|
25
25
|
- qr, vertical 'READY' configuration
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
:param use_robot_descriptions: if ``True``, load the Panda URDF from the
|
|
28
|
+
`robot_descriptions <https://github.com/robot-descriptions/robot_descriptions.py>`_
|
|
29
|
+
package instead of the toolbox's own bundled ``qut_frankie_description``
|
|
30
|
+
xacro (the default, ``False``). The bundled model has real collision
|
|
31
|
+
geometry (a hand-built capsule approximation) but no inertial
|
|
32
|
+
(mass/CoM/inertia) data at all -- ``rne()``/``inertia()``/``coriolis()``/
|
|
33
|
+
``gravload()`` are all silently zero. The ``robot_descriptions`` model
|
|
34
|
+
has real inertial data, but its collision geometry is plain meshes,
|
|
35
|
+
which are roughly an order of magnitude slower to collision-check
|
|
36
|
+
against than the bundled model's capsules -- noticeable in a
|
|
37
|
+
real-time reactive-avoidance loop (see ``examples/neo.py``). See the
|
|
38
|
+
wiki's `Panda models <https://github.com/petercorke/robotics-toolbox-python/wiki/Panda-models>`_
|
|
39
|
+
page for the full comparison and rationale.
|
|
40
|
+
:type use_robot_descriptions: bool
|
|
28
41
|
|
|
29
42
|
.. codeauthor:: Jesse Haviland
|
|
30
43
|
.. sectionauthor:: Peter Corke
|
|
31
44
|
"""
|
|
32
45
|
|
|
33
|
-
def __init__(self):
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
def __init__(self, use_robot_descriptions: bool = False):
|
|
47
|
+
|
|
48
|
+
if use_robot_descriptions:
|
|
49
|
+
super().__init__(
|
|
50
|
+
"panda",
|
|
51
|
+
manufacturer="Franka Emika",
|
|
52
|
+
gripper_link_index=9,
|
|
53
|
+
)
|
|
54
|
+
else:
|
|
55
|
+
super().__init__(
|
|
56
|
+
"qut_frankie_description/robots/panda_arm_hand.urdf.xacro",
|
|
57
|
+
manufacturer="Franka Emika",
|
|
58
|
+
gripper_link_index=9,
|
|
59
|
+
)
|
|
40
60
|
|
|
41
61
|
self.grippers[0].tool = SE3(0, 0, 0.1034)
|
|
42
62
|
|
|
@@ -12,6 +12,9 @@ class UR10(URDFRobot):
|
|
|
12
12
|
definition from a URDF file. The model describes its kinematic and
|
|
13
13
|
graphical characteristics.
|
|
14
14
|
|
|
15
|
+
The model is loaded via the `robot_descriptions
|
|
16
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
17
|
+
|
|
15
18
|
.. runblock:: pycon
|
|
16
19
|
|
|
17
20
|
>>> import roboticstoolbox as rtb
|
|
@@ -12,6 +12,9 @@ class UR3(URDFRobot):
|
|
|
12
12
|
definition from a URDF file. The model describes its kinematic and
|
|
13
13
|
graphical characteristics.
|
|
14
14
|
|
|
15
|
+
The model is loaded via the `robot_descriptions
|
|
16
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
17
|
+
|
|
15
18
|
.. runblock:: pycon
|
|
16
19
|
|
|
17
20
|
>>> import roboticstoolbox as rtb
|
|
@@ -13,6 +13,9 @@ class UR5(URDFRobot):
|
|
|
13
13
|
definition from a URDF file. The model describes its kinematic and
|
|
14
14
|
graphical characteristics.
|
|
15
15
|
|
|
16
|
+
The model is loaded via the `robot_descriptions
|
|
17
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
18
|
+
|
|
16
19
|
.. runblock:: pycon
|
|
17
20
|
|
|
18
21
|
>>> import roboticstoolbox as rtb
|
|
@@ -30,7 +33,16 @@ class UR5(URDFRobot):
|
|
|
30
33
|
|
|
31
34
|
def __init__(self):
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
# Name-based lookup, not a raw positional index: robot_descriptions
|
|
37
|
+
# 3.0.0 changed which upstream repo "ur5" resolves to, reordering
|
|
38
|
+
# links so index 7 silently pointed at a real arm joint instead of
|
|
39
|
+
# the tool attachment link (#578). tool0/ee_link/flange are stable
|
|
40
|
+
# names across the versions checked.
|
|
41
|
+
super().__init__(
|
|
42
|
+
"ur5",
|
|
43
|
+
manufacturer="Universal Robotics",
|
|
44
|
+
gripper_link_name=["tool0", "ee_link", "flange"],
|
|
45
|
+
)
|
|
34
46
|
|
|
35
47
|
# for link in links:
|
|
36
48
|
# print(link)
|
|
@@ -383,10 +383,16 @@ class URDFRobot(Robot):
|
|
|
383
383
|
super().__init__(
|
|
384
384
|
"ur5",
|
|
385
385
|
manufacturer="Universal Robotics",
|
|
386
|
-
|
|
386
|
+
gripper_link_name=["tool0", "ee_link"],
|
|
387
387
|
)
|
|
388
388
|
self.qz = np.zeros(6)
|
|
389
389
|
...
|
|
390
|
+
|
|
391
|
+
``gripper_link_name`` (a name, or a list of candidate names tried in
|
|
392
|
+
order) survives an upstream URDF reordering that would silently break a
|
|
393
|
+
raw positional ``gripper_link_index`` -- see #578. Prefer it for new
|
|
394
|
+
models; ``gripper_link_index`` remains for models where a stable,
|
|
395
|
+
well-known link name isn't available.
|
|
390
396
|
"""
|
|
391
397
|
|
|
392
398
|
def __init__(
|
|
@@ -394,6 +400,7 @@ class URDFRobot(Robot):
|
|
|
394
400
|
urdf_path: "str | Path",
|
|
395
401
|
manufacturer: str = "",
|
|
396
402
|
gripper_link_index: "int | None" = None,
|
|
403
|
+
gripper_link_name: "str | list[str] | None" = None,
|
|
397
404
|
patch: "Callable[[str], str] | None" = None,
|
|
398
405
|
extra_packages: "dict[str, str] | None" = None,
|
|
399
406
|
**kwargs,
|
|
@@ -401,7 +408,26 @@ class URDFRobot(Robot):
|
|
|
401
408
|
elinks, name, filepath = URDF_file(
|
|
402
409
|
urdf_path, patch=patch, extra_packages=extra_packages
|
|
403
410
|
)
|
|
404
|
-
if
|
|
411
|
+
if gripper_link_name is not None:
|
|
412
|
+
candidates = (
|
|
413
|
+
[gripper_link_name]
|
|
414
|
+
if isinstance(gripper_link_name, str)
|
|
415
|
+
else gripper_link_name
|
|
416
|
+
)
|
|
417
|
+
for candidate in candidates:
|
|
418
|
+
match = next(
|
|
419
|
+
(link for link in elinks if link.name == candidate), None
|
|
420
|
+
)
|
|
421
|
+
if match is not None:
|
|
422
|
+
kwargs["gripper_links"] = match
|
|
423
|
+
break
|
|
424
|
+
else:
|
|
425
|
+
raise ValueError(
|
|
426
|
+
f"none of the candidate gripper link names {candidates!r} "
|
|
427
|
+
f"were found in the parsed URDF for {name!r} (have: "
|
|
428
|
+
f"{[link.name for link in elinks]})"
|
|
429
|
+
)
|
|
430
|
+
elif gripper_link_index is not None:
|
|
405
431
|
kwargs["gripper_links"] = elinks[gripper_link_index]
|
|
406
432
|
super().__init__(elinks, name=name, manufacturer=manufacturer, **kwargs)
|
|
407
433
|
self._urdf_filepath = str(filepath) if filepath is not None else ""
|
|
@@ -41,6 +41,9 @@ class Valkyrie(Robot):
|
|
|
41
41
|
from a URDF file. The model describes its kinematic and graphical
|
|
42
42
|
characteristics.
|
|
43
43
|
|
|
44
|
+
The model is loaded via the `robot_descriptions
|
|
45
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
46
|
+
|
|
44
47
|
.. runblock:: pycon
|
|
45
48
|
|
|
46
49
|
>>> import roboticstoolbox as rtb
|
|
@@ -15,6 +15,9 @@ class YuMi(Robot):
|
|
|
15
15
|
from a URDF file. The model describes its kinematic and graphical
|
|
16
16
|
characteristics.
|
|
17
17
|
|
|
18
|
+
The model is loaded via the `robot_descriptions
|
|
19
|
+
<https://github.com/robot-descriptions/robot_descriptions.py>`_ package.
|
|
20
|
+
|
|
18
21
|
.. runblock:: pycon
|
|
19
22
|
|
|
20
23
|
>>> import roboticstoolbox as rtb
|
roboticstoolbox/robot/DHRobot.py
CHANGED
roboticstoolbox/robot/IK.py
CHANGED
|
@@ -308,13 +308,10 @@ class IKSolver(ABC):
|
|
|
308
308
|
while True:
|
|
309
309
|
# Check convergence for the current q before another update.
|
|
310
310
|
if E < self.tol:
|
|
311
|
-
|
|
312
|
-
# If your robot has larger than 180 deg range on a joint
|
|
313
|
-
# this line should be modified in incorporate the extra range
|
|
314
|
-
q = (q + np.pi) % (2 * np.pi) - np.pi
|
|
311
|
+
self._normalise_q(ets, q)
|
|
315
312
|
|
|
316
313
|
# Check if we have violated joint limits
|
|
317
|
-
jl_valid = self._check_jl(ets, q)
|
|
314
|
+
jl_valid = self._check_jl(ets, q[ets.jindices])
|
|
318
315
|
|
|
319
316
|
if not jl_valid and self.joint_limits:
|
|
320
317
|
# Abandon search and try again
|
|
@@ -450,6 +447,46 @@ class IKSolver(ABC):
|
|
|
450
447
|
|
|
451
448
|
return q
|
|
452
449
|
|
|
450
|
+
def _normalise_q(self, ets: "rtb.ETS", q: np.ndarray) -> None:
|
|
451
|
+
"""
|
|
452
|
+
Choose equivalent revolute coordinates without changing prismatic joints.
|
|
453
|
+
|
|
454
|
+
:param ets: The ETS defining the joint types and limits
|
|
455
|
+
:param q: Joint coordinates, indexed by joint jindex, modified in place
|
|
456
|
+
:returns: None
|
|
457
|
+
|
|
458
|
+
Preserve coordinates already within their limits, including revolute joints
|
|
459
|
+
outside the principal interval. Otherwise prefer the principal angle, shifted
|
|
460
|
+
by whole turns towards the limits if necessary. If no equivalent angle lies
|
|
461
|
+
within the limits, the subsequent joint-limit check will reject the solution.
|
|
462
|
+
"""
|
|
463
|
+
qlim = ets.qlim
|
|
464
|
+
for i, joint in enumerate(ets.joints()):
|
|
465
|
+
j = joint.jindex
|
|
466
|
+
lower, upper = qlim[:, i]
|
|
467
|
+
if not joint.isrotation or lower <= q[j] <= upper:
|
|
468
|
+
continue
|
|
469
|
+
|
|
470
|
+
# Avoid rounding a principal angle across a nearby joint limit.
|
|
471
|
+
angle = q[j]
|
|
472
|
+
if not -np.pi <= angle < np.pi:
|
|
473
|
+
angle = (angle + np.pi) % (2 * np.pi) - np.pi
|
|
474
|
+
if angle < lower:
|
|
475
|
+
angle += 2 * np.pi * np.ceil((lower - angle) / (2 * np.pi))
|
|
476
|
+
elif angle > upper:
|
|
477
|
+
angle -= 2 * np.pi * np.ceil((angle - upper) / (2 * np.pi))
|
|
478
|
+
if not lower <= angle <= upper:
|
|
479
|
+
# Argument reduction can round a limit plus whole turns just
|
|
480
|
+
# outside the closed interval. Accept that endpoint only when
|
|
481
|
+
# it reconstructs the original coordinate exactly, without an
|
|
482
|
+
# epsilon that could admit an unrelated out-of-limit angle.
|
|
483
|
+
for bound in (lower, upper):
|
|
484
|
+
turns = np.rint((q[j] - bound) / (2 * np.pi))
|
|
485
|
+
if turns != 0 and bound + turns * (2 * np.pi) == q[j]:
|
|
486
|
+
angle = bound
|
|
487
|
+
break
|
|
488
|
+
q[j] = angle
|
|
489
|
+
|
|
453
490
|
def _check_jl(self, ets: "rtb.ETS", q: np.ndarray) -> bool:
|
|
454
491
|
"""
|
|
455
492
|
Checks if the joints are within their respective limits
|
roboticstoolbox/robot/Robot.py
CHANGED
|
@@ -1385,7 +1385,7 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1385
1385
|
|
|
1386
1386
|
def joint_velocity_damper(
|
|
1387
1387
|
self,
|
|
1388
|
-
q=None,
|
|
1388
|
+
q: NDArray | None = None,
|
|
1389
1389
|
ps: float = 0.05,
|
|
1390
1390
|
pi: float = 0.1,
|
|
1391
1391
|
n: int | None = None,
|
|
@@ -1413,16 +1413,16 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1413
1413
|
n = self.n
|
|
1414
1414
|
|
|
1415
1415
|
if q is None:
|
|
1416
|
-
q =
|
|
1416
|
+
q = self.q
|
|
1417
1417
|
|
|
1418
1418
|
Ain = np.zeros((n, n))
|
|
1419
1419
|
Bin = np.zeros(n)
|
|
1420
1420
|
|
|
1421
1421
|
for i in range(n):
|
|
1422
|
-
if
|
|
1422
|
+
if q[i] - self.qlim[0, i] <= pi:
|
|
1423
1423
|
Bin[i] = -gain * (((self.qlim[0, i] - q[i]) + ps) / (pi - ps))
|
|
1424
1424
|
Ain[i, i] = -1
|
|
1425
|
-
if self.qlim[1, i] -
|
|
1425
|
+
if self.qlim[1, i] - q[i] <= pi:
|
|
1426
1426
|
Bin[i] = gain * ((self.qlim[1, i] - q[i]) - ps) / (pi - ps)
|
|
1427
1427
|
Ain[i, i] = 1
|
|
1428
1428
|
|
|
@@ -1460,13 +1460,21 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1460
1460
|
|
|
1461
1461
|
end, start, _ = self._get_limit_links(start=start, end=end)
|
|
1462
1462
|
|
|
1463
|
-
links,
|
|
1463
|
+
links, _, _ = self.get_path(start=start, end=end)
|
|
1464
1464
|
|
|
1465
1465
|
q = np.array(q)
|
|
1466
1466
|
j = 0
|
|
1467
1467
|
Ain = None
|
|
1468
1468
|
bin = None
|
|
1469
1469
|
|
|
1470
|
+
def get_link_joint_index(link: Link | None) -> int:
|
|
1471
|
+
curr = link
|
|
1472
|
+
while curr is not None:
|
|
1473
|
+
if curr.isjoint and curr.jindex is not None:
|
|
1474
|
+
return curr.jindex
|
|
1475
|
+
curr = curr.parent
|
|
1476
|
+
return 0
|
|
1477
|
+
|
|
1470
1478
|
def indiv_calculation(link: Link, link_col: CollisionShape, q: NDArray):
|
|
1471
1479
|
d, wTlp, wTcp = link_col.closest_point(shape, di)
|
|
1472
1480
|
|
|
@@ -1491,9 +1499,10 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1491
1499
|
Je = self.jacobe(q, start=start, end=link, tool=link_col.T)
|
|
1492
1500
|
n_dim = Je.shape[1]
|
|
1493
1501
|
dp = norm_h @ shape.v
|
|
1494
|
-
l_Ain = np.zeros((1, n))
|
|
1502
|
+
l_Ain = np.zeros((1, self.n))
|
|
1495
1503
|
|
|
1496
|
-
|
|
1504
|
+
start_jidx = get_link_joint_index(start)
|
|
1505
|
+
l_Ain[0, start_jidx : start_jidx + n_dim] = 1 * norm_h @ Je
|
|
1497
1506
|
l_bin = (xi * (d - ds) / (di - ds)) + dp
|
|
1498
1507
|
else: # pragma nocover
|
|
1499
1508
|
l_Ain = None
|
|
@@ -1507,9 +1516,6 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1507
1516
|
|
|
1508
1517
|
if collision_list is None:
|
|
1509
1518
|
col_list = link.collision
|
|
1510
|
-
|
|
1511
|
-
for c in col_list:
|
|
1512
|
-
pass
|
|
1513
1519
|
else:
|
|
1514
1520
|
col_list = [collision_list[j - 1]] # pragma nocover
|
|
1515
1521
|
|
|
@@ -1786,28 +1792,71 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1786
1792
|
|
|
1787
1793
|
link_groups: list[list[int]] = []
|
|
1788
1794
|
|
|
1789
|
-
# Group
|
|
1790
|
-
#
|
|
1791
|
-
|
|
1795
|
+
# Group each joint together with every static (fixed) link rigidly
|
|
1796
|
+
# attached to -- and moving with -- its own output frame: found by
|
|
1797
|
+
# walking each static link's ancestry (via .parent, not flat
|
|
1798
|
+
# self.links order, so this is correct under branching too) up to
|
|
1799
|
+
# its nearest joint. A static link ends up in that joint's group
|
|
1800
|
+
# regardless of where it sits relative to the *next* joint in the
|
|
1801
|
+
# chain -- immediately after this joint, sandwiched anywhere before
|
|
1802
|
+
# the next one, or trailing after the very last joint with nothing
|
|
1803
|
+
# further downstream (e.g. a tool flange/mount link, such as URDF
|
|
1804
|
+
# Panda's panda_link8). A static link with no joint ancestor at all
|
|
1805
|
+
# (rigidly mounted on the immovable base) contributes no joint
|
|
1806
|
+
# torque and is dropped.
|
|
1807
|
+
#
|
|
1808
|
+
# An earlier version grouped a static link with the first joint
|
|
1809
|
+
# encountered scanning *forward* -- correct for a trailing run
|
|
1810
|
+
# (#636), but wrong for a sandwiched static link (joint_A -> static
|
|
1811
|
+
# -> joint_B): that attaches the static link's mass to joint_B's
|
|
1812
|
+
# group, when it's actually rigidly welded to joint_A's output and
|
|
1813
|
+
# physically independent of joint_B's angle, silently misattributing
|
|
1814
|
+
# its torque contribution to the wrong joint (#483).
|
|
1815
|
+
group_of_link_idx: dict[int, int] = {}
|
|
1792
1816
|
for i, link in enumerate(self.links):
|
|
1793
|
-
current_group.append(i)
|
|
1794
|
-
|
|
1795
|
-
# Break after adding the first link
|
|
1796
1817
|
if link.isjoint:
|
|
1797
|
-
link_groups.append(
|
|
1798
|
-
|
|
1818
|
+
link_groups.append([i])
|
|
1819
|
+
group_of_link_idx[i] = len(link_groups) - 1
|
|
1820
|
+
elif link.parent is not None:
|
|
1821
|
+
group_idx = group_of_link_idx.get(self.links.index(link.parent))
|
|
1822
|
+
if group_idx is not None:
|
|
1823
|
+
link_groups[group_idx].append(i)
|
|
1824
|
+
group_of_link_idx[i] = group_idx
|
|
1799
1825
|
|
|
1800
1826
|
# Make some intermediate variables
|
|
1801
1827
|
for i, group in enumerate(link_groups):
|
|
1802
1828
|
I_int = SpatialInertia()
|
|
1803
1829
|
|
|
1830
|
+
# group[0] is always the joint itself (see the grouping loop
|
|
1831
|
+
# above); everything after it in the group is a static link
|
|
1832
|
+
# rigidly carried by that joint's own output frame, but
|
|
1833
|
+
# link.r/link.I are each expressed in that *link's own* frame,
|
|
1834
|
+
# not the joint's. Compose their fixed transforms relative to
|
|
1835
|
+
# the joint and carry the CoM/inertia into the joint's frame
|
|
1836
|
+
# before summing -- otherwise a static link's mass lands in
|
|
1837
|
+
# I_int with the wrong moment arm relative to this joint
|
|
1838
|
+
# (effectively r=0), which for a non-negligible offset silently
|
|
1839
|
+
# drops its contribution to this joint's torque (#636, #483).
|
|
1840
|
+
past_joint = False
|
|
1841
|
+
T_from_joint = None
|
|
1804
1842
|
for idx in group:
|
|
1805
1843
|
link = self.links[idx]
|
|
1806
1844
|
|
|
1807
|
-
|
|
1845
|
+
if past_joint:
|
|
1846
|
+
T_from_joint = (
|
|
1847
|
+
SE3(link.A())
|
|
1848
|
+
if T_from_joint is None
|
|
1849
|
+
else T_from_joint * SE3(link.A())
|
|
1850
|
+
)
|
|
1851
|
+
r = T_from_joint.R @ np.asarray(link.r) + T_from_joint.t
|
|
1852
|
+
Ir = T_from_joint.R @ link.I @ T_from_joint.R.T
|
|
1853
|
+
I_int = I_int + SpatialInertia(m=link.m, r=r, I=Ir)
|
|
1854
|
+
else:
|
|
1855
|
+
I_int = I_int + SpatialInertia(m=link.m, r=link.r, I=link.I)
|
|
1808
1856
|
|
|
1809
1857
|
if link.v is not None:
|
|
1810
1858
|
s.append(link.v.s) # type: ignore[union-attr]
|
|
1859
|
+
past_joint = True
|
|
1811
1860
|
|
|
1812
1861
|
I[i] = I_int
|
|
1813
1862
|
|
|
@@ -1832,8 +1881,8 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1832
1881
|
# where the indices correspond to the index of the group within
|
|
1833
1882
|
# link_groups
|
|
1834
1883
|
# As always, q, qd, qdd are lists of length n, where indices correspond
|
|
1835
|
-
# to the jindex of the joint, which
|
|
1836
|
-
# within link_groups
|
|
1884
|
+
# to the jindex of the joint, which is always the first link in the
|
|
1885
|
+
# group within link_groups
|
|
1837
1886
|
|
|
1838
1887
|
for k in range(l):
|
|
1839
1888
|
qk = q[k, :]
|
|
@@ -1842,48 +1891,43 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1842
1891
|
|
|
1843
1892
|
# forward recursion
|
|
1844
1893
|
for j, group in enumerate(link_groups):
|
|
1845
|
-
#
|
|
1846
|
-
|
|
1894
|
+
# group[0] is always the joint (see the grouping loop
|
|
1895
|
+
# above); any static links after it in the group are
|
|
1896
|
+
# rigidly carried by this joint's own output frame and are
|
|
1897
|
+
# folded into I[j] directly instead, not into this
|
|
1898
|
+
# kinematic frame -- v[j]/a[j] stay defined at the joint's
|
|
1899
|
+
# own output, matching s[j]/vJ, which are themselves only
|
|
1900
|
+
# ever expressed there.
|
|
1901
|
+
joint = self.links[group[0]]
|
|
1847
1902
|
jindex = joint.jindex
|
|
1848
1903
|
|
|
1849
1904
|
vJ = SpatialVelocity(s[j] * qdk[jindex])
|
|
1850
1905
|
|
|
1851
|
-
# transform from parent(j) to j
|
|
1852
|
-
#
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
if link.isjoint and link.jindex is not None:
|
|
1858
|
-
if first_element:
|
|
1859
|
-
Xup_int = SE3(link.A(qk[link.jindex]))
|
|
1860
|
-
first_element = False
|
|
1861
|
-
else:
|
|
1862
|
-
Xup_int = Xup_int * SE3(link.A(qk[link.jindex]))
|
|
1863
|
-
else:
|
|
1864
|
-
if first_element:
|
|
1865
|
-
Xup_int = SE3(link.A())
|
|
1866
|
-
first_element = False
|
|
1867
|
-
else:
|
|
1868
|
-
Xup_int = Xup_int * SE3(link.A())
|
|
1869
|
-
|
|
1906
|
+
# transform from parent(j) to j: joint.A() already
|
|
1907
|
+
# incorporates any fixed transform within the joint link's
|
|
1908
|
+
# own ETS (the joint variable is guaranteed to be the last
|
|
1909
|
+
# element of its segment -- see this method's docstring),
|
|
1910
|
+
# so no further composition is needed.
|
|
1911
|
+
Xup_int = SE3(joint.A(qk[jindex]))
|
|
1870
1912
|
Xup[j] = Xup_int.inv() # type: ignore[union-attr]
|
|
1871
1913
|
|
|
1872
|
-
#
|
|
1873
|
-
|
|
1914
|
+
# group_of_link_idx also covers a joint whose immediate
|
|
1915
|
+
# .parent is a static link, or a run of them, rather than
|
|
1916
|
+
# another joint directly -- returning None (rather than
|
|
1917
|
+
# raising) when that walk reaches the root with no joint
|
|
1918
|
+
# ancestor at all (e.g. a static base link, such as URDF
|
|
1919
|
+
# Panda's panda_link0), which is kinematically equivalent
|
|
1920
|
+
# to .parent being None.
|
|
1921
|
+
group_idx = (
|
|
1922
|
+
group_of_link_idx.get(self.links.index(joint.parent))
|
|
1923
|
+
if joint.parent is not None
|
|
1924
|
+
else None
|
|
1925
|
+
)
|
|
1874
1926
|
|
|
1875
|
-
if
|
|
1927
|
+
if group_idx is None:
|
|
1876
1928
|
v[j] = vJ
|
|
1877
1929
|
a[j] = Xup[j] * a_grav + SpatialAcceleration(s[j] * qddk[jindex])
|
|
1878
1930
|
else:
|
|
1879
|
-
# The index of `link`s parent within self.links
|
|
1880
|
-
parent_idx = self.links.index(first_link.parent)
|
|
1881
|
-
|
|
1882
|
-
# The index of the group that the parent link is in
|
|
1883
|
-
group_idx = [
|
|
1884
|
-
i for i, group in enumerate(link_groups) if parent_idx in group
|
|
1885
|
-
][0]
|
|
1886
|
-
|
|
1887
1931
|
v[j] = Xup[j] * v[group_idx] + vJ
|
|
1888
1932
|
a[j] = (
|
|
1889
1933
|
Xup[j] * a[group_idx]
|
|
@@ -1896,9 +1940,7 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1896
1940
|
# Backward recursion
|
|
1897
1941
|
for j in reversed(range(n)):
|
|
1898
1942
|
group = link_groups[j]
|
|
1899
|
-
joint = self.links[group[
|
|
1900
|
-
first_link = self.links[group[0]]
|
|
1901
|
-
# link = self.links[j]
|
|
1943
|
+
joint = self.links[group[0]] # always the joint -- see above
|
|
1902
1944
|
|
|
1903
1945
|
# next line could be dot(), but fails for symbolic arguments
|
|
1904
1946
|
Q[k, j] = sum(f[j].A * s[j])
|
|
@@ -1913,16 +1955,26 @@ class Robot(BaseRobot[Link], RobotKinematicsMixin):
|
|
|
1913
1955
|
- joint.friction(qdk[jindex], coulomb=not symbolic)
|
|
1914
1956
|
)
|
|
1915
1957
|
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1958
|
+
# See the forward recursion above: group_of_link_idx
|
|
1959
|
+
# resolves through any static link(s) between this joint
|
|
1960
|
+
# and its nearest joint ancestor, returning None if there
|
|
1961
|
+
# isn't one (root).
|
|
1962
|
+
group_idx = (
|
|
1963
|
+
group_of_link_idx.get(self.links.index(joint.parent))
|
|
1964
|
+
if joint.parent is not None
|
|
1965
|
+
else None
|
|
1966
|
+
)
|
|
1924
1967
|
|
|
1925
|
-
|
|
1968
|
+
if group_idx is not None:
|
|
1969
|
+
# Xup[j] is the child<-parent motion transform (v_child =
|
|
1970
|
+
# Xup[j] * v_parent); propagating a force the other way,
|
|
1971
|
+
# child->parent, needs the transform in the other
|
|
1972
|
+
# direction too. spatialmath's SE3 * SpatialForce applies
|
|
1973
|
+
# the coadjoint of its left operand (since
|
|
1974
|
+
# spatialmath-python 1.1.18, rai-opensource/
|
|
1975
|
+
# spatialmath-python#207), so the un-inverted transform
|
|
1976
|
+
# (Xup[j].inv(), i.e. parent<-child) is what's needed here.
|
|
1977
|
+
f[group_idx] = f[group_idx] + Xup[j].inv() * f[j]
|
|
1926
1978
|
|
|
1927
1979
|
# The current Q has the length equal to the number of links within the robot
|
|
1928
1980
|
# rather than the number of joints. We need to remove the static links
|
|
@@ -21,6 +21,16 @@ class RobotKinematicsMixin:
|
|
|
21
21
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
+
def _resolve_tool(self: KinematicsProtocol, tool: NDArray | SE3 | None) -> SE3:
|
|
25
|
+
"""
|
|
26
|
+
Resolve an explicit ``tool`` argument, defaulting to the robot's
|
|
27
|
+
own :attr:`tool` (identity if never set) when not given explicitly
|
|
28
|
+
-- see :meth:`fkine`'s ``tool`` parameter.
|
|
29
|
+
"""
|
|
30
|
+
if tool is None:
|
|
31
|
+
return self.tool
|
|
32
|
+
return tool if isinstance(tool, SE3) else SE3(tool, check=False)
|
|
33
|
+
|
|
24
34
|
# --------------------------------------------------------------------- #
|
|
25
35
|
# --------- Kinematic Methods ----------------------------------------- #
|
|
26
36
|
# --------------------------------------------------------------------- #
|
|
@@ -85,9 +95,11 @@ class RobotKinematicsMixin:
|
|
|
85
95
|
specify ``end``
|
|
86
96
|
- For a robot with multiple end-effectors, the ``end`` must
|
|
87
97
|
be specified.
|
|
88
|
-
- The robot's base
|
|
89
|
-
into the result.
|
|
90
|
-
-
|
|
98
|
+
- The robot's own base transform (``self.base``), if set, is
|
|
99
|
+
always incorporated into the result.
|
|
100
|
+
- The robot's own tool transform (``self.tool``), if set, is
|
|
101
|
+
incorporated into the result unless the ``tool`` parameter is
|
|
102
|
+
given explicitly, which overrides it.
|
|
91
103
|
- Works from the end-effector link to the base
|
|
92
104
|
|
|
93
105
|
.. rubric:: References
|
|
@@ -101,7 +113,10 @@ class RobotKinematicsMixin:
|
|
|
101
113
|
|
|
102
114
|
return SE3(
|
|
103
115
|
self.ets(start, end).fkine(
|
|
104
|
-
q,
|
|
116
|
+
q,
|
|
117
|
+
base=self._T,
|
|
118
|
+
tool=self._resolve_tool(tool),
|
|
119
|
+
include_base=include_base,
|
|
105
120
|
),
|
|
106
121
|
check=False,
|
|
107
122
|
)
|
|
@@ -155,7 +170,7 @@ class RobotKinematicsMixin:
|
|
|
155
170
|
|
|
156
171
|
"""
|
|
157
172
|
|
|
158
|
-
return self.ets(start, end).jacob0(q, tool=tool)
|
|
173
|
+
return self.ets(start, end).jacob0(q, tool=self._resolve_tool(tool))
|
|
159
174
|
|
|
160
175
|
def jacobe(
|
|
161
176
|
self: KinematicsProtocol,
|
|
@@ -206,7 +221,7 @@ class RobotKinematicsMixin:
|
|
|
206
221
|
|
|
207
222
|
"""
|
|
208
223
|
|
|
209
|
-
return self.ets(start, end).jacobe(q, tool=tool)
|
|
224
|
+
return self.ets(start, end).jacobe(q, tool=self._resolve_tool(tool))
|
|
210
225
|
|
|
211
226
|
@overload
|
|
212
227
|
def hessian0(
|
|
@@ -306,7 +321,7 @@ class RobotKinematicsMixin:
|
|
|
306
321
|
|
|
307
322
|
"""
|
|
308
323
|
|
|
309
|
-
return self.ets(start, end).hessian0(q, J0=J0, tool=tool)
|
|
324
|
+
return self.ets(start, end).hessian0(q, J0=J0, tool=self._resolve_tool(tool))
|
|
310
325
|
|
|
311
326
|
@overload
|
|
312
327
|
def hessiane(
|
|
@@ -406,7 +421,7 @@ class RobotKinematicsMixin:
|
|
|
406
421
|
|
|
407
422
|
"""
|
|
408
423
|
|
|
409
|
-
return self.ets(start, end).hessiane(q, Je=Je, tool=tool)
|
|
424
|
+
return self.ets(start, end).hessiane(q, Je=Je, tool=self._resolve_tool(tool))
|
|
410
425
|
|
|
411
426
|
def partial_fkine0(
|
|
412
427
|
self: KinematicsProtocol,
|
|
@@ -506,7 +521,7 @@ class RobotKinematicsMixin:
|
|
|
506
521
|
"""
|
|
507
522
|
|
|
508
523
|
return self.ets(start, end).jacob0_analytical(
|
|
509
|
-
q, tool=tool, representation=representation
|
|
524
|
+
q, tool=self._resolve_tool(tool), representation=representation
|
|
510
525
|
)
|
|
511
526
|
|
|
512
527
|
# --------------------------------------------------------------------- #
|
|
@@ -526,6 +541,7 @@ class RobotKinematicsMixin:
|
|
|
526
541
|
joint_limits: bool = True,
|
|
527
542
|
k: float = 1.0,
|
|
528
543
|
method: L["chan", "wampler", "sugihara"] = "chan",
|
|
544
|
+
tool: NDArray | SE3 | None = None,
|
|
529
545
|
) -> IKSolution:
|
|
530
546
|
r"""
|
|
531
547
|
Fast Levenberg-Marquardt Numerical Inverse Kinematics Solver
|
|
@@ -544,6 +560,9 @@ class RobotKinematicsMixin:
|
|
|
544
560
|
:param k: Sets the gain value for the damping matrix Wn in the next iteration
|
|
545
561
|
:param method: One of "chan", "sugihara" or "wampler". Defines which method is used
|
|
546
562
|
to calculate the damping matrix Wn in the ``step`` method
|
|
563
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
564
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
565
|
+
not given
|
|
547
566
|
:returns: an IKSolution containing joint coordinates ``q``, ``success`` flag,
|
|
548
567
|
``iterations``, ``searches`` and ``residual`` error value (``reason`` is
|
|
549
568
|
always empty -- this fast C++ solver doesn't produce a granular failure
|
|
@@ -661,7 +680,7 @@ class RobotKinematicsMixin:
|
|
|
661
680
|
"""
|
|
662
681
|
|
|
663
682
|
return self.ets(start, end).ik_LM(
|
|
664
|
-
Tep=Tep,
|
|
683
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
665
684
|
q0=q0,
|
|
666
685
|
ilimit=ilimit,
|
|
667
686
|
slimit=slimit,
|
|
@@ -685,6 +704,7 @@ class RobotKinematicsMixin:
|
|
|
685
704
|
joint_limits: bool = True,
|
|
686
705
|
pinv: int = True,
|
|
687
706
|
pinv_damping: float = 0.0,
|
|
707
|
+
tool: NDArray | SE3 | None = None,
|
|
688
708
|
) -> IKSolution:
|
|
689
709
|
r"""
|
|
690
710
|
Fast numerical inverse kinematics using Newton-Raphson optimization
|
|
@@ -705,6 +725,9 @@ class RobotKinematicsMixin:
|
|
|
705
725
|
another search up to the slimit)
|
|
706
726
|
:param pinv: Use the pseudo-inverse instead of the normal matrix inverse
|
|
707
727
|
:param pinv_damping: Damping factor for the pseudo-inverse
|
|
728
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
729
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
730
|
+
not given
|
|
708
731
|
:returns: an IKSolution containing joint coordinates ``q``, ``success`` flag,
|
|
709
732
|
``iterations``, ``searches`` and ``residual`` error value (``reason`` is
|
|
710
733
|
always empty -- this fast C++ solver doesn't produce a granular failure
|
|
@@ -782,7 +805,7 @@ class RobotKinematicsMixin:
|
|
|
782
805
|
"""
|
|
783
806
|
|
|
784
807
|
return self.ets(start, end).ik_NR(
|
|
785
|
-
Tep=Tep,
|
|
808
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
786
809
|
q0=q0,
|
|
787
810
|
ilimit=ilimit,
|
|
788
811
|
slimit=slimit,
|
|
@@ -806,6 +829,7 @@ class RobotKinematicsMixin:
|
|
|
806
829
|
joint_limits: bool = True,
|
|
807
830
|
pinv: int = True,
|
|
808
831
|
pinv_damping: float = 0.0,
|
|
832
|
+
tool: NDArray | SE3 | None = None,
|
|
809
833
|
) -> IKSolution:
|
|
810
834
|
r"""
|
|
811
835
|
Fast numerical inverse kinematics by Gauss-Newton optimization
|
|
@@ -826,6 +850,9 @@ class RobotKinematicsMixin:
|
|
|
826
850
|
another search up to the slimit)
|
|
827
851
|
:param pinv: Use the pseudo-inverse instead of the normal matrix inverse
|
|
828
852
|
:param pinv_damping: Damping factor for the pseudo-inverse
|
|
853
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
854
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
855
|
+
not given
|
|
829
856
|
:returns: an IKSolution containing joint coordinates ``q``, ``success`` flag,
|
|
830
857
|
``iterations``, ``searches`` and ``residual`` error value (``reason`` is
|
|
831
858
|
always empty -- this fast C++ solver doesn't produce a granular failure
|
|
@@ -918,7 +945,7 @@ class RobotKinematicsMixin:
|
|
|
918
945
|
"""
|
|
919
946
|
|
|
920
947
|
return self.ets(start, end).ik_GN(
|
|
921
|
-
Tep=Tep,
|
|
948
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
922
949
|
q0=q0,
|
|
923
950
|
ilimit=ilimit,
|
|
924
951
|
slimit=slimit,
|
|
@@ -947,6 +974,7 @@ class RobotKinematicsMixin:
|
|
|
947
974
|
km: float = 0.0,
|
|
948
975
|
ps: float = 0.0,
|
|
949
976
|
pi: NDArray | float = 0.3,
|
|
977
|
+
tool: NDArray | SE3 | None = None,
|
|
950
978
|
**kwargs,
|
|
951
979
|
):
|
|
952
980
|
r"""
|
|
@@ -976,6 +1004,9 @@ class RobotKinematicsMixin:
|
|
|
976
1004
|
allowed to approach to its limit
|
|
977
1005
|
:param pi: The influence angle/distance (in radians or metres) in null space motion
|
|
978
1006
|
becomes active
|
|
1007
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
1008
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
1009
|
+
not given
|
|
979
1010
|
:returns: an IKSolution containing joint coordinates ``q``, ``success`` flag,
|
|
980
1011
|
``iterations``, ``searches``, ``residual`` error value, and ``reason``
|
|
981
1012
|
string if applicable
|
|
@@ -1096,7 +1127,7 @@ class RobotKinematicsMixin:
|
|
|
1096
1127
|
"""
|
|
1097
1128
|
|
|
1098
1129
|
return self.ets(start, end).ikine_LM(
|
|
1099
|
-
Tep=Tep,
|
|
1130
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
1100
1131
|
q0=q0,
|
|
1101
1132
|
ilimit=ilimit,
|
|
1102
1133
|
slimit=slimit,
|
|
@@ -1130,6 +1161,7 @@ class RobotKinematicsMixin:
|
|
|
1130
1161
|
km: float = 0.0,
|
|
1131
1162
|
ps: float = 0.0,
|
|
1132
1163
|
pi: NDArray | float = 0.3,
|
|
1164
|
+
tool: NDArray | SE3 | None = None,
|
|
1133
1165
|
**kwargs,
|
|
1134
1166
|
):
|
|
1135
1167
|
r"""
|
|
@@ -1158,6 +1190,9 @@ class RobotKinematicsMixin:
|
|
|
1158
1190
|
allowed to approach to its limit
|
|
1159
1191
|
:param pi: The influence angle/distance (in radians or metres) in null space motion
|
|
1160
1192
|
becomes active
|
|
1193
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
1194
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
1195
|
+
not given
|
|
1161
1196
|
|
|
1162
1197
|
A method which provides functionality to perform numerical inverse kinematics (IK)
|
|
1163
1198
|
using the Newton-Raphson method.
|
|
@@ -1222,7 +1257,7 @@ class RobotKinematicsMixin:
|
|
|
1222
1257
|
"""
|
|
1223
1258
|
|
|
1224
1259
|
return self.ets(start, end).ikine_NR(
|
|
1225
|
-
Tep=Tep,
|
|
1260
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
1226
1261
|
q0=q0,
|
|
1227
1262
|
ilimit=ilimit,
|
|
1228
1263
|
slimit=slimit,
|
|
@@ -1255,6 +1290,7 @@ class RobotKinematicsMixin:
|
|
|
1255
1290
|
km: float = 0.0,
|
|
1256
1291
|
ps: float = 0.0,
|
|
1257
1292
|
pi: NDArray | float = 0.3,
|
|
1293
|
+
tool: NDArray | SE3 | None = None,
|
|
1258
1294
|
**kwargs,
|
|
1259
1295
|
):
|
|
1260
1296
|
r"""
|
|
@@ -1283,6 +1319,9 @@ class RobotKinematicsMixin:
|
|
|
1283
1319
|
allowed to approach to its limit
|
|
1284
1320
|
:param pi: The influence angle/distance (in radians or metres) in null space motion
|
|
1285
1321
|
becomes active
|
|
1322
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
1323
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
1324
|
+
not given
|
|
1286
1325
|
|
|
1287
1326
|
A method which provides functionality to perform numerical inverse kinematics (IK)
|
|
1288
1327
|
using the Gauss-Newton method.
|
|
@@ -1362,7 +1401,7 @@ class RobotKinematicsMixin:
|
|
|
1362
1401
|
"""
|
|
1363
1402
|
|
|
1364
1403
|
return self.ets(start, end).ikine_GN(
|
|
1365
|
-
Tep=Tep,
|
|
1404
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
1366
1405
|
q0=q0,
|
|
1367
1406
|
ilimit=ilimit,
|
|
1368
1407
|
slimit=slimit,
|
|
@@ -1396,6 +1435,7 @@ class RobotKinematicsMixin:
|
|
|
1396
1435
|
km: float = 0.0,
|
|
1397
1436
|
ps: float = 0.0,
|
|
1398
1437
|
pi: NDArray | float = 0.3,
|
|
1438
|
+
tool: NDArray | SE3 | None = None,
|
|
1399
1439
|
**kwargs,
|
|
1400
1440
|
):
|
|
1401
1441
|
r"""
|
|
@@ -1424,6 +1464,9 @@ class RobotKinematicsMixin:
|
|
|
1424
1464
|
allowed to approach to its limit
|
|
1425
1465
|
:param pi: The influence angle/distance (in radians or metres) in null space motion
|
|
1426
1466
|
becomes active
|
|
1467
|
+
:param tool: a static tool transformation matrix to apply to the
|
|
1468
|
+
end of ``end``; defaults to the robot's own ``self.tool`` if
|
|
1469
|
+
not given
|
|
1427
1470
|
:raises ImportError: If the package ``qpsolvers`` is not installed
|
|
1428
1471
|
:returns: an IKSolution containing joint coordinates ``q``, ``success`` flag,
|
|
1429
1472
|
``iterations``, ``searches``, ``residual`` error value, and ``reason``
|
|
@@ -1541,7 +1584,7 @@ class RobotKinematicsMixin:
|
|
|
1541
1584
|
"""
|
|
1542
1585
|
|
|
1543
1586
|
return self.ets(start, end).ikine_QP(
|
|
1544
|
-
Tep=Tep,
|
|
1587
|
+
Tep=SE3(Tep, check=False) * self._resolve_tool(tool).inv(),
|
|
1545
1588
|
q0=q0,
|
|
1546
1589
|
ilimit=ilimit,
|
|
1547
1590
|
slimit=slimit,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: roboticstoolbox-python
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.4
|
|
4
4
|
Summary: A Python library for robotics education and research
|
|
5
5
|
Keywords: python,robotics,robotics-toolbox,kinematics,dynamics,motion-planning,trajectory-generation,jacobian,hessian,control,simulation,robot-manipulator,mobile-robot
|
|
6
6
|
Author-Email: Jesse Haviland <j.haviland@qut.edu.au>, Peter Corke <rvc@petercorke.com>
|
|
@@ -39,7 +39,7 @@ Project-URL: documentation, https://petercorke.github.io/robotics-toolbox-python
|
|
|
39
39
|
Project-URL: repository, https://github.com/petercorke/robotics-toolbox-python
|
|
40
40
|
Requires-Python: >=3.10
|
|
41
41
|
Requires-Dist: numpy
|
|
42
|
-
Requires-Dist: spatialmath-python>=1.1.
|
|
42
|
+
Requires-Dist: spatialmath-python>=1.1.18
|
|
43
43
|
Requires-Dist: spatialgeometry>=1.4.0
|
|
44
44
|
Requires-Dist: pgraph-python
|
|
45
45
|
Requires-Dist: scipy
|
|
@@ -543,44 +543,4 @@ Graphical visualisation via Swift is currently not supported under Windows. Howe
|
|
|
543
543
|
|
|
544
544
|
The toolbox is incredibly useful for developing and prototyping algorithms for research, thanks to the exhaustive set of well documented and mature robotic functions exposed through clean and painless APIs. Additionally, the ease at which a user can visualize their algorithm supports a rapid prototyping paradigm.
|
|
545
545
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
J. Haviland, N. Sünderhauf and P. Corke, "**A Holistic Approach to Reactive Mobile Manipulation**," in _IEEE Robotics and Automation Letters_, doi: 10.1109/LRA.2022.3146554. In the video, the robot is controlled using the Robotics toolbox for Python and features a recording from the [Swift](https://github.com/jhavl/swift) Simulator.
|
|
549
|
-
|
|
550
|
-
[[Arxiv Paper](https://arxiv.org/abs/2109.04749)] [[IEEE Xplore](https://ieeexplore.ieee.org/abstract/document/9695298)] [[Project Website](https://jhavl.github.io/holistic/)] [[Video](https://youtu.be/-DXBQPeLIV4)] [[Code Example](https://github.com/petercorke/robotics-toolbox-python/blob/main/roboticstoolbox/examples/holistic_mm_non_holonomic.py)]
|
|
551
|
-
|
|
552
|
-
<p>
|
|
553
|
-
<a href="https://youtu.be/-DXBQPeLIV4">
|
|
554
|
-
<img src="https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/main/docs/figs/holistic_youtube.png" width="560">
|
|
555
|
-
</a>
|
|
556
|
-
</p>
|
|
557
|
-
|
|
558
|
-
J. Haviland and P. Corke, "**NEO: A Novel Expeditious Optimisation Algorithm for Reactive Motion Control of Manipulators**," in _IEEE Robotics and Automation Letters_, doi: 10.1109/LRA.2021.3056060. In the video, the robot is controlled using the Robotics toolbox for Python and features a recording from the [Swift](https://github.com/jhavl/swift) Simulator.
|
|
559
|
-
|
|
560
|
-
[[Arxiv Paper](https://arxiv.org/abs/2010.08686)] [[IEEE Xplore](https://ieeexplore.ieee.org/document/9343718)] [[Project Website](https://jhavl.github.io/neo/)] [[Video](https://youtu.be/jSLPJBr8QTY)] [[Code Example](https://github.com/petercorke/robotics-toolbox-python/blob/main/roboticstoolbox/examples/neo.py)]
|
|
561
|
-
|
|
562
|
-
<p>
|
|
563
|
-
<a href="https://youtu.be/jSLPJBr8QTY">
|
|
564
|
-
<img src="https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/main/docs/figs/neo_youtube.png" width="560">
|
|
565
|
-
</a>
|
|
566
|
-
</p>
|
|
567
|
-
|
|
568
|
-
K. He, R. Newbury, T. Tran, J. Haviland, B. Burgess-Limerick, D. Kulić, P. Corke, A. Cosgun, "**Visibility Maximization Controller for Robotic Manipulation**", in _IEEE Robotics and Automation Letters_, doi: 10.1109/LRA.2022.3188430. In the video, the robot is controlled using the Robotics toolbox for Python and features a recording from the [Swift](https://github.com/jhavl/swift) Simulator.
|
|
569
|
-
|
|
570
|
-
[[Arxiv Paper](https://arxiv.org/abs/2202.12557)] [[IEEE Xplore](https://ieeexplore.ieee.org/abstract/document/9815144)] [[Project Website](https://rhys-newbury.github.io/projects/vmc/)] [[Video](https://youtu.be/vobLvg4E3kM)] [[Code Example](https://github.com/petercorke/robotics-toolbox-python/blob/main/roboticstoolbox/examples/fetch_vision.py)]
|
|
571
|
-
|
|
572
|
-
<p>
|
|
573
|
-
<a href="https://youtu.be/vobLvg4E3kM">
|
|
574
|
-
<img src="https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/main/docs/figs/vmc_youtube.png" width="560">
|
|
575
|
-
</a>
|
|
576
|
-
</p>
|
|
577
|
-
|
|
578
|
-
**A Purely-Reactive Manipulability-Maximising Motion Controller**, J. Haviland and P. Corke. In the video, the robot is controlled using the Robotics toolbox for Python.
|
|
579
|
-
|
|
580
|
-
[[Paper](https://arxiv.org/abs/2002.11901)] [[Project Website](https://jhavl.github.io/mmc/)] [[Video](https://youtu.be/Vu_rcPlaADI)] [[Code Example](https://github.com/petercorke/robotics-toolbox-python/blob/main/roboticstoolbox/examples/mmc.py)]
|
|
581
|
-
|
|
582
|
-
<p>
|
|
583
|
-
<a href="https://youtu.be/Vu_rcPlaADI">
|
|
584
|
-
<img src="https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/main/docs/figs/mmc_youtube.png" width="560">
|
|
585
|
-
</a>
|
|
586
|
-
</p>
|
|
546
|
+
It's been the implementation substrate for several published reactive-control papers, and its kinematics are a direct implementation of a two-part differential-kinematics tutorial — see the wiki's [Reactive control](https://github.com/petercorke/robotics-toolbox-python/wiki/Reactive-control) and [Inverse kinematics](https://github.com/petercorke/robotics-toolbox-python/wiki/Inverse-kinematics) pages.
|
|
@@ -30,7 +30,7 @@ roboticstoolbox/backends/__init__.py,sha256=WXkKfxqjgu_LdyyvZT0qmYT5bZ9XtRJQvEn_
|
|
|
30
30
|
roboticstoolbox/backends/swift/__init__.py,sha256=uenayFsFBt1k3565I8rxjMHgyW3mrFhLXimRF5LYPn0,7077
|
|
31
31
|
roboticstoolbox/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
roboticstoolbox/bin/_bintools.py,sha256=ofTQ47u8sixdJGIxMzcxHsBRtWyenSVGhCqUKV8rF5c,1903
|
|
33
|
-
roboticstoolbox/bin/rtbtool.py,sha256=
|
|
33
|
+
roboticstoolbox/bin/rtbtool.py,sha256=9OEfJ_dRCg0jMimP3O4TdIPsi5TjepB7Pr_9mYvgcdg,12206
|
|
34
34
|
roboticstoolbox/blocks/Icons/250x250/armplot.png,sha256=3bZtXa_ZaLRtzEXZSooLEBp3EPFmEIaVIUQCT3bY8-8,5918
|
|
35
35
|
roboticstoolbox/blocks/Icons/250x250/bicycle.png,sha256=BEQkGUY81Bms4gvdBechZzbgZClTSOq9YqX03-XuVZk,8995
|
|
36
36
|
roboticstoolbox/blocks/Icons/250x250/camera.png,sha256=CGcTB_llMoucN-rfnP6ZP_7AfE_92z6JnCdam-hDLgs,1642
|
|
@@ -468,7 +468,7 @@ roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/MatrixCwiseUnaryOps.h,sha25
|
|
|
468
468
|
roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ReshapedMethods.h,sha256=OYyO_yoZ3TL7X8GFrIW-IKzqs_1LbM0M96HJyZAVOi8,6915
|
|
469
469
|
roboticstoolbox/ets/cpp-extensions/README.md,sha256=xLvpxXx8xbe-wElyzpODFOxairojzFyGgeeCjXYQyMQ,3666
|
|
470
470
|
roboticstoolbox/ets/cpp-extensions/fknm_nb.cpp,sha256=Zent7Jp9gn-Cg6Y2nZnrgaaMwi-WBrZ9tAuXE1ybz4A,22027
|
|
471
|
-
roboticstoolbox/ets/cpp-extensions/ik.cpp,sha256=
|
|
471
|
+
roboticstoolbox/ets/cpp-extensions/ik.cpp,sha256=6B4cDKiVc_5WKGba-bTE_ngB7_jU9gyQXa3tGGZEku0,13132
|
|
472
472
|
roboticstoolbox/ets/cpp-extensions/ik.h,sha256=OkgTgJ4tV8P47elnQCOnM76n8ru0PpkZPCQFmUn7fWY,1780
|
|
473
473
|
roboticstoolbox/ets/cpp-extensions/linalg.cpp,sha256=D8c4GmITlK_2ardbeUys6SyuoTKqSYrSke0144caFpc,8905
|
|
474
474
|
roboticstoolbox/ets/cpp-extensions/linalg.h,sha256=YeuiXgnFGHjmgv3GMN4q_veR3fLdnoEa00LLJk6Opos,1862
|
|
@@ -520,7 +520,7 @@ roboticstoolbox/models/DH/README.md,sha256=h8F7jSpP-6v0u4Ika5YEYluZg6qxTXQVsO6c8
|
|
|
520
520
|
roboticstoolbox/models/DH/Sawyer.py,sha256=WUeAeQeJ7-Kw6rvJAcAIr0IwhNeFl_SPnpOdlB3xKVM,2084
|
|
521
521
|
roboticstoolbox/models/DH/Stanford.py,sha256=fOLeK6oo6Zmr9-93Wd2yZJLIkDqMqm2WG6HNUHEGUtU,3908
|
|
522
522
|
roboticstoolbox/models/DH/TwoLink.py,sha256=EavoSjY8waes_WehZ5TVs3EDfD2N1kMwgoJtuuPiHd4,6077
|
|
523
|
-
roboticstoolbox/models/DH/UR10.py,sha256
|
|
523
|
+
roboticstoolbox/models/DH/UR10.py,sha256=mj-smTlQox9nIqTOqXec0gXPFjvNlMn4dMbF8Ip_XPQ,3736
|
|
524
524
|
roboticstoolbox/models/DH/UR3.py,sha256=ZHq5ayfCdU2HW2yV8Yist8BC8PKR1woKWRka3pO6e34,2483
|
|
525
525
|
roboticstoolbox/models/DH/UR5.py,sha256=yYxp5JABLTbQjwiDQksBeyNmjzJ5uH8_IEOqwPawpls,2534
|
|
526
526
|
roboticstoolbox/models/DH/Uprighttl.py,sha256=4bTrWW7uFTyoJCb4n9ivy1V8SCPCo0XLByo_Wni6-iw,571
|
|
@@ -536,21 +536,21 @@ roboticstoolbox/models/ETS/XYPanda.py,sha256=62_oLmwss-incP-NkaDdvKF7ee0gsbNsH7k
|
|
|
536
536
|
roboticstoolbox/models/ETS/__init__.py,sha256=GYPivBP0GXaX8nODS-3lRoppTISH4PEcXnKUNasDXB8,583
|
|
537
537
|
roboticstoolbox/models/README.md,sha256=2NHhybtNIE6rIViAw6ElKUd44zPM8umpM8pB4FpKUpU,1312
|
|
538
538
|
roboticstoolbox/models/URDF/AL5D.py,sha256=He4bM47R-nyO15jv0fYOtvKQV0nPcsubH9UKamt2A3Y,1192
|
|
539
|
-
roboticstoolbox/models/URDF/Fetch.py,sha256=
|
|
540
|
-
roboticstoolbox/models/URDF/Frankie.py,sha256=
|
|
541
|
-
roboticstoolbox/models/URDF/FrankieOmni.py,sha256=
|
|
542
|
-
roboticstoolbox/models/URDF/Jaco.py,sha256=
|
|
539
|
+
roboticstoolbox/models/URDF/Fetch.py,sha256=XZfV7wfIvy--3vTNqIq33TUdbLkFIznEjUzJJ0vaCsY,3164
|
|
540
|
+
roboticstoolbox/models/URDF/Frankie.py,sha256=FvZXXdT2-6VsnphkduiisDr4cmk_pZFq7w3s6Eqi-0s,2132
|
|
541
|
+
roboticstoolbox/models/URDF/FrankieOmni.py,sha256=D2TJSbxWD6LpW3_bh7uCtIFSBrE_kJqcHJdpC1NS2rc,2998
|
|
542
|
+
roboticstoolbox/models/URDF/Jaco.py,sha256=vwK88sHrMp6Q6gqHgDlbn4TiXfrwrD8jvEmgfVnb4V4,1415
|
|
543
543
|
roboticstoolbox/models/URDF/KinovaGen3.py,sha256=fsmxZX7kooNMqp_tUGGXJgh86GOG2OT3_shOhRIdaSQ,1580
|
|
544
544
|
roboticstoolbox/models/URDF/LBR.py,sha256=uzP-7FzCpF8mIhSiT8HoKuYeISOkYS-NkmTjmUJgQmA,1806
|
|
545
|
-
roboticstoolbox/models/URDF/PR2.py,sha256=
|
|
546
|
-
roboticstoolbox/models/URDF/Panda.py,sha256=
|
|
545
|
+
roboticstoolbox/models/URDF/PR2.py,sha256=ZEpFuOWXQW33l68EEP3QxnKs7l9lP0vHIvUJeVFDmc4,1612
|
|
546
|
+
roboticstoolbox/models/URDF/Panda.py,sha256=ws8YtoudZ88L9F6O2S7oioK3w_V4RzztMMLHqHAnJcU,2752
|
|
547
547
|
roboticstoolbox/models/URDF/Puma560.py,sha256=1WHxYNXkYgJ6TJ9xJpJzfkZlfHZA2N9HFS6_p1b171w,2881
|
|
548
|
-
roboticstoolbox/models/URDF/UR10.py,sha256=
|
|
549
|
-
roboticstoolbox/models/URDF/UR3.py,sha256=
|
|
550
|
-
roboticstoolbox/models/URDF/UR5.py,sha256=
|
|
551
|
-
roboticstoolbox/models/URDF/URDFRobot.py,sha256=
|
|
552
|
-
roboticstoolbox/models/URDF/Valkyrie.py,sha256=
|
|
553
|
-
roboticstoolbox/models/URDF/YuMi.py,sha256=
|
|
548
|
+
roboticstoolbox/models/URDF/UR10.py,sha256=Excq3j1nuaqWGw67UPmAlWoXICUMsngbY1NU1Uc4MA8,1203
|
|
549
|
+
roboticstoolbox/models/URDF/UR3.py,sha256=FIQTrAlqUrY8qeCkbNc2hpQPnxnv19cz_nlC1EM0JGg,1196
|
|
550
|
+
roboticstoolbox/models/URDF/UR5.py,sha256=vCM373teYtNMcQXyWLuqtNqCNVoEJBgbnwa-BSeo-44,2221
|
|
551
|
+
roboticstoolbox/models/URDF/URDFRobot.py,sha256=x6ItlP5oZBLXo0IZAijDyrZwZ-LiFHfFnRs5S7TLNLY,16632
|
|
552
|
+
roboticstoolbox/models/URDF/Valkyrie.py,sha256=E75Sl1fG9lM-iCtxy6mo8OymW7M8qnXkc-uJSWMmvew,4263
|
|
553
|
+
roboticstoolbox/models/URDF/YuMi.py,sha256=BrkpWMsOB9jFVeNVaw8MX_vAVYEBIOUrNI7gKbBMGC4,3375
|
|
554
554
|
roboticstoolbox/models/URDF/__init__.py,sha256=G4PNTfYRiYekdxssVHN8v3zPUWPhbcOrffJR9u6lWDo,1599
|
|
555
555
|
roboticstoolbox/models/URDF/px100.py,sha256=sEU-keutJh_KP30zQfV-n51UZoaLCD1SQgw2vf31Ipk,1240
|
|
556
556
|
roboticstoolbox/models/URDF/px150.py,sha256=NzGJ0pV9pLeS5mtaMvtLJpkcwvwYcSYpQcuqPTVxdqI,1243
|
|
@@ -566,16 +566,16 @@ roboticstoolbox/models/catalog.py,sha256=R-Lc_vHoOfae-afVS1olmoPu9cq7YTDfYqtCJeM
|
|
|
566
566
|
roboticstoolbox/robot/BaseRobot.py,sha256=OcUR9yMLDvUUTrD34FnoufoZOdbU2Lc-pRxn08g3OCk,82370
|
|
567
567
|
roboticstoolbox/robot/DHFactor.py,sha256=Bf-j7IvBKRA6_k3uev_ceQRMAC79D7W0Ir7kCJt4mec,15981
|
|
568
568
|
roboticstoolbox/robot/DHLink.py,sha256=_7FtGDuS_dVxFGUQx9-Vqj7EoLsMIhV9SwVDFpWBPWs,27815
|
|
569
|
-
roboticstoolbox/robot/DHRobot.py,sha256=
|
|
569
|
+
roboticstoolbox/robot/DHRobot.py,sha256=UTWuE7Fl2shooddEKQn2BQ6w5VHfNwClz2ljKYy093A,67041
|
|
570
570
|
roboticstoolbox/robot/Dynamics.py,sha256=iCplz4L1wT2OeXuS0acO9x8h4uxsifT67PV4TViUwZw,52479
|
|
571
571
|
roboticstoolbox/robot/ELink.py,sha256=sgA-1c-U0Gz6TxABSJvfauq2L0Wu_1_pGJVKfLgrGP8,525
|
|
572
572
|
roboticstoolbox/robot/ERobot.py,sha256=aUnSg91PwHyIHO6ipWtnNBNLYCftKGIxgYz1qX8wghg,567
|
|
573
573
|
roboticstoolbox/robot/Gripper.py,sha256=CYyXFBYbEp52-RX-b6xGWS3EH-Y2BsYdtaR8Q0yAm3s,6954
|
|
574
|
-
roboticstoolbox/robot/IK.py,sha256=
|
|
574
|
+
roboticstoolbox/robot/IK.py,sha256=8s_YwcU22IxcMwke9yHX-ssv5HvdtHf_2vcuknhimBg,50270
|
|
575
575
|
roboticstoolbox/robot/Link.py,sha256=m98nfpv61C5Z1GDrOV_iN6gxyh9qj8URwiju9ssKXxw,46283
|
|
576
576
|
roboticstoolbox/robot/PoERobot.py,sha256=mByMjb3P5FrW3Z8zyLS5waYcKBy8lpHG44g2uBUyB70,11053
|
|
577
|
-
roboticstoolbox/robot/Robot.py,sha256
|
|
578
|
-
roboticstoolbox/robot/RobotKinematics.py,sha256=
|
|
577
|
+
roboticstoolbox/robot/Robot.py,sha256=rkzRa9LTrTBIuSI0dbT1SjI44YdX5VS-1OuPm2W1Q6U,82555
|
|
578
|
+
roboticstoolbox/robot/RobotKinematics.py,sha256=0K-bdowzzzPUnImSVAxRylucSAyl-dyfhP7_4hpcvrs,64448
|
|
579
579
|
roboticstoolbox/robot/RobotPlottingMPL.py,sha256=tmIGievDZwtLkd0To0Of2MeAB38yvbUd8T0bF0qwLd8,14207
|
|
580
580
|
roboticstoolbox/robot/RobotProto.py,sha256=os5bJSXp4ZO-ANJjaSF8_Xb-TJxbCg1Ry_obS3A6LqM,4339
|
|
581
581
|
roboticstoolbox/robot/__init__.py,sha256=RUeji1GTnAL3U3mn0ae6W1lnmvC-CFlUw5U7RTQnvO8,1237
|
|
@@ -604,8 +604,8 @@ roboticstoolbox/tools/urdf/tests/data/ur5.urdf,sha256=9g0uYkRHRsWHWl6vn5lIK_JMHq
|
|
|
604
604
|
roboticstoolbox/tools/urdf/tests/test_urdf.py,sha256=MoRP8DolFu7RXxrKkwEWJOSfVygX7UJwEv-hLZkdlKw,3445
|
|
605
605
|
roboticstoolbox/tools/urdf/urdf.py,sha256=IE5EUSNjkOAZZUOkuhXKDhYRq2AuJGulIvfbsRHy7pI,58743
|
|
606
606
|
roboticstoolbox/tools/urdf/utils.py,sha256=6g1uuI2u7CUaWhKavI7wDHT3a2T3ijb92JByQ1lNq6w,1483
|
|
607
|
-
roboticstoolbox_python-1.4.
|
|
608
|
-
roboticstoolbox_python-1.4.
|
|
609
|
-
roboticstoolbox_python-1.4.
|
|
610
|
-
roboticstoolbox_python-1.4.
|
|
611
|
-
roboticstoolbox_python-1.4.
|
|
607
|
+
roboticstoolbox_python-1.4.4.dist-info/METADATA,sha256=VEV1p5AVn9XeJpI3VhDpvo9PYFA9mKufl8XwcQwYu1Y,24258
|
|
608
|
+
roboticstoolbox_python-1.4.4.dist-info/WHEEL,sha256=DJBbB-IMWy7eyPvSdm5L2t-BbrULtweJWf0YC-blkl0,95
|
|
609
|
+
roboticstoolbox_python-1.4.4.dist-info/entry_points.txt,sha256=m9xEI6rJsYQL0HosyeS-4TUPzxOR3kqx4vbJVVxwo7k,214
|
|
610
|
+
roboticstoolbox_python-1.4.4.dist-info/licenses/LICENSE,sha256=oXNGHTPcMKl8PPZWk_4NIWGAtiaQcTgVJ1hpnTcnKFA,1062
|
|
611
|
+
roboticstoolbox_python-1.4.4.dist-info/RECORD,,
|
|
File without changes
|
{roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{roboticstoolbox_python-1.4.3.dist-info → roboticstoolbox_python-1.4.4.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|