@@ -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