@@ -515,6 +515,7 @@ def reach(self):
515
515
def ets(self, start=None, end=None, explored=None, path=None):
516
516
"""
517
517
ERobot to ETS
518
+
518
519
:param start: start of path, defaults to ``base_link``
519
520
:type start: ELink or str, optional
520
521
:param end: end of path, defaults to end-effector
@@ -523,12 +524,15 @@ def ets(self, start=None, end=None, explored=None, path=None):
523
524
:raises TypeError: a bad link argument
524
525
:return: elementary transform sequence
525
526
:rtype: ETS instance
527
+
528
+
526
529
- ``robot.ets()`` is an ETS representing the kinematics from base to
527
530
end-effector.
528
531
- ``robot.ets(end=link)`` is an ETS representing the kinematics from
529
532
base to the link ``link`` specified as an ELink reference or a name.
530
533
- ``robot.ets(start=l1, end=l2)`` is an ETS representing the kinematics
531
534
from link ``l1`` to link ``l2``.
535
+
532
536
.. runblock:: pycon
533
537
>>> import roboticstoolbox as rtb
534
538
>>> panda = rtb.models.ETS.Panda()
@@ -575,6 +579,106 @@ def ets(self, start=None, end=None, explored=None, path=None):
575
579
return p
576
580
return None
577
581
582
+ # --------------------------------------------------------------------- #
583
+
584
+ def segments(self):
585
+ """
586
+ Segments of branched robot
587
+
588
+ :return: Segment list
589
+ :rtype: list of lists of Link
590
+
591
+ For a single-chain robot with structure::
592
+
593
+ L1 - L2 - L3
594
+
595
+ the return is ``[[None, L1, L2, L3]]``
596
+
597
+ For a robot with structure::
598
+
599
+ L1 - L2 +- L3 - L4
600
+ +- L5 - L6
601
+
602
+ the return is ``[[None, L1, L2], [L2, L3, L4], [L2, L5, L6]]``
603
+
604
+ .. note::
605
+ - the length of the list is the number of segments in the robot
606
+ - the first segment always starts with ``None`` which represents
607
+ the base transform (since there is no base link)
608
+ - the last link of one segment is also the first link of subsequent
609
+ segments
610
+ """
611
+
612
+ def recurse(link):
613
+
614
+ segs = [link.parent]
615
+ while True:
616
+ segs.append(link)
617
+ if link.nchildren == 0:
618
+ return segs
619
+ elif link.nchildren == 1:
620
+ link = link.children[0]
621
+ continue
622
+ elif link.nchildren > 1:
623
+ segs = [segs]
624
+
625
+ for child in link.children:
626
+ segs.append(recurse(child))
627
+
628
+ return segs
629
+
630
+ return recurse(self.links[0])
631
+
632
+ # --------------------------------------------------------------------- #
633
+
634
+ def fkine_path(self, q, old=None):
635
+ '''
636
+ Compute the pose of every link frame
637
+
638
+ :param q: The joint configuration
639
+ :type q: darray(n)
640
+ :return: Pose of all links
641
+ :rtype: SE3 instance
642
+
643
+ ``T = robot.fkine_path(q)`` is an SE3 instance with ``robot.nlinks +
644
+ 1`` values:
645
+
646
+ - ``T[0]`` is the base transform
647
+ - ``T[i+1]`` is the pose of link whose ``number`` is ``i``
648
+
649
+ :references:
650
+ - Kinematic Derivatives using the Elementary Transform
651
+ Sequence, J. Haviland and P. Corke
652
+ '''
653
+ q = getvector(q)
654
+ Tbase = self.base # add base, also sets the type
655
+ linkframes = Tbase.__class__.Alloc(self.nlinks + 1)
656
+ linkframes[0] = Tbase
657
+
658
+ def recurse(Tall, Tparent, q, link):
659
+ # if joint??
660
+ T = Tparent
661
+ while True:
662
+ T *= link.A(q[link.jindex])
663
+ Tall[link.number + 1] = T
664
+
665
+ if link.nchildren == 1:
666
+ link = link.children[0]
667
+ continue
668
+
669
+ elif link.nchildren == 0:
670
+ return
671
+
672
+ else:
673
+ # multiple children
674
+ for child in link.children:
675
+ recurse(Tall, T, q, child)
676
+ return
677
+
678
+ recurse(linkframes, Tbase, q, self.links[0])
679
+
680
+
681
+ return linkframes
578
682
579
683
# --------------------------------------------------------------------- #
580
684
@@ -859,38 +963,7 @@ def _getlink(self, link, default=None):
859
963
else:
860
964
raise TypeError('unknown argument')
861
965
862
- def fkine_path(self, q, old=None):
863
- '''
864
- Tall = robot.fkine_all(q) evaluates fkine for each joint within a
865
- robot and returns a trajecotry of poses.
866
- Tall = fkine_all() as above except uses the stored q value of the
867
- robot object.
868
- :param q: The joint angles/configuration of the robot (Optional,
869
- if not supplied will use the stored q values).
870
- :type q: float ndarray(n)
871
- :param old: for compatibility with DHRobot version, ignored.
872
- :return T: Homogeneous transformation trajectory
873
- :rtype T: SE3 list
874
- .. note::
875
- - The robot's base transform, if present, are incorporated
876
- into the result.
877
- :references:
878
- - Kinematic Derivatives using the Elementary Transform
879
- Sequence, J. Haviland and P. Corke
880
- '''
881
- q = getvector(q)
882
- T = self.base
883
- linkframes = []
884
- j = 0
885
- for link in self.elinks:
886
- if link.isjoint:
887
- T *= link.A(q[j])
888
- j += 1
889
- else:
890
- T *= link.A()
891
- linkframes.append(T)
892
966
893
- return linkframes
894
967
# =========================================================================== #
895
968
896
969
@@ -2224,7 +2297,6 @@ def teach(
2224
2297
return env
2225
2298
2226
2299
2227
-
2228
2300
if __name__ == "__main__": # pragma nocover
2229
2301
2230
2302
# import roboticstoolbox as rtb
0 commit comments