roboticstoolbox-python 1.4.0__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.
Files changed (610) hide show
  1. roboticstoolbox/__init__.py +107 -0
  2. roboticstoolbox/backends/Connector.py +113 -0
  3. roboticstoolbox/backends/Dynamixel/README.md +9 -0
  4. roboticstoolbox/backends/Dynamixel/dynamixel.json +581 -0
  5. roboticstoolbox/backends/Dynamixel/dynamixel_io.py +450 -0
  6. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/LICENSE +201 -0
  7. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/README.md +28 -0
  8. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/ReleaseNote.md +181 -0
  9. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/__init__.py +27 -0
  10. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_read.py +163 -0
  11. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_write.py +109 -0
  12. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_read.py +166 -0
  13. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_write.py +99 -0
  14. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/packet_handler.py +33 -0
  15. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/port_handler.py +155 -0
  16. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol1_packet_handler.py +548 -0
  17. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol2_packet_handler.py +1080 -0
  18. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/robotis_def.py +75 -0
  19. roboticstoolbox/backends/Dynamixel/dyndata.py +121 -0
  20. roboticstoolbox/backends/PyPlot/EllipsePlot.py +256 -0
  21. roboticstoolbox/backends/PyPlot/PyPlot.py +778 -0
  22. roboticstoolbox/backends/PyPlot/PyPlot2.py +537 -0
  23. roboticstoolbox/backends/PyPlot/README.md +67 -0
  24. roboticstoolbox/backends/PyPlot/RobotPlot.py +247 -0
  25. roboticstoolbox/backends/PyPlot/RobotPlot2.py +123 -0
  26. roboticstoolbox/backends/PyPlot/__init__.py +4 -0
  27. roboticstoolbox/backends/ROS/ROS.py +129 -0
  28. roboticstoolbox/backends/ROS/__init__.py +3 -0
  29. roboticstoolbox/backends/__init__.py +39 -0
  30. roboticstoolbox/backends/swift/__init__.py +165 -0
  31. roboticstoolbox/bin/__init__.py +0 -0
  32. roboticstoolbox/bin/_bintools.py +61 -0
  33. roboticstoolbox/bin/rtbtool.py +404 -0
  34. roboticstoolbox/blocks/Icons/250x250/armplot.png +0 -0
  35. roboticstoolbox/blocks/Icons/250x250/bicycle.png +0 -0
  36. roboticstoolbox/blocks/Icons/250x250/camera.png +0 -0
  37. roboticstoolbox/blocks/Icons/250x250/circlepath.png +0 -0
  38. roboticstoolbox/blocks/Icons/250x250/coriolis.png +0 -0
  39. roboticstoolbox/blocks/Icons/250x250/ctraj.png +0 -0
  40. roboticstoolbox/blocks/Icons/250x250/delta2tr.png +0 -0
  41. roboticstoolbox/blocks/Icons/250x250/diffsteer.png +0 -0
  42. roboticstoolbox/blocks/Icons/250x250/fdyn.png +0 -0
  43. roboticstoolbox/blocks/Icons/250x250/fdynx.png +0 -0
  44. roboticstoolbox/blocks/Icons/250x250/fkine.png +0 -0
  45. roboticstoolbox/blocks/Icons/250x250/gravload.png +0 -0
  46. roboticstoolbox/blocks/Icons/250x250/idyn.png +0 -0
  47. roboticstoolbox/blocks/Icons/250x250/idynx.png +0 -0
  48. roboticstoolbox/blocks/Icons/250x250/ikine.png +0 -0
  49. roboticstoolbox/blocks/Icons/250x250/inertia.png +0 -0
  50. roboticstoolbox/blocks/Icons/250x250/jacobian.png +0 -0
  51. roboticstoolbox/blocks/Icons/250x250/jtraj.png +0 -0
  52. roboticstoolbox/blocks/Icons/250x250/lspb.png +0 -0
  53. roboticstoolbox/blocks/Icons/250x250/multirotor.png +0 -0
  54. roboticstoolbox/blocks/Icons/250x250/multirotormixer.png +0 -0
  55. roboticstoolbox/blocks/Icons/250x250/multirotorplot.png +0 -0
  56. roboticstoolbox/blocks/Icons/250x250/point2tr.png +0 -0
  57. roboticstoolbox/blocks/Icons/250x250/tr2delta.png +0 -0
  58. roboticstoolbox/blocks/Icons/250x250/tr2t.png +0 -0
  59. roboticstoolbox/blocks/Icons/250x250/unicycle.png +0 -0
  60. roboticstoolbox/blocks/Icons/250x250/vehicleplot.png +0 -0
  61. roboticstoolbox/blocks/Icons/50x50/armplot.png +0 -0
  62. roboticstoolbox/blocks/Icons/50x50/bicycle.png +0 -0
  63. roboticstoolbox/blocks/Icons/50x50/camera.png +0 -0
  64. roboticstoolbox/blocks/Icons/50x50/circlepath.png +0 -0
  65. roboticstoolbox/blocks/Icons/50x50/coriolis.png +0 -0
  66. roboticstoolbox/blocks/Icons/50x50/delta2tr.png +0 -0
  67. roboticstoolbox/blocks/Icons/50x50/diffsteer.png +0 -0
  68. roboticstoolbox/blocks/Icons/50x50/fdyn.png +0 -0
  69. roboticstoolbox/blocks/Icons/50x50/fdynx.png +0 -0
  70. roboticstoolbox/blocks/Icons/50x50/fkine.png +0 -0
  71. roboticstoolbox/blocks/Icons/50x50/gravload.png +0 -0
  72. roboticstoolbox/blocks/Icons/50x50/idyn.png +0 -0
  73. roboticstoolbox/blocks/Icons/50x50/idynx.png +0 -0
  74. roboticstoolbox/blocks/Icons/50x50/ikine.png +0 -0
  75. roboticstoolbox/blocks/Icons/50x50/inertia.png +0 -0
  76. roboticstoolbox/blocks/Icons/50x50/jacobian.png +0 -0
  77. roboticstoolbox/blocks/Icons/50x50/jtraj.png +0 -0
  78. roboticstoolbox/blocks/Icons/50x50/lspb.png +0 -0
  79. roboticstoolbox/blocks/Icons/50x50/multirotor.png +0 -0
  80. roboticstoolbox/blocks/Icons/50x50/multirotormixer.png +0 -0
  81. roboticstoolbox/blocks/Icons/50x50/multirotorplot.png +0 -0
  82. roboticstoolbox/blocks/Icons/50x50/point2tr.png +0 -0
  83. roboticstoolbox/blocks/Icons/50x50/tr2delta.png +0 -0
  84. roboticstoolbox/blocks/Icons/50x50/tr2t.png +0 -0
  85. roboticstoolbox/blocks/Icons/50x50/unicycle.png +0 -0
  86. roboticstoolbox/blocks/Icons/50x50/vehicleplot.png +0 -0
  87. roboticstoolbox/blocks/Icons/armplot.png +0 -0
  88. roboticstoolbox/blocks/Icons/bicycle.png +0 -0
  89. roboticstoolbox/blocks/Icons/camera.png +0 -0
  90. roboticstoolbox/blocks/Icons/circlepath.png +0 -0
  91. roboticstoolbox/blocks/Icons/coriolis.png +0 -0
  92. roboticstoolbox/blocks/Icons/ctraj.png +0 -0
  93. roboticstoolbox/blocks/Icons/delta2tr.png +0 -0
  94. roboticstoolbox/blocks/Icons/diffsteer.png +0 -0
  95. roboticstoolbox/blocks/Icons/fdyn.png +0 -0
  96. roboticstoolbox/blocks/Icons/fdynx.png +0 -0
  97. roboticstoolbox/blocks/Icons/fkine.png +0 -0
  98. roboticstoolbox/blocks/Icons/gravload.png +0 -0
  99. roboticstoolbox/blocks/Icons/idyn.png +0 -0
  100. roboticstoolbox/blocks/Icons/idynx.png +0 -0
  101. roboticstoolbox/blocks/Icons/ikine.png +0 -0
  102. roboticstoolbox/blocks/Icons/inertia.png +0 -0
  103. roboticstoolbox/blocks/Icons/jacobian.png +0 -0
  104. roboticstoolbox/blocks/Icons/jtraj.png +0 -0
  105. roboticstoolbox/blocks/Icons/lspb.png +0 -0
  106. roboticstoolbox/blocks/Icons/multirotor.png +0 -0
  107. roboticstoolbox/blocks/Icons/multirotormixer.png +0 -0
  108. roboticstoolbox/blocks/Icons/multirotorplot.png +0 -0
  109. roboticstoolbox/blocks/Icons/point2tr.png +0 -0
  110. roboticstoolbox/blocks/Icons/tr2delta.png +0 -0
  111. roboticstoolbox/blocks/Icons/tr2t.png +0 -0
  112. roboticstoolbox/blocks/Icons/unicycle.png +0 -0
  113. roboticstoolbox/blocks/Icons/vehicleplot.png +0 -0
  114. roboticstoolbox/blocks/README.md +43 -0
  115. roboticstoolbox/blocks/__init__.py +6 -0
  116. roboticstoolbox/blocks/arm.py +1591 -0
  117. roboticstoolbox/blocks/mobile.py +522 -0
  118. roboticstoolbox/blocks/quad_model.py +132 -0
  119. roboticstoolbox/blocks/spatial.py +245 -0
  120. roboticstoolbox/blocks/uav.py +949 -0
  121. roboticstoolbox/demo/__init__.py +0 -0
  122. roboticstoolbox/demo/eigdemo.py +112 -0
  123. roboticstoolbox/demo/tripleangledemo.py +239 -0
  124. roboticstoolbox/demo/twistdemo.py +175 -0
  125. roboticstoolbox/ets/ET.py +439 -0
  126. roboticstoolbox/ets/ET2.py +179 -0
  127. roboticstoolbox/ets/ETS.py +2013 -0
  128. roboticstoolbox/ets/ETS2.py +449 -0
  129. roboticstoolbox/ets/_ET.py +668 -0
  130. roboticstoolbox/ets/_ETS.py +781 -0
  131. roboticstoolbox/ets/__init__.py +11 -0
  132. roboticstoolbox/ets/cpp-extensions/Eigen/Cholesky +45 -0
  133. roboticstoolbox/ets/cpp-extensions/Eigen/CholmodSupport +48 -0
  134. roboticstoolbox/ets/cpp-extensions/Eigen/Core +384 -0
  135. roboticstoolbox/ets/cpp-extensions/Eigen/Dense +7 -0
  136. roboticstoolbox/ets/cpp-extensions/Eigen/Eigen +2 -0
  137. roboticstoolbox/ets/cpp-extensions/Eigen/Eigenvalues +60 -0
  138. roboticstoolbox/ets/cpp-extensions/Eigen/Geometry +59 -0
  139. roboticstoolbox/ets/cpp-extensions/Eigen/Householder +29 -0
  140. roboticstoolbox/ets/cpp-extensions/Eigen/IterativeLinearSolvers +48 -0
  141. roboticstoolbox/ets/cpp-extensions/Eigen/Jacobi +32 -0
  142. roboticstoolbox/ets/cpp-extensions/Eigen/KLUSupport +41 -0
  143. roboticstoolbox/ets/cpp-extensions/Eigen/LU +47 -0
  144. roboticstoolbox/ets/cpp-extensions/Eigen/MetisSupport +35 -0
  145. roboticstoolbox/ets/cpp-extensions/Eigen/OrderingMethods +70 -0
  146. roboticstoolbox/ets/cpp-extensions/Eigen/PaStiXSupport +49 -0
  147. roboticstoolbox/ets/cpp-extensions/Eigen/PardisoSupport +35 -0
  148. roboticstoolbox/ets/cpp-extensions/Eigen/QR +50 -0
  149. roboticstoolbox/ets/cpp-extensions/Eigen/QtAlignedMalloc +39 -0
  150. roboticstoolbox/ets/cpp-extensions/Eigen/SPQRSupport +34 -0
  151. roboticstoolbox/ets/cpp-extensions/Eigen/SVD +50 -0
  152. roboticstoolbox/ets/cpp-extensions/Eigen/Sparse +34 -0
  153. roboticstoolbox/ets/cpp-extensions/Eigen/SparseCholesky +37 -0
  154. roboticstoolbox/ets/cpp-extensions/Eigen/SparseCore +69 -0
  155. roboticstoolbox/ets/cpp-extensions/Eigen/SparseLU +50 -0
  156. roboticstoolbox/ets/cpp-extensions/Eigen/SparseQR +36 -0
  157. roboticstoolbox/ets/cpp-extensions/Eigen/StdDeque +27 -0
  158. roboticstoolbox/ets/cpp-extensions/Eigen/StdList +26 -0
  159. roboticstoolbox/ets/cpp-extensions/Eigen/StdVector +27 -0
  160. roboticstoolbox/ets/cpp-extensions/Eigen/SuperLUSupport +64 -0
  161. roboticstoolbox/ets/cpp-extensions/Eigen/UmfPackSupport +40 -0
  162. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LDLT.h +688 -0
  163. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LLT.h +558 -0
  164. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  165. roboticstoolbox/ets/cpp-extensions/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  166. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArithmeticSequence.h +413 -0
  167. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Array.h +417 -0
  168. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArrayBase.h +226 -0
  169. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArrayWrapper.h +209 -0
  170. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Assign.h +90 -0
  171. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/AssignEvaluator.h +1010 -0
  172. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Assign_MKL.h +178 -0
  173. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/BandMatrix.h +353 -0
  174. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Block.h +448 -0
  175. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/BooleanRedux.h +162 -0
  176. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CommaInitializer.h +164 -0
  177. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ConditionEstimator.h +175 -0
  178. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CoreEvaluators.h +1741 -0
  179. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CoreIterators.h +132 -0
  180. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  181. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  182. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  183. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  184. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseUnaryView.h +132 -0
  185. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseBase.h +701 -0
  186. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  187. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseStorage.h +652 -0
  188. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Diagonal.h +258 -0
  189. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DiagonalMatrix.h +391 -0
  190. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DiagonalProduct.h +28 -0
  191. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Dot.h +318 -0
  192. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/EigenBase.h +160 -0
  193. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  194. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Fuzzy.h +155 -0
  195. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GeneralProduct.h +465 -0
  196. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GenericPacketMath.h +1040 -0
  197. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GlobalFunctions.h +194 -0
  198. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/IO.h +258 -0
  199. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/IndexedView.h +237 -0
  200. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Inverse.h +117 -0
  201. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Map.h +171 -0
  202. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MapBase.h +310 -0
  203. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MathFunctions.h +2057 -0
  204. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  205. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Matrix.h +565 -0
  206. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MatrixBase.h +547 -0
  207. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NestByValue.h +85 -0
  208. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NoAlias.h +109 -0
  209. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NumTraits.h +335 -0
  210. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  211. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PermutationMatrix.h +605 -0
  212. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PlainObjectBase.h +1128 -0
  213. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Product.h +191 -0
  214. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ProductEvaluators.h +1179 -0
  215. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Random.h +218 -0
  216. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Redux.h +515 -0
  217. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Ref.h +381 -0
  218. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Replicate.h +142 -0
  219. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Reshaped.h +454 -0
  220. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ReturnByValue.h +119 -0
  221. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Reverse.h +217 -0
  222. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Select.h +164 -0
  223. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SelfAdjointView.h +365 -0
  224. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  225. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Solve.h +188 -0
  226. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SolveTriangular.h +235 -0
  227. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SolverBase.h +168 -0
  228. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/StableNorm.h +251 -0
  229. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/StlIterators.h +463 -0
  230. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Stride.h +116 -0
  231. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Swap.h +68 -0
  232. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Transpose.h +464 -0
  233. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Transpositions.h +386 -0
  234. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/TriangularMatrix.h +1001 -0
  235. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/VectorBlock.h +96 -0
  236. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/VectorwiseOp.h +784 -0
  237. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Visitor.h +381 -0
  238. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  239. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  240. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  241. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  242. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  243. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  244. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  245. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  246. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  247. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  248. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  249. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  250. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  251. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  252. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  253. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  254. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  255. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  256. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  257. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/Half.h +942 -0
  258. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/Settings.h +49 -0
  259. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  260. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  261. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  262. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  263. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  264. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  265. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  266. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  267. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  268. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  269. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  270. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  271. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  272. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  273. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  274. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  275. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  276. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  277. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  278. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  279. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  280. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  281. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  282. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  283. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  284. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  285. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  286. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  287. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  288. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  289. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  290. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/StlFunctors.h +166 -0
  291. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  292. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  293. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  294. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  295. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  296. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  297. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  298. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  299. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  300. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/Parallelizer.h +180 -0
  301. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  302. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  303. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  304. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  305. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  306. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  307. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  308. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  309. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  310. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  311. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  312. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  313. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  314. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/BlasUtil.h +583 -0
  315. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  316. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Constants.h +563 -0
  317. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  318. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  319. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  320. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/IntegralConstant.h +272 -0
  321. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/MKL_support.h +137 -0
  322. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Macros.h +1464 -0
  323. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Memory.h +1163 -0
  324. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Meta.h +812 -0
  325. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/NonMPL2.h +3 -0
  326. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  327. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  328. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/StaticAssert.h +221 -0
  329. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  330. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/XprHelper.h +856 -0
  331. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  332. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  333. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  334. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  335. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  336. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  337. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  338. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  339. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  340. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  341. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  342. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  343. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  344. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  345. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/AlignedBox.h +486 -0
  346. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/AngleAxis.h +247 -0
  347. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/EulerAngles.h +114 -0
  348. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Homogeneous.h +501 -0
  349. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Hyperplane.h +282 -0
  350. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/OrthoMethods.h +235 -0
  351. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  352. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Quaternion.h +870 -0
  353. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Rotation2D.h +199 -0
  354. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/RotationBase.h +206 -0
  355. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Scaling.h +188 -0
  356. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Transform.h +1563 -0
  357. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Translation.h +202 -0
  358. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Umeyama.h +166 -0
  359. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  360. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/BlockHouseholder.h +110 -0
  361. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/Householder.h +176 -0
  362. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/HouseholderSequence.h +545 -0
  363. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  364. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  365. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  366. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  367. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  368. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  369. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  370. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  371. roboticstoolbox/ets/cpp-extensions/Eigen/src/Jacobi/Jacobi.h +483 -0
  372. roboticstoolbox/ets/cpp-extensions/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  373. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/Determinant.h +117 -0
  374. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/FullPivLU.h +877 -0
  375. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/InverseImpl.h +432 -0
  376. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/PartialPivLU.h +624 -0
  377. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  378. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/arch/InverseSize4.h +351 -0
  379. roboticstoolbox/ets/cpp-extensions/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  380. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Amd.h +435 -0
  381. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  382. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Ordering.h +153 -0
  383. roboticstoolbox/ets/cpp-extensions/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  384. roboticstoolbox/ets/cpp-extensions/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  385. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  386. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  387. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  388. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  389. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/HouseholderQR.h +434 -0
  390. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  391. roboticstoolbox/ets/cpp-extensions/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  392. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/BDCSVD.h +1366 -0
  393. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/JacobiSVD.h +812 -0
  394. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  395. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/SVDBase.h +376 -0
  396. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  397. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  398. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  399. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/AmbiVector.h +378 -0
  400. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  401. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  402. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  403. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseAssign.h +270 -0
  404. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseBlock.h +571 -0
  405. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  406. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  407. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  408. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  409. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  410. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  411. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDot.h +98 -0
  412. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  413. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMap.h +305 -0
  414. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  415. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  416. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  417. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseProduct.h +181 -0
  418. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseRedux.h +49 -0
  419. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseRef.h +397 -0
  420. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  421. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  422. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  423. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  424. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  425. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseUtil.h +186 -0
  426. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseVector.h +478 -0
  427. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseView.h +254 -0
  428. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  429. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU.h +923 -0
  430. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  431. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  432. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  433. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  434. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  435. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  436. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  437. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  438. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  439. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  440. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  441. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  442. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  443. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  444. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  445. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  446. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseQR/SparseQR.h +758 -0
  447. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdDeque.h +116 -0
  448. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdList.h +106 -0
  449. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdVector.h +131 -0
  450. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/details.h +84 -0
  451. roboticstoolbox/ets/cpp-extensions/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  452. roboticstoolbox/ets/cpp-extensions/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  453. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/Image.h +82 -0
  454. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/Kernel.h +79 -0
  455. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/RealSvd2x2.h +55 -0
  456. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/blas.h +440 -0
  457. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapack.h +152 -0
  458. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapacke.h +16292 -0
  459. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapacke_mangling.h +17 -0
  460. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  461. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  462. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/BlockMethods.h +1442 -0
  463. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  464. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  465. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  466. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  467. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  468. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ReshapedMethods.h +149 -0
  469. roboticstoolbox/ets/cpp-extensions/README.md +73 -0
  470. roboticstoolbox/ets/cpp-extensions/fknm_nb.cpp +534 -0
  471. roboticstoolbox/ets/cpp-extensions/ik.cpp +301 -0
  472. roboticstoolbox/ets/cpp-extensions/ik.h +59 -0
  473. roboticstoolbox/ets/cpp-extensions/linalg.cpp +316 -0
  474. roboticstoolbox/ets/cpp-extensions/linalg.h +64 -0
  475. roboticstoolbox/ets/cpp-extensions/methods.cpp +372 -0
  476. roboticstoolbox/ets/cpp-extensions/methods.h +32 -0
  477. roboticstoolbox/ets/cpp-extensions/structs.cpp +24 -0
  478. roboticstoolbox/ets/cpp-extensions/structs.h +62 -0
  479. roboticstoolbox/ets/fknm.py +366 -0
  480. roboticstoolbox/mobile/Animations.py +485 -0
  481. roboticstoolbox/mobile/Bug2.py +455 -0
  482. roboticstoolbox/mobile/CurvaturePolyPlanner.py +179 -0
  483. roboticstoolbox/mobile/DistanceTransformPlanner.py +395 -0
  484. roboticstoolbox/mobile/DstarPlanner.py +591 -0
  485. roboticstoolbox/mobile/DubinsPlanner.py +474 -0
  486. roboticstoolbox/mobile/EKF.py +1617 -0
  487. roboticstoolbox/mobile/LatticePlanner.py +419 -0
  488. roboticstoolbox/mobile/OccGrid.py +613 -0
  489. roboticstoolbox/mobile/PRMPlanner.py +348 -0
  490. roboticstoolbox/mobile/ParticleFilter.py +706 -0
  491. roboticstoolbox/mobile/PlannerBase.py +1009 -0
  492. roboticstoolbox/mobile/PoseGraph.py +544 -0
  493. roboticstoolbox/mobile/QuinticPolyPlanner.py +349 -0
  494. roboticstoolbox/mobile/RRTPlanner.py +359 -0
  495. roboticstoolbox/mobile/ReedsSheppPlanner.py +545 -0
  496. roboticstoolbox/mobile/Vehicle.py +1909 -0
  497. roboticstoolbox/mobile/__init__.py +194 -0
  498. roboticstoolbox/mobile/drivers.py +397 -0
  499. roboticstoolbox/mobile/landmarkmap.py +181 -0
  500. roboticstoolbox/mobile/sensors.py +789 -0
  501. roboticstoolbox/models/DH/AL5D.py +121 -0
  502. roboticstoolbox/models/DH/Ball.py +87 -0
  503. roboticstoolbox/models/DH/Baxter.py +91 -0
  504. roboticstoolbox/models/DH/Cobra600.py +63 -0
  505. roboticstoolbox/models/DH/Coil.py +80 -0
  506. roboticstoolbox/models/DH/Hyper.py +81 -0
  507. roboticstoolbox/models/DH/Hyper3d.py +83 -0
  508. roboticstoolbox/models/DH/IRB140.py +159 -0
  509. roboticstoolbox/models/DH/Jaco.py +102 -0
  510. roboticstoolbox/models/DH/KR5.py +112 -0
  511. roboticstoolbox/models/DH/LWR4.py +80 -0
  512. roboticstoolbox/models/DH/Mico.py +102 -0
  513. roboticstoolbox/models/DH/Orion5.py +91 -0
  514. roboticstoolbox/models/DH/P8.py +80 -0
  515. roboticstoolbox/models/DH/Panda.py +213 -0
  516. roboticstoolbox/models/DH/Planar2.py +69 -0
  517. roboticstoolbox/models/DH/Planar3.py +51 -0
  518. roboticstoolbox/models/DH/Puma560.py +326 -0
  519. roboticstoolbox/models/DH/README.md +216 -0
  520. roboticstoolbox/models/DH/Sawyer.py +85 -0
  521. roboticstoolbox/models/DH/Stanford.py +147 -0
  522. roboticstoolbox/models/DH/TwoLink.py +153 -0
  523. roboticstoolbox/models/DH/UR10.py +124 -0
  524. roboticstoolbox/models/DH/UR3.py +98 -0
  525. roboticstoolbox/models/DH/UR5.py +98 -0
  526. roboticstoolbox/models/DH/Uprighttl.py +24 -0
  527. roboticstoolbox/models/DH/__init__.py +52 -0
  528. roboticstoolbox/models/ETS/Frankie.py +90 -0
  529. roboticstoolbox/models/ETS/GenericSeven.py +54 -0
  530. roboticstoolbox/models/ETS/Omni.py +74 -0
  531. roboticstoolbox/models/ETS/Panda.py +69 -0
  532. roboticstoolbox/models/ETS/Planar2.py +49 -0
  533. roboticstoolbox/models/ETS/Planar_Y.py +65 -0
  534. roboticstoolbox/models/ETS/Puma560.py +70 -0
  535. roboticstoolbox/models/ETS/XYPanda.py +84 -0
  536. roboticstoolbox/models/ETS/__init__.py +20 -0
  537. roboticstoolbox/models/README.md +9 -0
  538. roboticstoolbox/models/URDF/AL5D.py +45 -0
  539. roboticstoolbox/models/URDF/Fetch.py +96 -0
  540. roboticstoolbox/models/URDF/Frankie.py +67 -0
  541. roboticstoolbox/models/URDF/FrankieOmni.py +94 -0
  542. roboticstoolbox/models/URDF/Jaco.py +49 -0
  543. roboticstoolbox/models/URDF/KinovaGen3.py +63 -0
  544. roboticstoolbox/models/URDF/LBR.py +57 -0
  545. roboticstoolbox/models/URDF/PR2.py +66 -0
  546. roboticstoolbox/models/URDF/Panda.py +60 -0
  547. roboticstoolbox/models/URDF/Puma560.py +90 -0
  548. roboticstoolbox/models/URDF/UR10.py +43 -0
  549. roboticstoolbox/models/URDF/UR3.py +43 -0
  550. roboticstoolbox/models/URDF/UR5.py +64 -0
  551. roboticstoolbox/models/URDF/URDFRobot.py +402 -0
  552. roboticstoolbox/models/URDF/Valkyrie.py +110 -0
  553. roboticstoolbox/models/URDF/YuMi.py +107 -0
  554. roboticstoolbox/models/URDF/__init__.py +51 -0
  555. roboticstoolbox/models/URDF/px100.py +48 -0
  556. roboticstoolbox/models/URDF/px150.py +48 -0
  557. roboticstoolbox/models/URDF/rx150.py +48 -0
  558. roboticstoolbox/models/URDF/rx200.py +48 -0
  559. roboticstoolbox/models/URDF/vx300.py +48 -0
  560. roboticstoolbox/models/URDF/vx300s.py +48 -0
  561. roboticstoolbox/models/URDF/wx200.py +48 -0
  562. roboticstoolbox/models/URDF/wx250.py +48 -0
  563. roboticstoolbox/models/URDF/wx250s.py +48 -0
  564. roboticstoolbox/models/__init__.py +7 -0
  565. roboticstoolbox/models/catalog.py +226 -0
  566. roboticstoolbox/robot/BaseRobot.py +2589 -0
  567. roboticstoolbox/robot/DHFactor.py +522 -0
  568. roboticstoolbox/robot/DHLink.py +949 -0
  569. roboticstoolbox/robot/DHRobot.py +2591 -0
  570. roboticstoolbox/robot/Dynamics.py +1537 -0
  571. roboticstoolbox/robot/ELink.py +23 -0
  572. roboticstoolbox/robot/ERobot.py +25 -0
  573. roboticstoolbox/robot/Gripper.py +242 -0
  574. roboticstoolbox/robot/IK.py +1378 -0
  575. roboticstoolbox/robot/Link.py +1557 -0
  576. roboticstoolbox/robot/PoERobot.py +352 -0
  577. roboticstoolbox/robot/Robot.py +2157 -0
  578. roboticstoolbox/robot/RobotKinematics.py +1505 -0
  579. roboticstoolbox/robot/RobotPlottingMPL.py +355 -0
  580. roboticstoolbox/robot/RobotProto.py +156 -0
  581. roboticstoolbox/robot/__init__.py +57 -0
  582. roboticstoolbox/robot/cpp-extensions/README.md +29 -0
  583. roboticstoolbox/robot/cpp-extensions/frne.h +96 -0
  584. roboticstoolbox/robot/cpp-extensions/frne_nb.cpp +237 -0
  585. roboticstoolbox/robot/cpp-extensions/ne.c +495 -0
  586. roboticstoolbox/robot/cpp-extensions/vmath.c +163 -0
  587. roboticstoolbox/robot/cpp-extensions/vmath.h +32 -0
  588. roboticstoolbox/robot/frne.py +51 -0
  589. roboticstoolbox/tools/DHFactor.py +375 -0
  590. roboticstoolbox/tools/Ticker.py +53 -0
  591. roboticstoolbox/tools/__init__.py +54 -0
  592. roboticstoolbox/tools/data.py +187 -0
  593. roboticstoolbox/tools/jsingu.py +51 -0
  594. roboticstoolbox/tools/null.py +48 -0
  595. roboticstoolbox/tools/numerical.py +96 -0
  596. roboticstoolbox/tools/p_servo.py +108 -0
  597. roboticstoolbox/tools/params.py +11 -0
  598. roboticstoolbox/tools/plot.py +109 -0
  599. roboticstoolbox/tools/trajectory.py +1152 -0
  600. roboticstoolbox/tools/types.py +13 -0
  601. roboticstoolbox/tools/urdf/__init__.py +45 -0
  602. roboticstoolbox/tools/urdf/tests/data/ur5.urdf +341 -0
  603. roboticstoolbox/tools/urdf/tests/test_urdf.py +116 -0
  604. roboticstoolbox/tools/urdf/urdf.py +1930 -0
  605. roboticstoolbox/tools/urdf/utils.py +50 -0
  606. roboticstoolbox_python-1.4.0.dist-info/METADATA +664 -0
  607. roboticstoolbox_python-1.4.0.dist-info/RECORD +610 -0
  608. roboticstoolbox_python-1.4.0.dist-info/WHEEL +5 -0
  609. roboticstoolbox_python-1.4.0.dist-info/entry_points.txt +6 -0
  610. roboticstoolbox_python-1.4.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,2013 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ @author: Jesse Haviland
5
+ @author: Peter Corke
6
+ """
7
+
8
+ from __future__ import annotations
9
+ from functools import cached_property
10
+ import numpy as np
11
+ from numpy.random import uniform
12
+ from numpy.linalg import inv, det, cond, svd
13
+ from spatialmath import SE3, SE2
14
+ from spatialmath.base import (
15
+ getvector,
16
+ issymbol,
17
+ tr2jac,
18
+ verifymatrix,
19
+ tr2jac2,
20
+ t2r,
21
+ rotvelxform,
22
+ simplify,
23
+ getmatrix,
24
+ )
25
+ from roboticstoolbox.tools.params import rtb_get_param
26
+ from roboticstoolbox.robot.IK import IK_GN, IK_LM, IK_NR, IK_QP
27
+
28
+ from roboticstoolbox.ets.fknm import (
29
+ ETS_init,
30
+ ETS_fkine,
31
+ ETS_jacob0,
32
+ ETS_jacobe,
33
+ ETS_hessian0,
34
+ ETS_hessiane,
35
+ IK_NR_c,
36
+ IK_GN_c,
37
+ IK_LM_c,
38
+ )
39
+ from copy import deepcopy
40
+ from roboticstoolbox.ets.ET import ET
41
+ from roboticstoolbox.ets._ET import BaseET
42
+ from roboticstoolbox.ets._ETS import BaseETS, T, _dirties_fknm
43
+ from typing import overload, TypeVar
44
+ from typing import Literal as L
45
+ from roboticstoolbox.tools.types import ArrayLike, NDArray
46
+
47
+
48
+ class ETS(BaseETS):
49
+ """
50
+ This class implements an elementary transform sequence (ETS) for 3D
51
+
52
+ An instance can contain an elementary transform (ET) or an elementary
53
+ transform sequence (ETS). It has list-like properties by subclassing
54
+ UserList, which means we can perform indexing, slicing pop, insert, as well
55
+ as using it as an iterator over its values.
56
+
57
+ - ``ETS()`` an empty ETS list
58
+ - ``ETS(et)`` an ETS containing a single ET
59
+ - ``ETS([et0, et1, et2])`` an ETS consisting of three ET's
60
+
61
+ :param arg: list of ETs or a single ET to initialise the ETS
62
+
63
+ Examples
64
+ --------
65
+
66
+ .. runblock:: pycon
67
+
68
+ >>> from roboticstoolbox import ETS, ET
69
+ >>> e = ET.Rz(0.3) # a single ET, rotation about z
70
+ >>> ets1 = ETS(e)
71
+ >>> len(ets1)
72
+ >>> ets2 = ET.Rz(0.3) * ET.tx(2) # an ETS
73
+ >>> len(ets2) # of length 2
74
+ >>> ets2[1] # an ET sliced from the ETS
75
+
76
+ .. rubric:: References
77
+
78
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
79
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
80
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
81
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
82
+
83
+
84
+ See Also
85
+ --------
86
+ :func:`rx`
87
+ :func:`ry`
88
+ :func:`rz`
89
+ :func:`tx`
90
+ :func:`ty`
91
+ :func:`tz`
92
+
93
+ """
94
+
95
+ def __init__(
96
+ self,
97
+ arg: list[ETS | ET] | list[ET] | list[ETS] | ET | ETS | None = None,
98
+ ):
99
+ super().__init__()
100
+ if isinstance(arg, list):
101
+ for item in arg:
102
+ if isinstance(item, ET):
103
+ self._data.append(deepcopy(item))
104
+ elif isinstance(item, ETS):
105
+ for ets_item in item:
106
+ self._data.append(deepcopy(ets_item))
107
+ else:
108
+ raise TypeError("Invalid arg")
109
+ elif isinstance(arg, ET):
110
+ self._data.append(deepcopy(arg))
111
+ elif isinstance(arg, ETS):
112
+ for ets_item in arg:
113
+ self._data.append(deepcopy(ets_item))
114
+ elif arg is not None:
115
+ raise TypeError("Invalid arg")
116
+
117
+ self._auto_jindex = False
118
+
119
+ # Check if jindices are set
120
+ joints = self.joints()
121
+
122
+ # Number of joints with a jindex
123
+ jindices = 0
124
+
125
+ # Number of joints with a sequential jindex (j[2] -> jindex = 2)
126
+ seq_jindex = 0
127
+
128
+ # Count them up
129
+ for j, joint in enumerate(joints):
130
+ if joint.jindex is not None:
131
+ jindices += 1
132
+ if joint.jindex == j:
133
+ seq_jindex += 1
134
+
135
+ if (
136
+ jindices == self.n - 1
137
+ and seq_jindex == self.n - 1
138
+ and joints[-1].jindex is None
139
+ ):
140
+ # ets has sequential jindicies, except for the last.
141
+ joints[-1].jindex = self.n - 1
142
+ self._auto_jindex = True
143
+
144
+ elif jindices > 0 and not jindices == self.n:
145
+ raise ValueError(
146
+ "You can not have some jindices set for the ET's in arg. It must be all"
147
+ " or none"
148
+ ) # pragma: nocover
149
+ elif jindices == 0 and self.n > 0:
150
+ # Set them ourself
151
+ for j, joint in enumerate(joints):
152
+ joint.jindex = j
153
+
154
+ self._auto_jindex = True
155
+
156
+ def __mul__(self, other: ET | ETS) -> "ETS":
157
+ if isinstance(other, ET):
158
+ return ETS([*self._data, other])
159
+ else:
160
+ return ETS([*self._data, *other._data]) # pragma: nocover
161
+
162
+ def __rmul__(self, other: ET | ETS) -> "ETS":
163
+ return ETS([other, *self._data]) # pragma: nocover
164
+
165
+ def __imul__(self, rest: "ETS"):
166
+ return self + rest # pragma: nocover
167
+
168
+ def __add__(self, rest) -> "ETS":
169
+ return self.__mul__(rest) # pragma: nocover
170
+
171
+ def compile(self) -> "ETS":
172
+ """
173
+ Compile an ETS
174
+
175
+ :returns: optimised ETS
176
+ :rtype: ETS
177
+
178
+ Perform constant folding for faster evaluation. Consecutive constant
179
+ ETs are compounded, leading to a constant ET which is denoted by
180
+ ``SE3`` when displayed.
181
+
182
+ Examples
183
+ --------
184
+
185
+ .. runblock:: pycon
186
+
187
+ >>> import roboticstoolbox as rtb
188
+ >>> robot = rtb.models.ETS.Panda()
189
+ >>> ets = robot.ets()
190
+ >>> ets
191
+ >>> ets.compile()
192
+
193
+ See Also
194
+ --------
195
+ :func:`isconstant`
196
+ """
197
+ const = None
198
+ ets = ETS()
199
+
200
+ for et in self:
201
+ if et.isjoint:
202
+ # a joint
203
+ if const is not None:
204
+ # flush the constant
205
+ if not np.array_equal(const, np.eye(4)):
206
+ ets *= ET.SE3(const)
207
+ const = None
208
+ ets *= et # emit the joint ET
209
+ else:
210
+ # not a joint
211
+ if const is None:
212
+ const = et.A()
213
+ else:
214
+ const = const @ et.A()
215
+
216
+ if const is not None:
217
+ # flush the constant, tool transform
218
+ if not np.array_equal(const, np.eye(4)):
219
+ ets *= ET.SE3(const)
220
+ return ets
221
+
222
+ def insert( # type: ignore[override]
223
+ self,
224
+ index: int,
225
+ value: ET | ETS,
226
+ ) -> None:
227
+ """
228
+ Insert value
229
+
230
+ :param index: position to insert at
231
+ :param value: the elementary transform or sequence to insert
232
+
233
+ Inserts an ET or ETS into the ET sequence. The inserted ET is at position
234
+ ``index``; an ETS is expanded and inserted element by element.
235
+
236
+ Examples
237
+ --------
238
+
239
+ .. runblock:: pycon
240
+
241
+ >>> from roboticstoolbox import ET
242
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
243
+ >>> f = ET.Ry()
244
+ >>> e.insert(2, f)
245
+ >>> e
246
+
247
+ """
248
+
249
+ if isinstance(value, ET):
250
+ self._data.insert(index, value)
251
+ elif isinstance(value, ETS):
252
+ for j, et in enumerate(value):
253
+ self._data.insert(index + j, et)
254
+ self._fknm_stale = True
255
+
256
+ def fkine(
257
+ self,
258
+ q: ArrayLike,
259
+ base: NDArray | SE3 | None = None,
260
+ tool: NDArray | SE3 | None = None,
261
+ include_base: bool = True,
262
+ ) -> SE3:
263
+ """
264
+ Forward kinematics
265
+
266
+ :param q: Joint coordinates
267
+ :param base: a base transform applied before the ETS
268
+ :param tool: tool transform, optional
269
+ :param include_base: set to True if the base transform should be considered
270
+ :returns: the transformation matrix representing the pose of the end-effector
271
+ :rtype: SE3
272
+
273
+ ``T = ets.fkine(q)`` evaluates forward kinematics for the ets at
274
+ joint configuration ``q``.
275
+
276
+ **Trajectory operation**:
277
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
278
+ result is an ``SE3`` instance with ``m`` values.
279
+
280
+ Examples
281
+ --------
282
+
283
+ The following example makes a ``panda`` robot object, gets the ets, and
284
+ solves for the forward kinematics at the listed configuration.
285
+
286
+ .. runblock:: pycon
287
+ >>> import roboticstoolbox as rtb
288
+ >>> panda = rtb.models.Panda().ets()
289
+ >>> panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
290
+
291
+ .. rubric:: Notes
292
+
293
+ - A tool transform, if provided, is incorporated into the result.
294
+ - Works from the end-effector link to the base
295
+
296
+ .. rubric:: References
297
+
298
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
299
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
300
+
301
+ """
302
+
303
+ ret = SE3.Empty()
304
+ fk = self.eval(q, base, tool, include_base)
305
+
306
+ if fk.dtype == "O":
307
+ # symbolic
308
+ fk = np.array(simplify(fk))
309
+
310
+ if fk.ndim == 3:
311
+ for T in fk:
312
+ ret.append(SE3(T, check=False)) # type: ignore
313
+ else:
314
+ ret = SE3(fk, check=False)
315
+
316
+ return ret
317
+
318
+ def eval(
319
+ self,
320
+ q: ArrayLike,
321
+ base: NDArray | SE3 | None = None,
322
+ tool: NDArray | SE3 | None = None,
323
+ include_base: bool = True,
324
+ ) -> NDArray:
325
+ """
326
+ Forward kinematics (returns raw ndarray)
327
+
328
+ :param q: Joint coordinates
329
+ :param base: a base transform applied before the ETS
330
+ :param tool: tool transform, optional
331
+ :param include_base: set to True if the base transform should be considered
332
+ :returns: the transformation matrix representing the pose of the end-effector
333
+ :rtype: ndarray(4,4) or ndarray(m,4,4)
334
+
335
+ ``T = ets.eval(q)`` evaluates forward kinematics for the ets at
336
+ joint configuration ``q``.
337
+
338
+ **Trajectory operation**:
339
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
340
+ result is a 3d array with ``m`` planes.
341
+
342
+ Examples
343
+ --------
344
+
345
+ .. runblock:: pycon
346
+
347
+ >>> import roboticstoolbox as rtb
348
+ >>> panda = rtb.models.Panda().ets()
349
+ >>> panda.eval([0, -0.3, 0, -2.2, 0, 2, 0.7854])
350
+
351
+ .. rubric:: Notes
352
+
353
+ - A tool transform, if provided, is incorporated into the result.
354
+ - Works from the end-effector link to the base
355
+
356
+ .. rubric:: References
357
+
358
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
359
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
360
+
361
+ """
362
+
363
+ return ETS_fkine(self._fknm, q, base, tool, include_base, _data=self.data)
364
+
365
+ def jacob0(
366
+ self,
367
+ q: ArrayLike,
368
+ tool: NDArray | SE3 | None = None,
369
+ ) -> NDArray:
370
+ r"""
371
+ Manipulator geometric Jacobian in the base frame
372
+
373
+ :param q: Joint coordinate vector
374
+ :param tool: a static tool transformation matrix to apply to the end of ETS
375
+ :returns: Manipulator Jacobian in the base frame
376
+ :rtype: ndarray(6,n)
377
+
378
+ ``robot.jacob0(q)`` is the manipulator Jacobian matrix which maps
379
+ joint velocity to end-effector spatial velocity expressed in the
380
+ base frame.
381
+
382
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
383
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
384
+
385
+ Examples
386
+ --------
387
+
388
+ The following example makes a ``Puma560`` robot object, and solves for the
389
+ base-frame Jacobian at the zero joint angle configuration
390
+
391
+ .. runblock:: pycon
392
+ >>> import roboticstoolbox as rtb
393
+ >>> puma = rtb.models.Puma560().ets()
394
+ >>> puma.jacob0([0, 0, 0, 0, 0, 0])
395
+
396
+ .. rubric:: Notes
397
+
398
+ - This is the geometric Jacobian as described in texts by
399
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
400
+ described in terms of translational and angular velocity, not a
401
+ velocity twist as per the text by Lynch & Park.
402
+
403
+ .. rubric:: References
404
+
405
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
406
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
407
+
408
+ """
409
+
410
+ return ETS_jacob0(self._fknm, q, tool, _data=self.data, _n=self.n)
411
+
412
+ def jacobe(
413
+ self,
414
+ q: ArrayLike,
415
+ tool: NDArray | SE3 | None = None,
416
+ ) -> NDArray:
417
+ r"""
418
+ Manipulator geometric Jacobian in the end-effector frame
419
+
420
+ :param q: Joint coordinate vector
421
+ :param tool: a static tool transformation matrix to apply to the end of ETS
422
+ :returns: Manipulator Jacobian in the end-effector frame
423
+ :rtype: ndarray(6,n)
424
+
425
+ ``robot.jacobe(q)`` is the manipulator Jacobian matrix which maps
426
+ joint velocity to end-effector spatial velocity expressed in the
427
+ end-effector frame.
428
+
429
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
430
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
431
+
432
+ Examples
433
+ --------
434
+
435
+ The following example makes a ``Puma560`` robot object, and solves for the
436
+ end-effector frame Jacobian at the zero joint angle configuration
437
+
438
+ .. runblock:: pycon
439
+ >>> import roboticstoolbox as rtb
440
+ >>> puma = rtb.models.Puma560().ets()
441
+ >>> puma.jacobe([0, 0, 0, 0, 0, 0])
442
+
443
+ .. rubric:: Notes
444
+
445
+ - This is the geometric Jacobian as described in texts by
446
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
447
+ described in terms of translational and angular velocity, not a
448
+ velocity twist as per the text by Lynch & Park.
449
+
450
+ .. rubric:: References
451
+
452
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
453
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
454
+
455
+ """
456
+
457
+ return ETS_jacobe(self._fknm, q, tool, _data=self.data, _n=self.n)
458
+
459
+ def hessian0(
460
+ self,
461
+ q: ArrayLike | None = None,
462
+ J0: NDArray | None = None,
463
+ tool: NDArray | SE3 | None = None,
464
+ ) -> NDArray:
465
+ r"""
466
+ Manipulator Hessian in the base frame
467
+
468
+ :param q: joint angles (optional if J0 supplied)
469
+ :param J0: the manipulator Jacobian in the base frame (optional if q supplied)
470
+ :param tool: a static tool transformation matrix to apply to the end of ETS
471
+ :returns: The manipulator Hessian in the base frame
472
+ :rtype: ndarray(n,6,n)
473
+
474
+ This method computes the manipulator Hessian in the base frame. If
475
+ we take the time derivative of the differential kinematic relationship
476
+
477
+ .. math::
478
+
479
+ \nu &= \mat{J}(\vec{q}) \dvec{q} \\
480
+ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}
481
+
482
+ where
483
+
484
+ .. math::
485
+
486
+ \dmat{J} = \mat{H} \dvec{q}
487
+
488
+ and :math:`\mat{H} \in \mathbb{R}^{6\times n \times n}` is the
489
+ Hessian tensor.
490
+
491
+ The elements of the Hessian are
492
+
493
+ .. math::
494
+
495
+ \mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}
496
+
497
+ where :math:`u = \{t_x, t_y, t_z, r_x, r_y, r_z\}` are the elements
498
+ of the spatial velocity vector.
499
+
500
+ Similarly, we can write
501
+
502
+ .. math::
503
+
504
+ \mat{J}_{i,j} = \frac{d u_i}{d q_j}
505
+
506
+ Examples
507
+ --------
508
+
509
+ The following example makes a ``Panda`` robot object, and solves for the
510
+ base frame Hessian at the given joint angle configuration
511
+
512
+ .. runblock:: pycon
513
+ >>> import roboticstoolbox as rtb
514
+ >>> panda = rtb.models.Panda().ets()
515
+ >>> panda.hessian0([0, -0.3, 0, -2.2, 0, 2, 0.7854])
516
+
517
+ .. rubric:: References
518
+
519
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
520
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
521
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
522
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
523
+
524
+ """
525
+
526
+ return ETS_hessian0(self._fknm, q, J0, tool, _data=self.data, _n=self.n)
527
+
528
+ def hessiane(
529
+ self,
530
+ q: ArrayLike | None = None,
531
+ Je: NDArray | None = None,
532
+ tool: NDArray | SE3 | None = None,
533
+ ) -> NDArray:
534
+ r"""
535
+ Manipulator Hessian in the end-effector frame
536
+
537
+ :param q: joint angles (optional if Je supplied)
538
+ :param Je: the manipulator Jacobian in the end-effector frame (optional if q supplied)
539
+ :param tool: a static tool transformation matrix to apply to the end of ETS
540
+ :returns: The manipulator Hessian in the end-effector frame
541
+ :rtype: ndarray(n,6,n)
542
+
543
+ This method computes the manipulator Hessian in the end-effector frame. If
544
+ we take the time derivative of the differential kinematic relationship
545
+
546
+ .. math::
547
+
548
+ \nu &= \mat{J}(\vec{q}) \dvec{q} \\
549
+ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}
550
+
551
+ where
552
+
553
+ .. math::
554
+
555
+ \dmat{J} = \mat{H} \dvec{q}
556
+
557
+ and :math:`\mat{H} \in \mathbb{R}^{6\times n \times n}` is the
558
+ Hessian tensor.
559
+
560
+ The elements of the Hessian are
561
+
562
+ .. math::
563
+
564
+ \mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}
565
+
566
+ where :math:`u = \{t_x, t_y, t_z, r_x, r_y, r_z\}` are the elements
567
+ of the spatial velocity vector.
568
+
569
+ Similarly, we can write
570
+
571
+ .. math::
572
+
573
+ \mat{J}_{i,j} = \frac{d u_i}{d q_j}
574
+
575
+ Examples
576
+ --------
577
+
578
+ The following example makes a ``Panda`` robot object, and solves for the
579
+ end-effector frame Hessian at the given joint angle configuration
580
+
581
+ .. runblock:: pycon
582
+ >>> import roboticstoolbox as rtb
583
+ >>> panda = rtb.models.Panda().ets()
584
+ >>> panda.hessiane([0, -0.3, 0, -2.2, 0, 2, 0.7854])
585
+
586
+ .. rubric:: References
587
+
588
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
589
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
590
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
591
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
592
+
593
+ """
594
+
595
+ return ETS_hessiane(self._fknm, q, Je, tool, _data=self.data, _n=self.n)
596
+
597
+ def jacob0_analytical(
598
+ self,
599
+ q: ArrayLike,
600
+ representation: str = "rpy/xyz",
601
+ tool: NDArray | SE3 | None = None,
602
+ ):
603
+ r"""
604
+ Manipulator analytical Jacobian in the base frame
605
+
606
+ :param q: joint coordinate vector
607
+ :param representation: angular representation
608
+ :param tool: a static tool transformation matrix to apply to the end of ETS
609
+ :returns: Manipulator Jacobian in the base frame
610
+ :rtype: ndarray(6,n)
611
+
612
+ ``robot.jacob0_analytical(q)`` is the manipulator Jacobian matrix which maps
613
+ joint velocity to end-effector spatial velocity expressed in the base frame.
614
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
615
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
616
+
617
+ |``representation`` | Rotational representation |
618
+ |---------------------|-------------------------------------|
619
+ |``'rpy/xyz'`` | RPY angular rates in XYZ order |
620
+ |``'rpy/zyx'`` | RPY angular rates in XYZ order |
621
+ |``'eul'`` | Euler angular rates in ZYZ order |
622
+ |``'exp'`` | exponential coordinate rates |
623
+
624
+ Examples
625
+ --------
626
+
627
+ Makes a robot object and computes the analytic Jacobian for the given
628
+ joint configuration
629
+
630
+ .. runblock:: pycon
631
+ >>> import roboticstoolbox as rtb
632
+ >>> puma = rtb.models.ETS.Puma560().ets()
633
+ >>> puma.jacob0_analytical([0, 0, 0, 0, 0, 0])
634
+
635
+ """
636
+
637
+ T = self.eval(q, tool=tool)
638
+ J = self.jacob0(q, tool=tool)
639
+ gamma = t2r(T)[:3, :3]
640
+ A = rotvelxform(gamma, full=True, inverse=True, representation=representation)
641
+ return A @ J
642
+
643
+ def jacobm(self, q: ArrayLike) -> NDArray:
644
+ r"""
645
+ The manipulability Jacobian
646
+
647
+ :param q: joint angles/configuration of the robot
648
+ :returns: The manipulability Jacobian
649
+ :rtype: ndarray(n,1)
650
+
651
+ This measure relates the rate of change of the manipulability to the
652
+ joint velocities of the robot.
653
+ Yoshikawa's manipulability measure
654
+
655
+ .. math::
656
+
657
+ m(\vec{q}) = \sqrt{\mat{J}(\vec{q}) \mat{J}(\vec{q})^T}
658
+
659
+ This method returns its Jacobian with respect to configuration
660
+
661
+ .. math::
662
+
663
+ \frac{\partial m(\vec{q})}{\partial \vec{q}}
664
+
665
+ .. rubric:: References
666
+
667
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
668
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
669
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
670
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
671
+
672
+ """
673
+
674
+ J = self.jacob0(q)
675
+ H = self.hessian0(q)
676
+
677
+ manipulability = self.manipulability(q)
678
+
679
+ # J = J[axes, :]
680
+ # H = H[:, axes, :]
681
+
682
+ b = inv(J @ J.T)
683
+ Jm = np.zeros((self.n, 1))
684
+
685
+ for i in range(self.n):
686
+ c = J @ H[i, :, :].T
687
+ Jm[i, 0] = manipulability * (c.flatten("F")).T @ b.flatten("F")
688
+
689
+ return Jm
690
+
691
+ def manipulability(
692
+ self,
693
+ q,
694
+ method: L["yoshikawa", "minsingular", "invcondition"] = "yoshikawa",
695
+ axes: L["all", "trans", "rot"] | list[bool] = "all",
696
+ ):
697
+ """
698
+ Manipulability measure
699
+
700
+ :param q: joint coordinates (trajectory as matrix(m,n))
701
+ :param method: method to use, ``"yoshikawa"`` (default), ``"invcondition"``, or ``"minsingular"``
702
+ :param axes: task space axes to consider: ``"all"`` [default], ``"trans"``, or ``"rot"``
703
+ :returns: the manipulability metric
704
+ :rtype: float | ndarray(m)
705
+
706
+ ``manipulability(q)`` is the scalar manipulability index
707
+ for the ets at the joint configuration ``q``. It indicates
708
+ dexterity, that is, how well conditioned the ets is for motion
709
+ with respect to the 6 degrees of Cartesian motion. The value is
710
+ zero if the ets is at a singularity.
711
+
712
+ Various measures are supported:
713
+
714
+ | Measure | Description |
715
+ |-------------------|-------------------------------------------------|
716
+ | ``"yoshikawa"`` | Volume of the velocity ellipsoid, *distance* |
717
+ | | from singularity [Yoshikawa85]_ |
718
+ | ``"invcondition"``| Inverse condition number of Jacobian, isotropy |
719
+ | | of the velocity ellipsoid [Klein87]_ |
720
+ | ``"minsingular"`` | Minimum singular value of the Jacobian, |
721
+ | | *distance* from singularity [Klein87]_ |
722
+
723
+ **Trajectory operation**:
724
+
725
+ If ``q`` is a matrix (m,n) then the result (m,) is a vector of
726
+ manipulability indices for each joint configuration specified by a row
727
+ of ``q``.
728
+
729
+ .. rubric:: Notes
730
+
731
+ - Invokes the ``jacob0`` method of the robot if ``J`` is not passed
732
+ - The "all" option includes rotational and translational
733
+ dexterity, but this involves adding different units. It can be
734
+ more useful to look at the translational and rotational
735
+ manipulability separately.
736
+ - Examples in the RVC book (1st edition) can be replicated by
737
+ using the "all" option
738
+ - Asada's measure requires inertial a robot model with inertial
739
+ parameters.
740
+
741
+ .. rubric:: References
742
+
743
+ .. [Yoshikawa85] Manipulability of Robotic Mechanisms. Yoshikawa T.,
744
+ The International Journal of Robotics Research.
745
+ 1985;4(2):3-9. doi:10.1177/027836498500400201
746
+ .. [Klein87] Dexterity Measures for the Design and Control of
747
+ Kinematically Redundant Manipulators. Klein CA, Blaho BE.
748
+ The International Journal of Robotics Research.
749
+ 1987;6(2):72-83. doi:10.1177/027836498700600206
750
+ - Robotics, Vision & Control in Python, 3e, P. Corke, Springer 2023, Chap 7.
751
+
752
+
753
+ .. versionchanged:: 1.0.4
754
+ Removed 'both' option for axes, added a custom list option.
755
+
756
+ """
757
+
758
+ axes_list: list[bool] = []
759
+
760
+ if isinstance(axes, list):
761
+ axes_list = axes
762
+ elif axes == "all":
763
+ axes_list = [True, True, True, True, True, True]
764
+ elif axes.startswith("trans"):
765
+ axes_list = [True, True, True, False, False, False]
766
+ elif axes.startswith("rot"):
767
+ axes_list = [False, False, False, True, True, True]
768
+ else:
769
+ raise ValueError("axes must be all, trans, rot or both")
770
+
771
+ def yoshikawa(robot, J, q, axes, **kwargs):
772
+ J = J[axes, :]
773
+ if J.shape[0] == J.shape[1]:
774
+ # simplified case for square matrix
775
+ return abs(det(J))
776
+ else:
777
+ m2 = det(J @ J.T)
778
+ return np.sqrt(abs(m2))
779
+
780
+ def condition(robot, J, q, axes, **kwargs):
781
+ J = J[axes, :]
782
+ return 1 / cond(J)
783
+
784
+ def minsingular(robot, J, q, axes, **kwargs):
785
+ J = J[axes, :]
786
+ s = svd(J, compute_uv=False)
787
+ return s[-1] # return last/smallest singular value of J
788
+
789
+ # choose the handler function
790
+ if method == "yoshikawa":
791
+ mfunc = yoshikawa
792
+ elif method == "invcondition":
793
+ mfunc = condition
794
+ elif method == "minsingular":
795
+ mfunc = minsingular
796
+ else:
797
+ raise ValueError("Invalid method chosen")
798
+
799
+ # Otherwise use the q vector/matrix
800
+ q = np.array(getmatrix(q, (None, self.n)))
801
+ w = np.zeros(q.shape[0])
802
+
803
+ for k, qk in enumerate(q):
804
+ Jk = self.jacob0(qk)
805
+ w[k] = mfunc(self, Jk, qk, axes_list)
806
+
807
+ if len(w) == 1:
808
+ return w[0]
809
+ else:
810
+ return w
811
+
812
+ def partial_fkine0(self, q: ArrayLike, n: int) -> NDArray:
813
+ r"""
814
+ Manipulator Forward Kinematics nth Partial Derivative
815
+
816
+ :param q: joint angles/configuration of the robot
817
+ :param n: the order of derivative (must be >= 3)
818
+ :returns: The nth partial derivative of the forward kinematics
819
+
820
+ This method computes the nth derivative of the forward kinematics where ``n`` is
821
+ greater than or equal to 3. This is an extension of the differential kinematics
822
+ where the Jacobian is the first partial derivative and the Hessian is the
823
+ second.
824
+
825
+ Examples
826
+ --------
827
+
828
+ The following example makes a ``Panda`` robot object, and solves for the
829
+ base-effector frame 4th derivative of the forward kinematics at the given
830
+ joint angle configuration
831
+
832
+ .. runblock:: pycon
833
+ >>> import roboticstoolbox as rtb
834
+ >>> panda = rtb.models.Panda().ets()
835
+ >>> panda.partial_fkine0([0, -0.3, 0, -2.2, 0, 2, 0.7854], n=4)
836
+
837
+ .. rubric:: References
838
+
839
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
840
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
841
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
842
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
843
+
844
+ """
845
+
846
+ # Calculate the Jacobian and Hessian
847
+ J = self.jacob0(q)
848
+ H = self.hessian0(q)
849
+
850
+ # A list of derivatives, starting with the jacobian and hessian
851
+ dT = [J, H]
852
+
853
+ # The tensor dimensions of the latest derivative
854
+ # Set to the current size of the Hessian
855
+ size = [self.n, 6, self.n]
856
+
857
+ # An array which keeps track of the index of the partial derivative
858
+ # we are calculating
859
+ # It stores the indices in the order: "j, k, l. m, n, o, ..."
860
+ # where count is extended to match oder of the partial derivative
861
+ count = np.array([0, 0])
862
+
863
+ # The order of derivative for which we are calculating
864
+ # The Hessian is the 2nd-order so we start with c = 2
865
+ c = 2
866
+
867
+ def add_indices(indices, c):
868
+ total = len(indices * 2)
869
+ new_indices = []
870
+
871
+ for i in range(total):
872
+ j = i // 2
873
+ new_indices.append([])
874
+ new_indices[i].append(indices[j][0].copy())
875
+ new_indices[i].append(indices[j][1].copy())
876
+
877
+ if i % 2 == 0:
878
+ # if even number
879
+ new_indices[i][0].append(c)
880
+ else:
881
+ # if odd number
882
+ new_indices[i][1].append(c)
883
+
884
+ return new_indices
885
+
886
+ def add_pdi(pdi):
887
+ total = len(pdi * 2)
888
+ new_pdi = []
889
+
890
+ for i in range(total):
891
+ j = i // 2
892
+ new_pdi.append([])
893
+ new_pdi[i].append(pdi[j][0])
894
+ new_pdi[i].append(pdi[j][1])
895
+
896
+ # if even number
897
+ if i % 2 == 0:
898
+ new_pdi[i][0] += 1
899
+ # if odd number
900
+ else:
901
+ new_pdi[i][1] += 1
902
+
903
+ return new_pdi
904
+
905
+ # these are the indices used for the hessian
906
+ indices = [[[1], [0]]]
907
+
908
+ # The partial derivative indices (pdi)
909
+ # the are the pd indices used in the cross products
910
+ pdi = [[0, 0]]
911
+
912
+ # The length of dT correspods to the number of derivatives we have calculated
913
+ while len(dT) != n:
914
+ # Add to the start of the tensor size list
915
+ size.insert(0, self.n)
916
+
917
+ # Add an axis to the count array
918
+ count = np.concatenate(([0], count))
919
+
920
+ # This variables corresponds to indices within the previous
921
+ # partial derivatives
922
+ # to be cross prodded
923
+ # The order is: "[j, k, l, m, n, o, ...]"
924
+ # Although, our partial derivatives have the order:
925
+ # pd[..., o, n, m, l, k, cartesian DoF, j]
926
+ # For example, consider the Hessian Tensor H[n, 6, n],
927
+ # the index H[k, :, j]. This corrsponds
928
+ # to the second partial derivative of the kinematics of joint j with
929
+ # respect to joint k.
930
+ indices = add_indices(indices, c)
931
+
932
+ # This variable corresponds to the indices in Td which corresponds to the
933
+ # partial derivatives we need to use
934
+ pdi = add_pdi(pdi)
935
+
936
+ c += 1
937
+
938
+ # Allocate our new partial derivative tensor
939
+ pd = np.zeros(size)
940
+
941
+ # We need to loop n^c times
942
+ # There are n^c columns to calculate
943
+ for _ in range(self.n**c):
944
+ # Allocate the rotation and translation components
945
+ rot = np.zeros(3)
946
+ trn = np.zeros(3)
947
+
948
+ # This loop calculates a single column ([trn, rot])
949
+ # of the tensor for dT(x)
950
+ for j in range(len(indices)):
951
+ pdr0 = dT[pdi[j][0]]
952
+ pdr1 = dT[pdi[j][1]]
953
+
954
+ idx0 = count[indices[j][0]]
955
+ idx1 = count[indices[j][1]]
956
+
957
+ # This is a list of indices selecting the slices of the
958
+ # previous tensor
959
+ idx0_slices = np.flip(idx0[1:])
960
+ idx1_slices = np.flip(idx1[1:])
961
+
962
+ # This index selecting the column within the 2d slice of the
963
+ # previous tensor
964
+ idx0_n = idx0[0]
965
+ idx1_n = idx1[0]
966
+
967
+ # Use our indices to select the rotational column from pdr0 and pdr1
968
+ col0_rot = pdr0[(*idx0_slices, slice(3, 6), idx0_n)]
969
+ col1_rot = pdr1[(*idx1_slices, slice(3, 6), idx1_n)]
970
+
971
+ # Use our indices to select the translational column from pdr1
972
+ col1_trn = pdr1[(*idx1_slices, slice(0, 3), idx1_n)]
973
+
974
+ # Perform the cross product as described in the maths above
975
+ rot += np.cross(col0_rot, col1_rot)
976
+ trn += np.cross(col0_rot, col1_trn)
977
+
978
+ pd[(*np.flip(count[1:]), slice(0, 3), count[0])] = trn
979
+ pd[(*np.flip(count[1:]), slice(3, 6), count[0])] = rot
980
+
981
+ count[0] += 1
982
+ for j in range(len(count)):
983
+ if count[j] == self.n:
984
+ count[j] = 0
985
+ if j != len(count) - 1:
986
+ count[j + 1] += 1
987
+
988
+ dT.append(pd)
989
+
990
+ return dT[-1]
991
+
992
+ def ik_LM(
993
+ self,
994
+ Tep: NDArray | SE3,
995
+ q0: NDArray | None = None,
996
+ ilimit: int = 30,
997
+ slimit: int = 100,
998
+ tol: float = 1e-6,
999
+ mask: NDArray | None = None,
1000
+ joint_limits: bool = True,
1001
+ k: float = 1.0,
1002
+ method: L["chan", "wampler", "sugihara"] = "chan",
1003
+ ) -> tuple[NDArray, int, int, int, float]:
1004
+ r"""
1005
+ Fast Levenberg-Marquardt numerical inverse kinematics solver
1006
+
1007
+ :param Tep: the desired end-effector pose
1008
+ :param q0: the initial joint coordinate vector
1009
+ :param ilimit: maximum iterations allowed per search
1010
+ :param slimit: maximum search attempts before failure
1011
+ :param tol: maximum allowed residual error E
1012
+ :param mask: a 6-vector weighting Cartesian DoF error priority
1013
+ :param joint_limits: reject solutions with joint limit violations
1014
+ :param k: gain value for the damping matrix Wn
1015
+ :param method: one of ``"chan"`` (default), ``"sugihara"`` or ``"wampler"``
1016
+ :returns: tuple (q, success, iterations, searches, residual)
1017
+ :rtype: tuple
1018
+
1019
+ A method which provides functionality to perform numerical inverse kinematics (IK)
1020
+ using the Levenberg-Marquardt method. This is a fast solver implemented in C++.
1021
+
1022
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1023
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1024
+
1025
+ The operation is defined by the choice of the ``method`` kwarg.
1026
+
1027
+ The step is deined as
1028
+
1029
+ .. math::
1030
+
1031
+ \vec{q}_{k+1}
1032
+ &=
1033
+ \vec{q}_k +
1034
+ \left(
1035
+ \mat{A}_k
1036
+ \right)^{-1}
1037
+ \bf{g}_k \\
1038
+ %
1039
+ \mat{A}_k
1040
+ &=
1041
+ {\mat{J}(\vec{q}_k)}^\top
1042
+ \mat{W}_e \
1043
+ {\mat{J}(\vec{q}_k)}
1044
+ +
1045
+ \mat{W}_n
1046
+
1047
+ where :math:`\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})` is a
1048
+ diagonal damping matrix. The damping matrix ensures that :math:`\mat{A}_k` is
1049
+ non-singular and positive definite. The performance of the LM method largely depends
1050
+ on the choice of :math:`\mat{W}_n`.
1051
+
1052
+ *Chan's Method*
1053
+
1054
+ Chan proposed
1055
+
1056
+ .. math::
1057
+
1058
+ \mat{W}_n
1059
+ =
1060
+ λ E_k \mat{1}_n
1061
+
1062
+ where λ is a constant which reportedly does not have much influence on performance.
1063
+ Use the kwarg `k` to adjust the weighting term λ.
1064
+
1065
+ *Sugihara's Method*
1066
+
1067
+ Sugihara proposed
1068
+
1069
+ .. math::
1070
+
1071
+ \mat{W}_n
1072
+ =
1073
+ E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)
1074
+
1075
+ where :math:`\hat{\vec{w}}_n \in \mathbb{R}^n`, :math:`\hat{w}_{n_i} = l^2 \sim 0.01 l^2`,
1076
+ and :math:`l` is the length of a typical link within the manipulator. We provide the
1077
+ variable `k` as a kwarg to adjust the value of :math:`w_n`.
1078
+
1079
+ *Wampler's Method*
1080
+
1081
+ Wampler proposed :math:`\vec{w_n}` to be a constant. This is set through the `k` kwarg.
1082
+
1083
+ Examples
1084
+ --------
1085
+
1086
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1087
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1088
+ ``Tep`` using the `ikine_LM` method.
1089
+
1090
+ .. runblock:: pycon
1091
+ >>> import roboticstoolbox as rtb
1092
+ >>> panda = rtb.models.Panda().ets()
1093
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1094
+ >>> panda.ikine_LM(Tep)
1095
+
1096
+ .. rubric:: Notes
1097
+
1098
+ The value for the ``k`` kwarg will depend on the ``method`` chosen and the arm you are
1099
+ using. Use the following as a rough guide ``chan, k = 1.0 - 0.01``,
1100
+ ``wampler, k = 0.01 - 0.0001``, and ``sugihara, k = 0.1 - 0.0001``
1101
+
1102
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1103
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1104
+
1105
+ This class supports null-space motion to assist with maximising manipulability and
1106
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
1107
+
1108
+ .. rubric:: References
1109
+
1110
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1111
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1112
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1113
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1114
+
1115
+ .. seealso:: :meth:`ik_NR` :meth:`ik_GN`
1116
+
1117
+ .. versionchanged:: 1.0.4
1118
+ Merged the Levenberg-Marquardt IK solvers into the ik_LM method
1119
+
1120
+ """
1121
+
1122
+ return IK_LM_c(
1123
+ self._fknm, Tep, q0, ilimit, slimit, tol, joint_limits, mask, k, method
1124
+ )
1125
+
1126
+ def ik_NR(
1127
+ self,
1128
+ Tep: NDArray | SE3,
1129
+ q0: NDArray | None = None,
1130
+ ilimit: int = 30,
1131
+ slimit: int = 100,
1132
+ tol: float = 1e-6,
1133
+ mask: NDArray | None = None,
1134
+ joint_limits: bool = True,
1135
+ pinv: int = True,
1136
+ pinv_damping: float = 0.0,
1137
+ ) -> tuple[NDArray, int, int, int, float]:
1138
+ r"""
1139
+ Fast numerical inverse kinematics using Newton-Raphson optimisation
1140
+
1141
+ :param Tep: the desired end-effector pose or pose trajectory
1142
+ :param q0: initial joint configuration (random valid configuration if not supplied)
1143
+ :param ilimit: maximum number of iterations per search
1144
+ :param slimit: maximum number of search attempts
1145
+ :param tol: final error tolerance
1146
+ :param mask: a 6-vector weighting end-effector error priority (XYZ translation, XYZ rotation)
1147
+ :param joint_limits: reject solutions with invalid joint configurations
1148
+ :param pinv: use the pseudo-inverse instead of the normal matrix inverse
1149
+ :param pinv_damping: damping factor for the pseudo-inverse
1150
+ :returns: tuple (q, success, iterations, searches, residual)
1151
+ :rtype: tuple
1152
+
1153
+ ``sol = ets.ik_NR(Tep)`` are the joint coordinates (n) corresponding
1154
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
1155
+ This method can be used for robots with any number of degrees of freedom. This
1156
+ is a fast solver implemented in C++.
1157
+
1158
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1159
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1160
+
1161
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``.
1162
+
1163
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
1164
+ solution will be in error. The amount of error is indicated by
1165
+ the ``residual``.
1166
+
1167
+ Each iteration uses the Newton-Raphson optimisation method
1168
+
1169
+ .. math::
1170
+
1171
+ \vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k
1172
+
1173
+ Examples
1174
+ --------
1175
+
1176
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1177
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1178
+ ``Tep`` using the `ik_NR` method.
1179
+
1180
+ .. runblock:: pycon
1181
+ >>> import roboticstoolbox as rtb
1182
+ >>> panda = rtb.models.Panda().ets()
1183
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1184
+ >>> panda.ik_NR(Tep)
1185
+
1186
+ .. rubric:: Notes
1187
+
1188
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1189
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1190
+
1191
+ .. rubric:: References
1192
+
1193
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1194
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1195
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1196
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1197
+
1198
+ .. seealso:: :meth:`ik_LM` :meth:`ik_GN`
1199
+
1200
+ """
1201
+
1202
+ return IK_NR_c(
1203
+ self._fknm,
1204
+ Tep,
1205
+ q0,
1206
+ ilimit,
1207
+ slimit,
1208
+ tol,
1209
+ joint_limits,
1210
+ mask,
1211
+ pinv,
1212
+ pinv_damping,
1213
+ )
1214
+
1215
+ def ik_GN(
1216
+ self,
1217
+ Tep: NDArray | SE3,
1218
+ q0: NDArray | None = None,
1219
+ ilimit: int = 30,
1220
+ slimit: int = 100,
1221
+ tol: float = 1e-6,
1222
+ mask: NDArray | None = None,
1223
+ joint_limits: bool = True,
1224
+ pinv: int = True,
1225
+ pinv_damping: float = 0.0,
1226
+ ) -> tuple[NDArray, int, int, int, float]:
1227
+ r"""
1228
+ Fast numerical inverse kinematics by Gauss-Newton optimisation
1229
+
1230
+ :param Tep: the desired end-effector pose or pose trajectory
1231
+ :param q0: initial joint configuration (random valid configuration if not supplied)
1232
+ :param ilimit: maximum number of iterations per search
1233
+ :param slimit: maximum number of search attempts
1234
+ :param tol: final error tolerance
1235
+ :param mask: a 6-vector weighting end-effector error priority (XYZ translation, XYZ rotation)
1236
+ :param joint_limits: reject solutions with invalid joint configurations
1237
+ :param pinv: use the pseudo-inverse instead of the normal matrix inverse
1238
+ :param pinv_damping: damping factor for the pseudo-inverse
1239
+ :returns: tuple (q, success, iterations, searches, residual)
1240
+ :rtype: tuple
1241
+
1242
+ ``sol = ets.ik_GN(Tep)`` are the joint coordinates (n) corresponding
1243
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
1244
+ This method can be used for robots with any number of degrees of freedom. This
1245
+ is a fast solver implemented in C++.
1246
+
1247
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1248
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1249
+
1250
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``.
1251
+
1252
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
1253
+ solution will be in error. The amount of error is indicated by
1254
+ the ``residual``.
1255
+
1256
+ Each iteration uses the Gauss-Newton optimisation method
1257
+
1258
+ .. math::
1259
+
1260
+ \vec{q}_{k+1} &= \vec{q}_k +
1261
+ \left(
1262
+ {\mat{J}(\vec{q}_k)}^\top
1263
+ \mat{W}_e \
1264
+ {\mat{J}(\vec{q}_k)}
1265
+ \right)^{-1}
1266
+ \bf{g}_k \\
1267
+ \bf{g}_k &=
1268
+ {\mat{J}(\vec{q}_k)}^\top
1269
+ \mat{W}_e
1270
+ \vec{e}_k
1271
+
1272
+ where :math:`\mat{J} = {^0\mat{J}}` is the base-frame manipulator Jacobian. If
1273
+ :math:`\mat{J}(\vec{q}_k)` is non-singular, and :math:`\mat{W}_e = \mat{1}_n`, then
1274
+ the above provides the pseudoinverse solution. However, if :math:`\mat{J}(\vec{q}_k)`
1275
+ is singular, the above can not be computed and the GN solution is infeasible.
1276
+
1277
+ Examples
1278
+ --------
1279
+
1280
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1281
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1282
+ ``Tep`` using the `ikine_GN` method.
1283
+
1284
+ .. runblock:: pycon
1285
+ >>> import roboticstoolbox as rtb
1286
+ >>> panda = rtb.models.Panda().ets()
1287
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1288
+ >>> panda.ik_GN(Tep)
1289
+
1290
+ .. rubric:: Notes
1291
+
1292
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1293
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1294
+
1295
+ .. rubric:: References
1296
+
1297
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1298
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1299
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1300
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1301
+
1302
+ .. seealso:: :meth:`ik_LM` :meth:`ik_NR`
1303
+
1304
+ """
1305
+
1306
+ return IK_GN_c(
1307
+ self._fknm,
1308
+ Tep,
1309
+ q0,
1310
+ ilimit,
1311
+ slimit,
1312
+ tol,
1313
+ joint_limits,
1314
+ mask,
1315
+ pinv,
1316
+ pinv_damping,
1317
+ )
1318
+
1319
+ def ikine_LM(
1320
+ self,
1321
+ Tep: NDArray | SE3,
1322
+ q0: ArrayLike | None = None,
1323
+ ilimit: int = 30,
1324
+ slimit: int = 100,
1325
+ tol: float = 1e-6,
1326
+ mask: ArrayLike | None = None,
1327
+ joint_limits: bool = True,
1328
+ seed: int | None = None,
1329
+ k: float = 1.0,
1330
+ method: L["chan", "wampler", "sugihara"] = "chan",
1331
+ kq: float = 0.0,
1332
+ km: float = 0.0,
1333
+ ps: float = 0.0,
1334
+ pi: NDArray | float = 0.3,
1335
+ **kwargs,
1336
+ ):
1337
+ r"""
1338
+ Levenberg-Marquardt numerical inverse kinematics solver
1339
+
1340
+ :param Tep: the desired end-effector pose
1341
+ :param q0: the initial joint coordinate vector
1342
+ :param ilimit: maximum iterations allowed per search
1343
+ :param slimit: maximum search attempts before failure
1344
+ :param tol: maximum allowed residual error E
1345
+ :param mask: a 6-vector weighting Cartesian DoF error priority
1346
+ :param joint_limits: reject solutions with joint limit violations
1347
+ :param seed: seed for the RNG used to generate random joint configurations
1348
+ :param k: gain value for the damping matrix Wn
1349
+ :param method: one of ``"chan"`` (default), ``"sugihara"`` or ``"wampler"``
1350
+ :param kq: gain for joint limit avoidance (0.0 disables)
1351
+ :param km: gain for manipulability maximisation (0.0 disables)
1352
+ :param ps: minimum joint approach distance to limit (radians or metres)
1353
+ :param pi: null-space influence distance (radians or metres)
1354
+ :returns: IK solution
1355
+
1356
+ A method which provides functionality to perform numerical inverse kinematics (IK)
1357
+ using the Levenberg-Marquardt method.
1358
+
1359
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1360
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1361
+
1362
+ The operation is defined by the choice of the ``method`` kwarg.
1363
+
1364
+ The step is defined as
1365
+
1366
+ .. math::
1367
+
1368
+ \vec{q}_{k+1}
1369
+ &=
1370
+ \vec{q}_k +
1371
+ \left(
1372
+ \mat{A}_k
1373
+ \right)^{-1}
1374
+ \bf{g}_k \\
1375
+ %
1376
+ \mat{A}_k
1377
+ &=
1378
+ {\mat{J}(\vec{q}_k)}^\top
1379
+ \mat{W}_e \
1380
+ {\mat{J}(\vec{q}_k)}
1381
+ +
1382
+ \mat{W}_n
1383
+
1384
+ where :math:`\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})` is a
1385
+ diagonal damping matrix. The damping matrix ensures that :math:`\mat{A}_k` is
1386
+ non-singular and positive definite. The performance of the LM method largely depends
1387
+ on the choice of :math:`\mat{W}_n`.
1388
+
1389
+ *Chan's Method*
1390
+
1391
+ Chan proposed
1392
+
1393
+ .. math::
1394
+
1395
+ \mat{W}_n
1396
+ =
1397
+ λ E_k \mat{1}_n
1398
+
1399
+ where λ is a constant which reportedly does not have much influence on performance.
1400
+ Use the kwarg `k` to adjust the weighting term λ.
1401
+
1402
+ *Sugihara's Method*
1403
+
1404
+ Sugihara proposed
1405
+
1406
+ .. math::
1407
+
1408
+ \mat{W}_n
1409
+ =
1410
+ E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)
1411
+
1412
+ where :math:`\hat{\vec{w}}_n \in \mathbb{R}^n`, :math:`\hat{w}_{n_i} = l^2 \sim 0.01 l^2`,
1413
+ and :math:`l` is the length of a typical link within the manipulator. We provide the
1414
+ variable `k` as a kwarg to adjust the value of :math:`w_n`.
1415
+
1416
+ *Wampler's Method*
1417
+
1418
+ Wampler proposed :math:`\vec{w_n}` to be a constant. This is set through the `k` kwarg.
1419
+
1420
+ Examples
1421
+ --------
1422
+
1423
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1424
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1425
+ ``Tep`` using the `ikine_LM` method.
1426
+
1427
+ .. runblock:: pycon
1428
+ >>> import roboticstoolbox as rtb
1429
+ >>> panda = rtb.models.Panda().ets()
1430
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1431
+ >>> panda.ikine_LM(Tep)
1432
+
1433
+ .. rubric:: Notes
1434
+
1435
+ The value for the ``k`` kwarg will depend on the ``method`` chosen and the arm you are
1436
+ using. Use the following as a rough guide ``chan, k = 1.0 - 0.01``,
1437
+ ``wampler, k = 0.01 - 0.0001``, and ``sugihara, k = 0.1 - 0.0001``
1438
+
1439
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1440
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1441
+
1442
+ This class supports null-space motion to assist with maximising manipulability and
1443
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
1444
+
1445
+ .. rubric:: References
1446
+
1447
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1448
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1449
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1450
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1451
+
1452
+ .. seealso:: :meth:`ikine_NR` :meth:`ikine_GN` :meth:`ikine_QP`
1453
+
1454
+ .. versionchanged:: 1.0.4
1455
+ Added the Levenberg-Marquardt IK solver method on the `ETS` class
1456
+
1457
+ """
1458
+
1459
+ solver = IK_LM(
1460
+ ilimit=ilimit,
1461
+ slimit=slimit,
1462
+ tol=tol,
1463
+ joint_limits=joint_limits,
1464
+ mask=mask,
1465
+ seed=seed,
1466
+ k=k,
1467
+ method=method,
1468
+ kq=kq,
1469
+ km=km,
1470
+ ps=ps,
1471
+ pi=pi,
1472
+ **kwargs,
1473
+ )
1474
+
1475
+ # if isinstance(Tep, SE3):
1476
+ # Tep = Tep.A
1477
+
1478
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
1479
+
1480
+ def ikine_NR(
1481
+ self,
1482
+ Tep: NDArray | SE3,
1483
+ q0: ArrayLike | None = None,
1484
+ ilimit: int = 30,
1485
+ slimit: int = 100,
1486
+ tol: float = 1e-6,
1487
+ mask: ArrayLike | None = None,
1488
+ joint_limits: bool = True,
1489
+ seed: int | None = None,
1490
+ pinv: bool = False,
1491
+ kq: float = 0.0,
1492
+ km: float = 0.0,
1493
+ ps: float = 0.0,
1494
+ pi: NDArray | float = 0.3,
1495
+ **kwargs,
1496
+ ):
1497
+ r"""
1498
+ Newton-Raphson numerical inverse kinematics solver
1499
+
1500
+ :param Tep: the desired end-effector pose
1501
+ :param q0: the initial joint coordinate vector
1502
+ :param ilimit: maximum iterations allowed per search
1503
+ :param slimit: maximum search attempts before failure
1504
+ :param tol: maximum allowed residual error E
1505
+ :param mask: a 6-vector weighting Cartesian DoF error priority
1506
+ :param joint_limits: reject solutions with joint limit violations
1507
+ :param seed: seed for the RNG used to generate random joint configurations
1508
+ :param pinv: use the pseudo-inverse in the step method instead of the normal inverse
1509
+ :param kq: gain for joint limit avoidance (0.0 disables)
1510
+ :param km: gain for manipulability maximisation (0.0 disables)
1511
+ :param ps: minimum joint approach distance to limit (radians or metres)
1512
+ :param pi: null-space influence distance (radians or metres)
1513
+ :returns: IK solution
1514
+
1515
+ A method which provides functionality to perform numerical inverse kinematics (IK)
1516
+ using the Newton-Raphson method.
1517
+
1518
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1519
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1520
+
1521
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``.
1522
+
1523
+ Each iteration uses the Newton-Raphson optimisation method
1524
+
1525
+ .. math::
1526
+
1527
+ \vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k
1528
+
1529
+ Examples
1530
+ --------
1531
+
1532
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1533
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1534
+ ``Tep`` using the `ikine_NR` method.
1535
+
1536
+ .. runblock:: pycon
1537
+ >>> import roboticstoolbox as rtb
1538
+ >>> panda = rtb.models.Panda().ets()
1539
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1540
+ >>> panda.ikine_NR(Tep)
1541
+
1542
+ .. rubric:: Notes
1543
+
1544
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1545
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1546
+
1547
+ This class supports null-space motion to assist with maximising manipulability and
1548
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
1549
+
1550
+ .. rubric:: References
1551
+
1552
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1553
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1554
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1555
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1556
+
1557
+ .. seealso:: :meth:`ikine_LM` :meth:`ikine_GN` :meth:`ikine_QP`
1558
+
1559
+ .. versionchanged:: 1.0.4
1560
+ Added the Newton-Raphson IK solver method on the `ETS` class
1561
+
1562
+ """
1563
+
1564
+ solver = IK_NR(
1565
+ ilimit=ilimit,
1566
+ slimit=slimit,
1567
+ tol=tol,
1568
+ joint_limits=joint_limits,
1569
+ mask=mask,
1570
+ seed=seed,
1571
+ pinv=pinv,
1572
+ kq=kq,
1573
+ km=km,
1574
+ ps=ps,
1575
+ pi=pi,
1576
+ **kwargs,
1577
+ )
1578
+
1579
+ # if isinstance(Tep, SE3):
1580
+ # Tep = Tep.A
1581
+
1582
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
1583
+
1584
+ def ikine_GN(
1585
+ self,
1586
+ Tep: NDArray | SE3,
1587
+ q0: ArrayLike | None = None,
1588
+ ilimit: int = 30,
1589
+ slimit: int = 100,
1590
+ tol: float = 1e-6,
1591
+ mask: ArrayLike | None = None,
1592
+ joint_limits: bool = True,
1593
+ seed: int | None = None,
1594
+ pinv: bool = False,
1595
+ kq: float = 0.0,
1596
+ km: float = 0.0,
1597
+ ps: float = 0.0,
1598
+ pi: NDArray | float = 0.3,
1599
+ **kwargs,
1600
+ ):
1601
+ r"""
1602
+ Gauss-Newton numerical inverse kinematics solver
1603
+
1604
+ :param Tep: the desired end-effector pose
1605
+ :param q0: the initial joint coordinate vector
1606
+ :param ilimit: maximum iterations allowed per search
1607
+ :param slimit: maximum search attempts before failure
1608
+ :param tol: maximum allowed residual error E
1609
+ :param mask: a 6-vector weighting Cartesian DoF error priority
1610
+ :param joint_limits: reject solutions with joint limit violations
1611
+ :param seed: seed for the RNG used to generate random joint configurations
1612
+ :param pinv: use the pseudo-inverse in the step method instead of the normal inverse
1613
+ :param kq: gain for joint limit avoidance (0.0 disables)
1614
+ :param km: gain for manipulability maximisation (0.0 disables)
1615
+ :param ps: minimum joint approach distance to limit (radians or metres)
1616
+ :param pi: null-space influence distance (radians or metres)
1617
+ :returns: IK solution
1618
+
1619
+ A method which provides functionality to perform numerical inverse kinematics (IK)
1620
+ using the Gauss-Newton method.
1621
+
1622
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1623
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1624
+
1625
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``.
1626
+
1627
+ Each iteration uses the Gauss-Newton optimisation method
1628
+
1629
+ .. math::
1630
+
1631
+ \vec{q}_{k+1} &= \vec{q}_k +
1632
+ \left(
1633
+ {\mat{J}(\vec{q}_k)}^\top
1634
+ \mat{W}_e \
1635
+ {\mat{J}(\vec{q}_k)}
1636
+ \right)^{-1}
1637
+ \bf{g}_k \\
1638
+ \bf{g}_k &=
1639
+ {\mat{J}(\vec{q}_k)}^\top
1640
+ \mat{W}_e
1641
+ \vec{e}_k
1642
+
1643
+ where :math:`\mat{J} = {^0\mat{J}}` is the base-frame manipulator Jacobian. If
1644
+ :math:`\mat{J}(\vec{q}_k)` is non-singular, and :math:`\mat{W}_e = \mat{1}_n`, then
1645
+ the above provides the pseudoinverse solution. However, if :math:`\mat{J}(\vec{q}_k)`
1646
+ is singular, the above can not be computed and the GN solution is infeasible.
1647
+
1648
+ Examples
1649
+ --------
1650
+
1651
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1652
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1653
+ ``Tep`` using the `ikine_GN` method.
1654
+
1655
+ .. runblock:: pycon
1656
+ >>> import roboticstoolbox as rtb
1657
+ >>> panda = rtb.models.Panda().ets()
1658
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1659
+ >>> panda.ikine_GN(Tep)
1660
+
1661
+ .. rubric:: Notes
1662
+
1663
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1664
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1665
+
1666
+ This class supports null-space motion to assist with maximising manipulability and
1667
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
1668
+
1669
+ .. rubric:: References
1670
+
1671
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1672
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1673
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1674
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1675
+
1676
+ .. seealso:: :meth:`ikine_LM` :meth:`ikine_NR` :meth:`ikine_QP`
1677
+
1678
+ .. versionchanged:: 1.0.4
1679
+ Added the Gauss-Newton IK solver method on the `ETS` class
1680
+
1681
+ """
1682
+
1683
+ solver = IK_GN(
1684
+ ilimit=ilimit,
1685
+ slimit=slimit,
1686
+ tol=tol,
1687
+ joint_limits=joint_limits,
1688
+ mask=mask,
1689
+ seed=seed,
1690
+ pinv=pinv,
1691
+ kq=kq,
1692
+ km=km,
1693
+ ps=ps,
1694
+ pi=pi,
1695
+ **kwargs,
1696
+ )
1697
+
1698
+ # if isinstance(Tep, SE3):
1699
+ # Tep = Tep.A
1700
+
1701
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
1702
+
1703
+ def ikine_QP(
1704
+ self,
1705
+ Tep: NDArray | SE3,
1706
+ q0: ArrayLike | None = None,
1707
+ ilimit: int = 30,
1708
+ slimit: int = 100,
1709
+ tol: float = 1e-6,
1710
+ mask: ArrayLike | None = None,
1711
+ joint_limits: bool = True,
1712
+ seed: int | None = None,
1713
+ kj=1.0,
1714
+ ks=1.0,
1715
+ kq: float = 0.0,
1716
+ km: float = 0.0,
1717
+ ps: float = 0.0,
1718
+ pi: NDArray | float = 0.3,
1719
+ **kwargs,
1720
+ ):
1721
+ r"""
1722
+ Quadratic programming numerical inverse kinematics solver
1723
+
1724
+ :param Tep: the desired end-effector pose
1725
+ :param q0: the initial joint coordinate vector
1726
+ :param ilimit: maximum iterations allowed per search
1727
+ :param slimit: maximum search attempts before failure
1728
+ :param tol: maximum allowed residual error E
1729
+ :param mask: a 6-vector weighting Cartesian DoF error priority
1730
+ :param joint_limits: reject solutions with joint limit violations
1731
+ :param seed: seed for the RNG used to generate random joint configurations
1732
+ :param kj: gain for joint velocity norm minimisation
1733
+ :param ks: gain adjusting the cost of slack (intentional error)
1734
+ :param kq: gain for joint limit avoidance (0.0 disables)
1735
+ :param km: gain for manipulability maximisation (0.0 disables)
1736
+ :param ps: minimum joint approach distance to limit (radians or metres)
1737
+ :param pi: null-space influence distance (radians or metres)
1738
+ :returns: IK solution
1739
+ :raises ImportError: if the package ``qpsolvers`` is not installed
1740
+
1741
+ A method that provides functionality to perform numerical inverse kinematics
1742
+ (IK) using a quadratic programming approach.
1743
+
1744
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
1745
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
1746
+
1747
+ Each iteration uses the following approach
1748
+
1749
+ .. math::
1750
+
1751
+ \vec{q}_{k+1} = \vec{q}_{k} + \dot{\vec{q}}.
1752
+
1753
+ where the QP is defined as
1754
+
1755
+ .. math::
1756
+
1757
+ \min_x \quad f_o(\vec{x}) &= \frac{1}{2} \vec{x}^\top \mathcal{Q} \vec{x}+ \mathcal{C}^\top \vec{x}, \\
1758
+ \text{subject to} \quad \mathcal{J} \vec{x} &= \vec{\nu}, \\
1759
+ \mathcal{A} \vec{x} &\leq \mathcal{B}, \\
1760
+ \vec{x}^- &\leq \vec{x} \leq \vec{x}^+
1761
+
1762
+ with
1763
+
1764
+ .. math::
1765
+
1766
+ \vec{x} &=
1767
+ \begin{pmatrix}
1768
+ \dvec{q} \\ \vec{\delta}
1769
+ \end{pmatrix} \in \mathbb{R}^{(n+6)} \\
1770
+ \mathcal{Q} &=
1771
+ \begin{pmatrix}
1772
+ \lambda_q \mat{1}_{n} & \mathbf{0}_{6 \times 6} \\ \mathbf{0}_{n \times n} & \lambda_\delta \mat{1}_{6}
1773
+ \end{pmatrix} \in \mathbb{R}^{(n+6) \times (n+6)} \\
1774
+ \mathcal{J} &=
1775
+ \begin{pmatrix}
1776
+ \mat{J}(\vec{q}) & \mat{1}_{6}
1777
+ \end{pmatrix} \in \mathbb{R}^{6 \times (n+6)} \\
1778
+ \mathcal{C} &=
1779
+ \begin{pmatrix}
1780
+ \mat{J}_m \\ \bf{0}_{6 \times 1}
1781
+ \end{pmatrix} \in \mathbb{R}^{(n + 6)} \\
1782
+ \mathcal{A} &=
1783
+ \begin{pmatrix}
1784
+ \mat{1}_{n \times n + 6} \\
1785
+ \end{pmatrix} \in \mathbb{R}^{(l + n) \times (n + 6)} \\
1786
+ \mathcal{B} &=
1787
+ \eta
1788
+ \begin{pmatrix}
1789
+ \frac{\rho_0 - \rho_s}
1790
+ {\rho_i - \rho_s} \\
1791
+ \vdots \\
1792
+ \frac{\rho_n - \rho_s}
1793
+ {\rho_i - \rho_s}
1794
+ \end{pmatrix} \in \mathbb{R}^{n} \\
1795
+ \vec{x}^{-, +} &=
1796
+ \begin{pmatrix}
1797
+ \dvec{q}^{-, +} \\
1798
+ \vec{\delta}^{-, +}
1799
+ \end{pmatrix} \in \mathbb{R}^{(n+6)},
1800
+
1801
+ where :math:`\vec{\delta} \in \mathbb{R}^6` is the slack vector,
1802
+ :math:`\lambda_\delta \in \mathbb{R}^+` is a gain term which adjusts the
1803
+ cost of the norm of the slack vector in the optimiser,
1804
+ :math:`\dvec{q}^{-,+}` are the minimum and maximum joint velocities, and
1805
+ :math:`\dvec{\delta}^{-,+}` are the minimum and maximum slack velocities.
1806
+
1807
+ Examples
1808
+ --------
1809
+
1810
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
1811
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
1812
+ ``Tep`` using the `ikine_QP` method.
1813
+
1814
+ .. runblock:: pycon
1815
+ >>> import roboticstoolbox as rtb
1816
+ >>> panda = rtb.models.Panda().ets()
1817
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1818
+ >>> panda.ikine_QP(Tep)
1819
+
1820
+ .. rubric:: Notes
1821
+
1822
+ When using this method, the initial joint coordinates :math:`q_0`, should correspond
1823
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
1824
+
1825
+ This class supports null-space motion to assist with maximising manipulability and
1826
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
1827
+
1828
+ .. rubric:: References
1829
+
1830
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1831
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1832
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1833
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1834
+
1835
+ .. seealso:: :meth:`ikine_LM` :meth:`ikine_NR` :meth:`ikine_GN`
1836
+
1837
+ .. versionchanged:: 1.0.4
1838
+ Added the Quadratic Programming IK solver method on the `ETS` class
1839
+
1840
+ """
1841
+
1842
+ solver = IK_QP(
1843
+ ilimit=ilimit,
1844
+ slimit=slimit,
1845
+ tol=tol,
1846
+ joint_limits=joint_limits,
1847
+ mask=mask,
1848
+ seed=seed,
1849
+ kj=kj,
1850
+ ks=ks,
1851
+ kq=kq,
1852
+ km=km,
1853
+ ps=ps,
1854
+ pi=pi,
1855
+ **kwargs,
1856
+ )
1857
+
1858
+ # if isinstance(Tep, SE3):
1859
+ # Tep = Tep.A
1860
+
1861
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
1862
+
1863
+ @staticmethod
1864
+ def _template_consume(elements: list["BaseET"], template: list[str]) -> int:
1865
+ """
1866
+ Greedily match a run of ETs against an ordered template of ``kind``
1867
+ strings, where each template slot is optional but present slots must
1868
+ occur in the given order.
1869
+
1870
+ :param elements: ETs to match, in the order they occur in the ETS
1871
+ :param template: ordered ``kind`` strings the elements may occupy
1872
+ :returns: number of leading ``elements`` consumed before the first
1873
+ one that fits no remaining template slot
1874
+ """
1875
+ slot = 0
1876
+ consumed = 0
1877
+ for et in elements:
1878
+ if et.kind in template[slot:]:
1879
+ slot = template.index(et.kind, slot) + 1
1880
+ consumed += 1
1881
+ else:
1882
+ break
1883
+ return consumed
1884
+
1885
+ def _split_convention(self, template: list[str], joint_slots: set[int], exposed: str):
1886
+ """
1887
+ Split according to a DH-like convention.
1888
+
1889
+ A segment is a 4-slot ordered ``template`` (e.g. Rz, tz, tx, Rx for
1890
+ DH); each slot is optional except that exactly one of the two
1891
+ ``joint_slots`` must be occupied by the segment's joint. Content
1892
+ between two joints must fully account for the gap in template
1893
+ order, else ``ValueError``. The end named by ``exposed`` (``"head"``
1894
+ or ``"tail"``) is reported separately and unvalidated; the other end
1895
+ is folded into the boundary segment.
1896
+ """
1897
+ idx = list(self.joint_idx())
1898
+ if len(idx) == 0:
1899
+ raise ValueError("ETS has no joints")
1900
+
1901
+ def joint_slot(et: "ET") -> int:
1902
+ if et.kind not in template or template.index(et.kind) not in joint_slots:
1903
+ raise ValueError(
1904
+ "ETS is not a valid DH/MDH parameterisation: "
1905
+ f"{et} is not a permitted joint for this convention"
1906
+ )
1907
+ return template.index(et.kind)
1908
+
1909
+ slots = [joint_slot(self[k]) for k in idx]
1910
+ start = [0] * len(idx)
1911
+ end = [0] * len(idx)
1912
+
1913
+ if exposed == "head":
1914
+ gap = list(reversed(self[0 : idx[0]]))
1915
+ sub = list(reversed(template[0 : slots[0]]))
1916
+ consumed = self._template_consume(gap, sub)
1917
+ start[0] = idx[0] - consumed
1918
+ head = self[0 : start[0]]
1919
+ else:
1920
+ head = self[0:0]
1921
+
1922
+ for i, k in enumerate(idx):
1923
+ hi_bound = idx[i + 1] if i + 1 < len(idx) else len(self)
1924
+ consumed = self._template_consume(
1925
+ list(self[k + 1 : hi_bound]), template[slots[i] + 1 :]
1926
+ )
1927
+ end[i] = k + 1 + consumed
1928
+
1929
+ if i + 1 < len(idx):
1930
+ gap = self[end[i] : idx[i + 1]]
1931
+ gap_consumed = self._template_consume(
1932
+ list(gap), template[0 : slots[i + 1]]
1933
+ )
1934
+ if gap_consumed != len(gap):
1935
+ raise ValueError(
1936
+ "ETS is not a valid DH/MDH parameterisation: "
1937
+ f"unexpected term at index {end[i] + gap_consumed}"
1938
+ )
1939
+ start[i + 1] = end[i]
1940
+
1941
+ if exposed == "tail":
1942
+ tail = self[end[-1] :]
1943
+ else:
1944
+ end[-1] = len(self)
1945
+ tail = self[0:0]
1946
+
1947
+ segments = [self.__class__(self[start[i] : end[i]]) for i in range(len(idx))]
1948
+ return segments, head, tail
1949
+
1950
+ def split(self, method: str = "last") -> list["ETS"]:
1951
+ r"""
1952
+ Split ETS into link segments
1953
+
1954
+ :param method: one of ``"first"``, ``"last"`` (default), ``"dh"``, or ``"mdh"``.
1955
+ :returns: ``[base, *segments, gripper]`` -- a list of length
1956
+ ``n_joints + 2``. ``base``/``gripper`` are empty ETS when the
1957
+ method has no concept of one (e.g. ``"dh"`` never populates
1958
+ ``gripper``, ``"mdh"`` never populates ``base``).
1959
+
1960
+ Split an ETS into segments representing links, plus a base and gripper segment.
1961
+ Unpack with ``base, *segments, gripper = ets.split(method)``.
1962
+
1963
+ The behaviour depends on the ``method`` argument:
1964
+
1965
+ * ``"first"``: each link segment begins with a joint and continues upto, but not
1966
+ including the next joint. Any constant ET before the first joint are part of
1967
+ the base. There are no gripper ET, they are included in the last link segment.
1968
+ * ``"last"``: each link segment ends with a joint and include all ET after the
1969
+ previous joint. Any constant ET after the last joint are part of the gripper.
1970
+ There are no base ET, they are included in the first link segment.
1971
+ * ``"dh"``: similar to ``"first"`` but each segment is validated against the
1972
+ Denavit-Hartenberg convention: an ordered, 4-slot template
1973
+ Rz($θ_j$) tz($d_j$) tx($a_j$) Rx($α_j$), exactly one of Rz/tz being the
1974
+ segment's joint and the rest optional (but present slots must occur in
1975
+ this order). Content between two joints that cannot be accounted for by
1976
+ the template raises ``ValueError``. The base (content before the first
1977
+ joint's template slots) is unvalidated and reported separately; trailing
1978
+ content past the last joint's template is folded into the last segment.
1979
+ * ``"mdh"``: similar to ``"last"`` but validated against the modified
1980
+ Denavit-Hartenberg convention, template tx($a_{j-1}$) Rx($α_{j-1}$)
1981
+ Rz($θ_j$) tz($d_j$), same rules as ``"dh"`` mirrored: the gripper
1982
+ (content past the last joint's template slots) is unvalidated and
1983
+ reported separately; leading content before the first joint's template
1984
+ is folded into the first segment.
1985
+
1986
+ .. runblock:: pycon
1987
+ >>> from roboticstoolbox.ets.ETS import *
1988
+ >>> e = tz(1) * Rx("q1") * tx(2) * Ry("q2") * ty(3) * Rz("q3") * tz(4)
1989
+ >>> base, *segments, gripper = e.split("first")
1990
+ >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}")
1991
+ >>> base, *segments, gripper = e.split("last")
1992
+ >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}")
1993
+ >>> e = tz(1) * Rz("q1") * tx(2) * Rx(90, 'deg') * Rz("q2") * tz(4) * Rz(180, 'deg') * tz("q3") * Rz(270, 'deg') * tz(4)
1994
+ >>> base, *segments, gripper = e.split("dh")
1995
+ >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}")
1996
+ >>> base, *segments, gripper = e.split("mdh")
1997
+ >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}")
1998
+ """
1999
+
2000
+ match method.lower():
2001
+ case "dh":
2002
+ segments, head, tail = self._split_convention(
2003
+ ["Rz", "tz", "tx", "Rx"], {0, 1}, exposed="head"
2004
+ )
2005
+ case "mdh":
2006
+ segments, head, tail = self._split_convention(
2007
+ ["tx", "Rx", "Rz", "tz"], {2, 3}, exposed="tail"
2008
+ )
2009
+ case _:
2010
+ return super().split(method) # type: ignore
2011
+
2012
+ return [head] + segments + [tail] # type: ignore
2013
+