|
10 | 10 | from spatialmath.base.argcheck import \
|
11 | 11 | getvector, ismatrix, isscalar, verifymatrix
|
12 | 12 | from spatialmath.base.transforms3d import tr2delta, tr2eul
|
13 |
| -from spatialmath import SE3 |
| 13 | +from spatialmath import SE3, Twist3 |
14 | 14 | from scipy.optimize import minimize, Bounds, LinearConstraint
|
15 | 15 | from frne import init, frne, delete
|
16 | 16 | from roboticstoolbox.backend.PyPlot.functions import \
|
@@ -483,51 +483,7 @@ def isspherical(self):
|
483 | 483 | else:
|
484 | 484 | return False
|
485 | 485 |
|
486 |
| - def payload(self, m, p=np.zeros(3)): |
487 |
| - """ |
488 |
| - payload(m, p) adds payload mass adds a payload with point mass m at |
489 |
| - position p in the end-effector coordinate frame. |
490 |
| -
|
491 |
| - payload(m) adds payload mass adds a payload with point mass m at |
492 |
| - in the end-effector coordinate frame. |
493 |
| -
|
494 |
| - payload(0) removes added payload. |
495 |
| -
|
496 |
| - :param m: mass (kg) |
497 |
| - :type m: float |
498 |
| - :param p: position in end-effector frame |
499 |
| - :type p: float ndarray(3,1) |
500 |
| -
|
501 |
| - """ |
502 |
| - |
503 |
| - p = getvector(p, 3, out='col') |
504 |
| - lastlink = self.links[self.n - 1] |
505 |
| - |
506 |
| - lastlink.m = m |
507 |
| - lastlink.r = p |
508 |
| - |
509 |
| - def jointdynamics(self, q, qd): |
510 |
| - """ |
511 |
| - Transfer function of joint actuator. |
512 | 486 |
|
513 |
| - tf = jointdynamics(qd, q) calculates a vector of n continuous-time |
514 |
| - transfer function objects that represent the transfer function |
515 |
| - 1/(Js+B) for each joint based on the dynamic parameters of the robot |
516 |
| - and the configuration q (n). n is the number of robot joints. |
517 |
| -
|
518 |
| - tf = jointdynamics(qd) as above except uses the stored q value of the |
519 |
| - robot object. |
520 |
| -
|
521 |
| - :param q: The joint angles/configuration of the robot (Optional, |
522 |
| - if not supplied will use the stored q values) |
523 |
| - :type q: float ndarray(n) |
524 |
| - :param qd: The joint velocities of the robot |
525 |
| - :type qd: float ndarray(n) |
526 |
| -
|
527 |
| - """ |
528 |
| - |
529 |
| - # TODO a tf object implementation? |
530 |
| - pass |
531 | 487 |
|
532 | 488 | def isprismatic(self):
|
533 | 489 | """
|
@@ -625,35 +581,52 @@ def toradians(self, q):
|
625 | 581 |
|
626 | 582 | def twists(self, q=None):
|
627 | 583 | """
|
628 |
| - Joint axis twists. |
629 |
| -
|
630 |
| - tw, T = twists(q) calculates a vector of Twist objects (n) that |
631 |
| - represent the axes of the joints for the robot with joint coordinates |
632 |
| - q (n). Also returns T0 which is an SE3 object representing the pose of |
633 |
| - the tool. |
634 |
| -
|
635 |
| - tw, T = twists() as above except uses the stored q value of the |
636 |
| - robot object. |
637 |
| -
|
638 |
| - :param q: The joint angles/configuration of the robot (Optional, |
639 |
| - if not supplied will use the stored q values) |
640 |
| - :type q: float ndarray(n) |
| 584 | + Joint axis as twists |
641 | 585 |
|
| 586 | + :param q: The joint angles/configuration of the robot |
| 587 | + :type q: array_like (n) |
642 | 588 | :return tw: a vector of Twist objects
|
643 | 589 | :rtype tw: float ndarray(n,)
|
644 | 590 | :return T0: Represents the pose of the tool
|
645 | 591 | :rtype T0: SE3
|
646 | 592 |
|
| 593 | + - ``tw, T0 = twists(q)`` calculates a vector of Twist objects (n) that |
| 594 | + represent the axes of the joints for the robot with joint coordinates |
| 595 | + ``q`` (n). Also returns T0 which is an SE3 object representing the pose of |
| 596 | + the tool. |
| 597 | +
|
| 598 | + - ``tw, T0 = twists()`` as above but the joint coordinates are taken to be |
| 599 | + zero. |
| 600 | +
|
647 | 601 | """
|
648 | 602 |
|
649 |
| - pass |
| 603 | + if q is None: |
| 604 | + q = np.zeros((self.n)) |
650 | 605 |
|
651 |
| - # if q is None: |
652 |
| - # q = np.copy(self.q) |
653 |
| - # else: |
654 |
| - # q = getvector(q, self.n) |
| 606 | + T = self.fkine_all(q) |
| 607 | + tw = Twist3.Alloc(self.n) |
| 608 | + if not self.mdh: |
| 609 | + # DH case |
| 610 | + for j in range(self.n): |
| 611 | + if j == 0: |
| 612 | + if self.links[j].sigma == 0: |
| 613 | + tw[j] = Twist3.R([0, 0, 1], [0, 0, 0]) # revolute |
| 614 | + else: |
| 615 | + tw[j] = Twist3.P([0, 0, 1]) # prismatic |
| 616 | + else: |
| 617 | + if self.links[j].sigma == 0: |
| 618 | + tw[j] = Twist3.R(T[j-1].a, T[j-1].t) # revolute |
| 619 | + else: |
| 620 | + tw[j] = Twist3.P(T[j-1].a) # prismatic |
| 621 | + else: |
| 622 | + # MDH case |
| 623 | + for j in range(self.n): |
| 624 | + if self.links[j].sigma == 0: |
| 625 | + tw[j] = Twist3.R(T[j].a, T[j].t) |
| 626 | + else: |
| 627 | + tw[j] = Twist3.P(T[j].a, T[j].t) |
655 | 628 |
|
656 |
| - # TODO Implement this |
| 629 | + return tw, T[-1] |
657 | 630 |
|
658 | 631 | def fkine(self, q=None):
|
659 | 632 | '''
|
@@ -715,10 +688,10 @@ def fkine(self, q=None):
|
715 | 688 |
|
716 | 689 | return t
|
717 | 690 |
|
718 |
| - def allfkine(self, q=None): |
| 691 | + def fkine_all(self, q=None): |
719 | 692 | '''
|
720 | 693 | Tall = allfkine(q) evaluates fkine for each joint within a robot and
|
721 |
| - returns a trajecotry of poses. |
| 694 | + returns a sequence of link frame poses. |
722 | 695 |
|
723 | 696 | Tall = allfkine() as above except uses the stored q value of the
|
724 | 697 | robot object.
|
|
0 commit comments