14
14
# except ImportError: # pragma: no cover
15
15
# _symbolics = False
16
16
17
- import spatialmath .base as base
17
+ import spatialmath .base as smbase
18
18
from spatialmath .base .types import *
19
19
from spatialmath .baseposelist import BasePoseList
20
20
30
30
except ImportError :
31
31
# print('colored not found')
32
32
_colored = False
33
+ except AttributeError :
34
+ # print('colored failed to load, can happen from MATLAB import')
35
+ _colored = False
33
36
34
37
try :
35
38
from ansitable import ANSIMatrix
@@ -366,9 +369,9 @@ def log(self, twist: Optional[bool] = False) -> Union[NDArray, List[NDArray]]:
366
369
:SymPy: not supported
367
370
"""
368
371
if self .N == 2 :
369
- log = [base .trlog2 (x , twist = twist ) for x in self .data ]
372
+ log = [smbase .trlog2 (x , twist = twist ) for x in self .data ]
370
373
else :
371
- log = [base .trlog (x , twist = twist ) for x in self .data ]
374
+ log = [smbase .trlog (x , twist = twist ) for x in self .data ]
372
375
if len (log ) == 1 :
373
376
return log [0 ]
374
377
else :
@@ -415,7 +418,7 @@ def interp(self, end: Optional[bool] = None, s: Union[int, float] = None) -> Sel
415
418
if isinstance (s , int ) and s > 1 :
416
419
s = np .linspace (0 , 1 , s )
417
420
else :
418
- s = base .getvector (s )
421
+ s = smbase .getvector (s )
419
422
s = np .clip (s , 0 , 1 )
420
423
421
424
if len (self ) > 1 :
@@ -429,13 +432,13 @@ def interp(self, end: Optional[bool] = None, s: Union[int, float] = None) -> Sel
429
432
if self .N == 2 :
430
433
# SO(2) or SE(2)
431
434
return self .__class__ (
432
- [base .trinterp2 (start = self .A , end = end , s = _s ) for _s in s ]
435
+ [smbase .trinterp2 (start = self .A , end = end , s = _s ) for _s in s ]
433
436
)
434
437
435
438
elif self .N == 3 :
436
439
# SO(3) or SE(3)
437
440
return self .__class__ (
438
- [base .trinterp (start = self .A , end = end , s = _s ) for _s in s ]
441
+ [smbase .trinterp (start = self .A , end = end , s = _s ) for _s in s ]
439
442
)
440
443
441
444
def interp1 (self , s : float = None ) -> Self :
@@ -485,30 +488,32 @@ def interp1(self, s: float = None) -> Self:
485
488
486
489
#. For SO3 and SE3 rotation is interpolated using quaternion spherical linear interpolation (slerp).
487
490
488
- :seealso: :func:`interp`, :func:`~spatialmath.base.transforms3d.trinterp`, :func:`~spatialmath.base.quaternions.qslerp`, :func:`~spatialmath.base .transforms2d.trinterp2`
491
+ :seealso: :func:`interp`, :func:`~spatialmath.base.transforms3d.trinterp`, :func:`~spatialmath.base.quaternions.qslerp`, :func:`~spatialmath.smbase .transforms2d.trinterp2`
489
492
490
493
:SymPy: not supported
491
494
"""
492
- s = base .getvector (s )
495
+ s = smbase .getvector (s )
493
496
s = np .clip (s , 0 , 1 )
494
497
495
498
if self .N == 2 :
496
499
# SO(2) or SE(2)
497
500
if len (s ) > 1 :
498
501
assert len (self ) == 1 , "if len(s) > 1, len(X) must == 1"
499
- return self .__class__ ([base .trinterp2 (start , self .A , s = _s ) for _s in s ])
502
+ return self .__class__ (
503
+ [smbase .trinterp2 (start , self .A , s = _s ) for _s in s ]
504
+ )
500
505
else :
501
506
return self .__class__ (
502
- [base .trinterp2 (start , x , s = s [0 ]) for x in self .data ]
507
+ [smbase .trinterp2 (start , x , s = s [0 ]) for x in self .data ]
503
508
)
504
509
elif self .N == 3 :
505
510
# SO(3) or SE(3)
506
511
if len (s ) > 1 :
507
512
assert len (self ) == 1 , "if len(s) > 1, len(X) must == 1"
508
- return self .__class__ ([base .trinterp (None , self .A , s = _s ) for _s in s ])
513
+ return self .__class__ ([smbase .trinterp (None , self .A , s = _s ) for _s in s ])
509
514
else :
510
515
return self .__class__ (
511
- [base .trinterp (None , x , s = s [0 ]) for x in self .data ]
516
+ [smbase .trinterp (None , x , s = s [0 ]) for x in self .data ]
512
517
)
513
518
514
519
def norm (self ) -> Self :
@@ -541,9 +546,9 @@ def norm(self) -> Self:
541
546
:seealso: :func:`~spatialmath.base.transforms3d.trnorm`, :func:`~spatialmath.base.transforms2d.trnorm2`
542
547
"""
543
548
if self .N == 2 :
544
- return self .__class__ ([base .trnorm2 (x ) for x in self .data ])
549
+ return self .__class__ ([smbase .trnorm2 (x ) for x in self .data ])
545
550
else :
546
- return self .__class__ ([base .trnorm (x ) for x in self .data ])
551
+ return self .__class__ ([smbase .trnorm (x ) for x in self .data ])
547
552
548
553
def simplify (self ) -> Self :
549
554
"""
@@ -575,7 +580,7 @@ def simplify(self) -> Self:
575
580
:SymPy: supported
576
581
"""
577
582
578
- vf = np .vectorize (base .sym .simplify )
583
+ vf = np .vectorize (smbase .sym .simplify )
579
584
return self .__class__ ([vf (x ) for x in self .data ], check = False )
580
585
581
586
def stack (self ) -> NDArray :
@@ -677,10 +682,10 @@ def printline(self, *args, **kwargs) -> None:
677
682
"""
678
683
if self .N == 2 :
679
684
for x in self .data :
680
- base .trprint2 (x , * args , ** kwargs )
685
+ smbase .trprint2 (x , * args , ** kwargs )
681
686
else :
682
687
for x in self .data :
683
- base .trprint (x , * args , ** kwargs )
688
+ smbase .trprint (x , * args , ** kwargs )
684
689
685
690
def strline (self , * args , ** kwargs ) -> str :
686
691
"""
@@ -739,10 +744,10 @@ def strline(self, *args, **kwargs) -> str:
739
744
s = ""
740
745
if self .N == 2 :
741
746
for x in self .data :
742
- s += base .trprint2 (x , * args , file = False , ** kwargs )
747
+ s += smbase .trprint2 (x , * args , file = False , ** kwargs )
743
748
else :
744
749
for x in self .data :
745
- s += base .trprint (x , * args , file = False , ** kwargs )
750
+ s += smbase .trprint (x , * args , file = False , ** kwargs )
746
751
return s
747
752
748
753
def __repr__ (self ) -> str :
@@ -768,7 +773,7 @@ def trim(x):
768
773
if x .dtype == "O" :
769
774
return x
770
775
else :
771
- return base .removesmall (x )
776
+ return smbase .removesmall (x )
772
777
773
778
name = type (self ).__name__
774
779
if len (self ) == 0 :
@@ -896,7 +901,7 @@ def mformat(self, X):
896
901
rowstr = " "
897
902
# format the columns
898
903
for colnum , element in enumerate (row ):
899
- if base .sym .issymbol (element ):
904
+ if smbase .sym .issymbol (element ):
900
905
s = "{:<12s}" .format (str (element ))
901
906
else :
902
907
if (
@@ -966,9 +971,9 @@ def plot(self, *args, **kwargs) -> None:
966
971
:seealso: :func:`~spatialmath.base.transforms3d.trplot`, :func:`~spatialmath.base.transforms2d.trplot2`
967
972
"""
968
973
if self .N == 2 :
969
- base .trplot2 (self .A , * args , ** kwargs )
974
+ smbase .trplot2 (self .A , * args , ** kwargs )
970
975
else :
971
- base .trplot (self .A , * args , ** kwargs )
976
+ smbase .trplot (self .A , * args , ** kwargs )
972
977
973
978
def animate (self , * args , start = None , ** kwargs ) -> None :
974
979
"""
@@ -999,15 +1004,15 @@ def animate(self, *args, start=None, **kwargs) -> None:
999
1004
if len (self ) > 1 :
1000
1005
# trajectory case
1001
1006
if self .N == 2 :
1002
- base .tranimate2 (self .data , * args , ** kwargs )
1007
+ smbase .tranimate2 (self .data , * args , ** kwargs )
1003
1008
else :
1004
- base .tranimate (self .data , * args , ** kwargs )
1009
+ smbase .tranimate (self .data , * args , ** kwargs )
1005
1010
else :
1006
1011
# singleton case
1007
1012
if self .N == 2 :
1008
- base .tranimate2 (self .A , start = start , * args , ** kwargs )
1013
+ smbase .tranimate2 (self .A , start = start , * args , ** kwargs )
1009
1014
else :
1010
- base .tranimate (self .A , start = start , * args , ** kwargs )
1015
+ smbase .tranimate (self .A , start = start , * args , ** kwargs )
1011
1016
1012
1017
# ------------------------------------------------------------------------ #
1013
1018
def prod (self ) -> Self :
@@ -1152,13 +1157,13 @@ def __mul__(left, right): # pylint: disable=no-self-argument
1152
1157
elif isinstance (right , (list , tuple , np .ndarray )):
1153
1158
# print('*: pose x array')
1154
1159
if len (left ) == 1 :
1155
- if base .isvector (right , left .N ):
1160
+ if smbase .isvector (right , left .N ):
1156
1161
# pose x vector
1157
1162
# print('*: pose x vector')
1158
- v = base .getvector (right , out = "col" )
1163
+ v = smbase .getvector (right , out = "col" )
1159
1164
if left .isSE :
1160
1165
# SE(n) x vector
1161
- return base .h2e (left .A @ base .e2h (v ))
1166 + return smbase .h2e (left .A @ smbase .e2h (v ))
1162
1167
else :
1163
1168
# SO(n) x vector
1164
1169
return left .A @ v
@@ -1168,19 +1173,19 @@ def __mul__(left, right): # pylint: disable=no-self-argument
1168
1173
else :
1169
1174
if left .isSE :
1170
1175
# SE(n) x [set of vectors]
1171
- return base .h2e (left .A @ base .e2h (right ))
1176
+ return smbase .h2e (left .A @ smbase .e2h (right ))
1172
1177
else :
1173
1178
# SO(n) x [set of vectors]
1174
1179
return left .A @ right
1175
1180
1176
- elif len (left ) > 1 and base .isvector (right , left .N ):
1181
+ elif len (left ) > 1 and smbase .isvector (right , left .N ):
1177
1182
# pose array x vector
1178
1183
# print('*: pose array x vector')
1179
- v = base .getvector (right )
1184
+ v = smbase .getvector (right )
1180
1185
if left .isSE :
1181
1186
# SE(n) x vector
1182
- v = base .e2h (v )
1183
- return np .array ([base .h2e (x @ v ).flatten () for x in left .A ]).T
1187
+ v = smbase .e2h (v )
1188
+ return np .array ([smbase .h2e (x @ v ).flatten () for x in left .A ]).T
1184
1189
else :
1185
1190
# SO(n) x vector
1186
1191
return np .array ([(x @ v ).flatten () for x in left .A ]).T
@@ -1200,7 +1205,7 @@ def __mul__(left, right): # pylint: disable=no-self-argument
1200
1205
and right .shape [0 ] == left .N
1201
1206
):
1202
1207
# SE(n) x matrix
1203
- return base .h2e (left .A @ base .e2h (right ))
1208
+ return smbase .h2e (left .A @ smbase .e2h (right ))
1204
1209
elif (
1205
1210
isinstance (right , np .ndarray )
1206
1211
and left .isSO
@@ -1217,11 +1222,11 @@ def __mul__(left, right): # pylint: disable=no-self-argument
1217
1222
):
1218
1223
# SE(n) x matrix
1219
1224
return np .c_ [
1220
- [base .h2e (x .A @ base .e2h (y )) for x , y in zip (right , left .T )]
1225
+ [smbase .h2e (x .A @ smbase .e2h (y )) for x , y in zip (right , left .T )]
1221
1226
].T
1222
1227
else :
1223
1228
raise ValueError ("bad operands" )
1224
- elif base .isscalar (right ):
1229
+ elif smbase .isscalar (right ):
1225
1230
return left ._op2 (right , lambda x , y : x * y )
1226
1231
else :
1227
1232
return NotImplemented
@@ -1247,7 +1252,7 @@ def __matmul__(left, right): # pylint: disable=no-self-argument
1247
1252
if isinstance (left , right .__class__ ):
1248
1253
# print('*: pose x pose')
1249
1254
return left .__class__ (
1250
- left ._op2 (right , lambda x , y : base .trnorm (x @ y )), check = False
1255
+ left ._op2 (right , lambda x , y : smbase .trnorm (x @ y )), check = False
1251
1256
)
1252
1257
else :
1253
1258
raise TypeError ("@ only applies to pose composition" )
@@ -1341,7 +1346,7 @@ def __truediv__(left, right): # pylint: disable=no-self-argument
1341
1346
return left .__class__ (
1342
1347
left ._op2 (right .inv (), lambda x , y : x @ y ), check = False
1343
1348
)
1344
- elif base .isscalar (right ):
1349
+ elif smbase .isscalar (right ):
1345
1350
return left ._op2 (right , lambda x , y : x / y )
1346
1351
else :
1347
1352
raise ValueError ("bad operands" )
@@ -1632,7 +1637,7 @@ def _op2(left, right: Self, op: Callable): # pylint: disable=no-self-argument
1632
1637
return [op (x , y ) for (x , y ) in zip (left .A , right .A )]
1633
1638
else :
1634
1639
raise ValueError ("length of lists to == must be same length" )
1635
- elif base .isscalar (right ) or (
1640
+ elif smbase .isscalar (right ) or (
1636
1641
isinstance (right , np .ndarray ) and right .shape == left .shape
1637
1642
):
1638
1643
# class by matrix
0 commit comments