roboticstoolbox-python 1.3.0__cp312-cp312-win_amd64.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 (673) hide show
  1. roboticstoolbox/__init__.py +104 -0
  2. roboticstoolbox/backends/Connector.py +107 -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 +253 -0
  21. roboticstoolbox/backends/PyPlot/PyPlot.py +769 -0
  22. roboticstoolbox/backends/PyPlot/PyPlot2.py +526 -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 +26 -0
  31. roboticstoolbox/bin/__init__.py +0 -0
  32. roboticstoolbox/bin/rtbtool.py +307 -0
  33. roboticstoolbox/blocks/Icons/250x250/armplot.png +0 -0
  34. roboticstoolbox/blocks/Icons/250x250/bicycle.png +0 -0
  35. roboticstoolbox/blocks/Icons/250x250/camera.png +0 -0
  36. roboticstoolbox/blocks/Icons/250x250/circlepath.png +0 -0
  37. roboticstoolbox/blocks/Icons/250x250/coriolis.png +0 -0
  38. roboticstoolbox/blocks/Icons/250x250/ctraj.png +0 -0
  39. roboticstoolbox/blocks/Icons/250x250/delta2tr.png +0 -0
  40. roboticstoolbox/blocks/Icons/250x250/diffsteer.png +0 -0
  41. roboticstoolbox/blocks/Icons/250x250/fdyn.png +0 -0
  42. roboticstoolbox/blocks/Icons/250x250/fdynx.png +0 -0
  43. roboticstoolbox/blocks/Icons/250x250/fkine.png +0 -0
  44. roboticstoolbox/blocks/Icons/250x250/gravload.png +0 -0
  45. roboticstoolbox/blocks/Icons/250x250/idyn.png +0 -0
  46. roboticstoolbox/blocks/Icons/250x250/idynx.png +0 -0
  47. roboticstoolbox/blocks/Icons/250x250/ikine.png +0 -0
  48. roboticstoolbox/blocks/Icons/250x250/inertia.png +0 -0
  49. roboticstoolbox/blocks/Icons/250x250/jacobian.png +0 -0
  50. roboticstoolbox/blocks/Icons/250x250/jtraj.png +0 -0
  51. roboticstoolbox/blocks/Icons/250x250/lspb.png +0 -0
  52. roboticstoolbox/blocks/Icons/250x250/multirotor.png +0 -0
  53. roboticstoolbox/blocks/Icons/250x250/multirotormixer.png +0 -0
  54. roboticstoolbox/blocks/Icons/250x250/multirotorplot.png +0 -0
  55. roboticstoolbox/blocks/Icons/250x250/point2tr.png +0 -0
  56. roboticstoolbox/blocks/Icons/250x250/tr2delta.png +0 -0
  57. roboticstoolbox/blocks/Icons/250x250/tr2t.png +0 -0
  58. roboticstoolbox/blocks/Icons/250x250/unicycle.png +0 -0
  59. roboticstoolbox/blocks/Icons/250x250/vehicleplot.png +0 -0
  60. roboticstoolbox/blocks/Icons/50x50/armplot.png +0 -0
  61. roboticstoolbox/blocks/Icons/50x50/bicycle.png +0 -0
  62. roboticstoolbox/blocks/Icons/50x50/camera.png +0 -0
  63. roboticstoolbox/blocks/Icons/50x50/circlepath.png +0 -0
  64. roboticstoolbox/blocks/Icons/50x50/coriolis.png +0 -0
  65. roboticstoolbox/blocks/Icons/50x50/delta2tr.png +0 -0
  66. roboticstoolbox/blocks/Icons/50x50/diffsteer.png +0 -0
  67. roboticstoolbox/blocks/Icons/50x50/fdyn.png +0 -0
  68. roboticstoolbox/blocks/Icons/50x50/fdynx.png +0 -0
  69. roboticstoolbox/blocks/Icons/50x50/fkine.png +0 -0
  70. roboticstoolbox/blocks/Icons/50x50/gravload.png +0 -0
  71. roboticstoolbox/blocks/Icons/50x50/idyn.png +0 -0
  72. roboticstoolbox/blocks/Icons/50x50/idynx.png +0 -0
  73. roboticstoolbox/blocks/Icons/50x50/ikine.png +0 -0
  74. roboticstoolbox/blocks/Icons/50x50/inertia.png +0 -0
  75. roboticstoolbox/blocks/Icons/50x50/jacobian.png +0 -0
  76. roboticstoolbox/blocks/Icons/50x50/jtraj.png +0 -0
  77. roboticstoolbox/blocks/Icons/50x50/lspb.png +0 -0
  78. roboticstoolbox/blocks/Icons/50x50/multirotor.png +0 -0
  79. roboticstoolbox/blocks/Icons/50x50/multirotormixer.png +0 -0
  80. roboticstoolbox/blocks/Icons/50x50/multirotorplot.png +0 -0
  81. roboticstoolbox/blocks/Icons/50x50/point2tr.png +0 -0
  82. roboticstoolbox/blocks/Icons/50x50/tr2delta.png +0 -0
  83. roboticstoolbox/blocks/Icons/50x50/tr2t.png +0 -0
  84. roboticstoolbox/blocks/Icons/50x50/unicycle.png +0 -0
  85. roboticstoolbox/blocks/Icons/50x50/vehicleplot.png +0 -0
  86. roboticstoolbox/blocks/Icons/armplot.png +0 -0
  87. roboticstoolbox/blocks/Icons/bicycle.png +0 -0
  88. roboticstoolbox/blocks/Icons/camera.png +0 -0
  89. roboticstoolbox/blocks/Icons/circlepath.png +0 -0
  90. roboticstoolbox/blocks/Icons/coriolis.png +0 -0
  91. roboticstoolbox/blocks/Icons/ctraj.png +0 -0
  92. roboticstoolbox/blocks/Icons/delta2tr.png +0 -0
  93. roboticstoolbox/blocks/Icons/diffsteer.png +0 -0
  94. roboticstoolbox/blocks/Icons/fdyn.png +0 -0
  95. roboticstoolbox/blocks/Icons/fdynx.png +0 -0
  96. roboticstoolbox/blocks/Icons/fkine.png +0 -0
  97. roboticstoolbox/blocks/Icons/gravload.png +0 -0
  98. roboticstoolbox/blocks/Icons/idyn.png +0 -0
  99. roboticstoolbox/blocks/Icons/idynx.png +0 -0
  100. roboticstoolbox/blocks/Icons/ikine.png +0 -0
  101. roboticstoolbox/blocks/Icons/inertia.png +0 -0
  102. roboticstoolbox/blocks/Icons/jacobian.png +0 -0
  103. roboticstoolbox/blocks/Icons/jtraj.png +0 -0
  104. roboticstoolbox/blocks/Icons/lspb.png +0 -0
  105. roboticstoolbox/blocks/Icons/multirotor.png +0 -0
  106. roboticstoolbox/blocks/Icons/multirotormixer.png +0 -0
  107. roboticstoolbox/blocks/Icons/multirotorplot.png +0 -0
  108. roboticstoolbox/blocks/Icons/point2tr.png +0 -0
  109. roboticstoolbox/blocks/Icons/tr2delta.png +0 -0
  110. roboticstoolbox/blocks/Icons/tr2t.png +0 -0
  111. roboticstoolbox/blocks/Icons/unicycle.png +0 -0
  112. roboticstoolbox/blocks/Icons/vehicleplot.png +0 -0
  113. roboticstoolbox/blocks/README.md +43 -0
  114. roboticstoolbox/blocks/__init__.py +6 -0
  115. roboticstoolbox/blocks/arm.py +1587 -0
  116. roboticstoolbox/blocks/mobile.py +500 -0
  117. roboticstoolbox/blocks/quad_model.py +132 -0
  118. roboticstoolbox/blocks/spatial.py +245 -0
  119. roboticstoolbox/blocks/uav.py +949 -0
  120. roboticstoolbox/core/Eigen/Cholesky +45 -0
  121. roboticstoolbox/core/Eigen/CholmodSupport +48 -0
  122. roboticstoolbox/core/Eigen/Core +384 -0
  123. roboticstoolbox/core/Eigen/Dense +7 -0
  124. roboticstoolbox/core/Eigen/Eigen +2 -0
  125. roboticstoolbox/core/Eigen/Eigenvalues +60 -0
  126. roboticstoolbox/core/Eigen/Geometry +59 -0
  127. roboticstoolbox/core/Eigen/Householder +29 -0
  128. roboticstoolbox/core/Eigen/IterativeLinearSolvers +48 -0
  129. roboticstoolbox/core/Eigen/Jacobi +32 -0
  130. roboticstoolbox/core/Eigen/KLUSupport +41 -0
  131. roboticstoolbox/core/Eigen/LU +47 -0
  132. roboticstoolbox/core/Eigen/MetisSupport +35 -0
  133. roboticstoolbox/core/Eigen/OrderingMethods +70 -0
  134. roboticstoolbox/core/Eigen/PaStiXSupport +49 -0
  135. roboticstoolbox/core/Eigen/PardisoSupport +35 -0
  136. roboticstoolbox/core/Eigen/QR +50 -0
  137. roboticstoolbox/core/Eigen/QtAlignedMalloc +39 -0
  138. roboticstoolbox/core/Eigen/SPQRSupport +34 -0
  139. roboticstoolbox/core/Eigen/SVD +50 -0
  140. roboticstoolbox/core/Eigen/Sparse +34 -0
  141. roboticstoolbox/core/Eigen/SparseCholesky +37 -0
  142. roboticstoolbox/core/Eigen/SparseCore +69 -0
  143. roboticstoolbox/core/Eigen/SparseLU +50 -0
  144. roboticstoolbox/core/Eigen/SparseQR +36 -0
  145. roboticstoolbox/core/Eigen/StdDeque +27 -0
  146. roboticstoolbox/core/Eigen/StdList +26 -0
  147. roboticstoolbox/core/Eigen/StdVector +27 -0
  148. roboticstoolbox/core/Eigen/SuperLUSupport +64 -0
  149. roboticstoolbox/core/Eigen/UmfPackSupport +40 -0
  150. roboticstoolbox/core/Eigen/src/Cholesky/LDLT.h +688 -0
  151. roboticstoolbox/core/Eigen/src/Cholesky/LLT.h +558 -0
  152. roboticstoolbox/core/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  153. roboticstoolbox/core/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  154. roboticstoolbox/core/Eigen/src/Core/ArithmeticSequence.h +413 -0
  155. roboticstoolbox/core/Eigen/src/Core/Array.h +417 -0
  156. roboticstoolbox/core/Eigen/src/Core/ArrayBase.h +226 -0
  157. roboticstoolbox/core/Eigen/src/Core/ArrayWrapper.h +209 -0
  158. roboticstoolbox/core/Eigen/src/Core/Assign.h +90 -0
  159. roboticstoolbox/core/Eigen/src/Core/AssignEvaluator.h +1010 -0
  160. roboticstoolbox/core/Eigen/src/Core/Assign_MKL.h +178 -0
  161. roboticstoolbox/core/Eigen/src/Core/BandMatrix.h +353 -0
  162. roboticstoolbox/core/Eigen/src/Core/Block.h +448 -0
  163. roboticstoolbox/core/Eigen/src/Core/BooleanRedux.h +162 -0
  164. roboticstoolbox/core/Eigen/src/Core/CommaInitializer.h +164 -0
  165. roboticstoolbox/core/Eigen/src/Core/ConditionEstimator.h +175 -0
  166. roboticstoolbox/core/Eigen/src/Core/CoreEvaluators.h +1741 -0
  167. roboticstoolbox/core/Eigen/src/Core/CoreIterators.h +132 -0
  168. roboticstoolbox/core/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  169. roboticstoolbox/core/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  170. roboticstoolbox/core/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  171. roboticstoolbox/core/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  172. roboticstoolbox/core/Eigen/src/Core/CwiseUnaryView.h +132 -0
  173. roboticstoolbox/core/Eigen/src/Core/DenseBase.h +701 -0
  174. roboticstoolbox/core/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  175. roboticstoolbox/core/Eigen/src/Core/DenseStorage.h +652 -0
  176. roboticstoolbox/core/Eigen/src/Core/Diagonal.h +258 -0
  177. roboticstoolbox/core/Eigen/src/Core/DiagonalMatrix.h +391 -0
  178. roboticstoolbox/core/Eigen/src/Core/DiagonalProduct.h +28 -0
  179. roboticstoolbox/core/Eigen/src/Core/Dot.h +318 -0
  180. roboticstoolbox/core/Eigen/src/Core/EigenBase.h +160 -0
  181. roboticstoolbox/core/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  182. roboticstoolbox/core/Eigen/src/Core/Fuzzy.h +155 -0
  183. roboticstoolbox/core/Eigen/src/Core/GeneralProduct.h +465 -0
  184. roboticstoolbox/core/Eigen/src/Core/GenericPacketMath.h +1040 -0
  185. roboticstoolbox/core/Eigen/src/Core/GlobalFunctions.h +194 -0
  186. roboticstoolbox/core/Eigen/src/Core/IO.h +258 -0
  187. roboticstoolbox/core/Eigen/src/Core/IndexedView.h +237 -0
  188. roboticstoolbox/core/Eigen/src/Core/Inverse.h +117 -0
  189. roboticstoolbox/core/Eigen/src/Core/Map.h +171 -0
  190. roboticstoolbox/core/Eigen/src/Core/MapBase.h +310 -0
  191. roboticstoolbox/core/Eigen/src/Core/MathFunctions.h +2057 -0
  192. roboticstoolbox/core/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  193. roboticstoolbox/core/Eigen/src/Core/Matrix.h +565 -0
  194. roboticstoolbox/core/Eigen/src/Core/MatrixBase.h +547 -0
  195. roboticstoolbox/core/Eigen/src/Core/NestByValue.h +85 -0
  196. roboticstoolbox/core/Eigen/src/Core/NoAlias.h +109 -0
  197. roboticstoolbox/core/Eigen/src/Core/NumTraits.h +335 -0
  198. roboticstoolbox/core/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  199. roboticstoolbox/core/Eigen/src/Core/PermutationMatrix.h +605 -0
  200. roboticstoolbox/core/Eigen/src/Core/PlainObjectBase.h +1128 -0
  201. roboticstoolbox/core/Eigen/src/Core/Product.h +191 -0
  202. roboticstoolbox/core/Eigen/src/Core/ProductEvaluators.h +1179 -0
  203. roboticstoolbox/core/Eigen/src/Core/Random.h +218 -0
  204. roboticstoolbox/core/Eigen/src/Core/Redux.h +515 -0
  205. roboticstoolbox/core/Eigen/src/Core/Ref.h +381 -0
  206. roboticstoolbox/core/Eigen/src/Core/Replicate.h +142 -0
  207. roboticstoolbox/core/Eigen/src/Core/Reshaped.h +454 -0
  208. roboticstoolbox/core/Eigen/src/Core/ReturnByValue.h +119 -0
  209. roboticstoolbox/core/Eigen/src/Core/Reverse.h +217 -0
  210. roboticstoolbox/core/Eigen/src/Core/Select.h +164 -0
  211. roboticstoolbox/core/Eigen/src/Core/SelfAdjointView.h +365 -0
  212. roboticstoolbox/core/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  213. roboticstoolbox/core/Eigen/src/Core/Solve.h +188 -0
  214. roboticstoolbox/core/Eigen/src/Core/SolveTriangular.h +235 -0
  215. roboticstoolbox/core/Eigen/src/Core/SolverBase.h +168 -0
  216. roboticstoolbox/core/Eigen/src/Core/StableNorm.h +251 -0
  217. roboticstoolbox/core/Eigen/src/Core/StlIterators.h +463 -0
  218. roboticstoolbox/core/Eigen/src/Core/Stride.h +116 -0
  219. roboticstoolbox/core/Eigen/src/Core/Swap.h +68 -0
  220. roboticstoolbox/core/Eigen/src/Core/Transpose.h +464 -0
  221. roboticstoolbox/core/Eigen/src/Core/Transpositions.h +386 -0
  222. roboticstoolbox/core/Eigen/src/Core/TriangularMatrix.h +1001 -0
  223. roboticstoolbox/core/Eigen/src/Core/VectorBlock.h +96 -0
  224. roboticstoolbox/core/Eigen/src/Core/VectorwiseOp.h +784 -0
  225. roboticstoolbox/core/Eigen/src/Core/Visitor.h +381 -0
  226. roboticstoolbox/core/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  227. roboticstoolbox/core/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  228. roboticstoolbox/core/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  229. roboticstoolbox/core/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  230. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  231. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  232. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  233. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  234. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  235. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  236. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  237. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  238. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  239. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  240. roboticstoolbox/core/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  241. roboticstoolbox/core/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  242. roboticstoolbox/core/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  243. roboticstoolbox/core/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  244. roboticstoolbox/core/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  245. roboticstoolbox/core/Eigen/src/Core/arch/Default/Half.h +942 -0
  246. roboticstoolbox/core/Eigen/src/Core/arch/Default/Settings.h +49 -0
  247. roboticstoolbox/core/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  248. roboticstoolbox/core/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  249. roboticstoolbox/core/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  250. roboticstoolbox/core/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  251. roboticstoolbox/core/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  252. roboticstoolbox/core/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  253. roboticstoolbox/core/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  254. roboticstoolbox/core/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  255. roboticstoolbox/core/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  256. roboticstoolbox/core/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  257. roboticstoolbox/core/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  258. roboticstoolbox/core/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  259. roboticstoolbox/core/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  260. roboticstoolbox/core/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  261. roboticstoolbox/core/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  262. roboticstoolbox/core/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  263. roboticstoolbox/core/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  264. roboticstoolbox/core/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  265. roboticstoolbox/core/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  266. roboticstoolbox/core/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  267. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  268. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  269. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  270. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  271. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  272. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  273. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  274. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  275. roboticstoolbox/core/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  276. roboticstoolbox/core/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  277. roboticstoolbox/core/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  278. roboticstoolbox/core/Eigen/src/Core/functors/StlFunctors.h +166 -0
  279. roboticstoolbox/core/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  280. roboticstoolbox/core/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  281. roboticstoolbox/core/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  282. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  283. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  284. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  285. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  286. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  287. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  288. roboticstoolbox/core/Eigen/src/Core/products/Parallelizer.h +180 -0
  289. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  290. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  291. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  292. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  293. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  294. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  295. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  296. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  297. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  298. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  299. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  300. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  301. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  302. roboticstoolbox/core/Eigen/src/Core/util/BlasUtil.h +583 -0
  303. roboticstoolbox/core/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  304. roboticstoolbox/core/Eigen/src/Core/util/Constants.h +563 -0
  305. roboticstoolbox/core/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  306. roboticstoolbox/core/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  307. roboticstoolbox/core/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  308. roboticstoolbox/core/Eigen/src/Core/util/IntegralConstant.h +272 -0
  309. roboticstoolbox/core/Eigen/src/Core/util/MKL_support.h +137 -0
  310. roboticstoolbox/core/Eigen/src/Core/util/Macros.h +1464 -0
  311. roboticstoolbox/core/Eigen/src/Core/util/Memory.h +1163 -0
  312. roboticstoolbox/core/Eigen/src/Core/util/Meta.h +812 -0
  313. roboticstoolbox/core/Eigen/src/Core/util/NonMPL2.h +3 -0
  314. roboticstoolbox/core/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  315. roboticstoolbox/core/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  316. roboticstoolbox/core/Eigen/src/Core/util/StaticAssert.h +221 -0
  317. roboticstoolbox/core/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  318. roboticstoolbox/core/Eigen/src/Core/util/XprHelper.h +856 -0
  319. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  320. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  321. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  322. roboticstoolbox/core/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  323. roboticstoolbox/core/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  324. roboticstoolbox/core/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  325. roboticstoolbox/core/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  326. roboticstoolbox/core/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  327. roboticstoolbox/core/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  328. roboticstoolbox/core/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  329. roboticstoolbox/core/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  330. roboticstoolbox/core/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  331. roboticstoolbox/core/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  332. roboticstoolbox/core/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  333. roboticstoolbox/core/Eigen/src/Geometry/AlignedBox.h +486 -0
  334. roboticstoolbox/core/Eigen/src/Geometry/AngleAxis.h +247 -0
  335. roboticstoolbox/core/Eigen/src/Geometry/EulerAngles.h +114 -0
  336. roboticstoolbox/core/Eigen/src/Geometry/Homogeneous.h +501 -0
  337. roboticstoolbox/core/Eigen/src/Geometry/Hyperplane.h +282 -0
  338. roboticstoolbox/core/Eigen/src/Geometry/OrthoMethods.h +235 -0
  339. roboticstoolbox/core/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  340. roboticstoolbox/core/Eigen/src/Geometry/Quaternion.h +870 -0
  341. roboticstoolbox/core/Eigen/src/Geometry/Rotation2D.h +199 -0
  342. roboticstoolbox/core/Eigen/src/Geometry/RotationBase.h +206 -0
  343. roboticstoolbox/core/Eigen/src/Geometry/Scaling.h +188 -0
  344. roboticstoolbox/core/Eigen/src/Geometry/Transform.h +1563 -0
  345. roboticstoolbox/core/Eigen/src/Geometry/Translation.h +202 -0
  346. roboticstoolbox/core/Eigen/src/Geometry/Umeyama.h +166 -0
  347. roboticstoolbox/core/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  348. roboticstoolbox/core/Eigen/src/Householder/BlockHouseholder.h +110 -0
  349. roboticstoolbox/core/Eigen/src/Householder/Householder.h +176 -0
  350. roboticstoolbox/core/Eigen/src/Householder/HouseholderSequence.h +545 -0
  351. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  352. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  353. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  354. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  355. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  356. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  357. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  358. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  359. roboticstoolbox/core/Eigen/src/Jacobi/Jacobi.h +483 -0
  360. roboticstoolbox/core/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  361. roboticstoolbox/core/Eigen/src/LU/Determinant.h +117 -0
  362. roboticstoolbox/core/Eigen/src/LU/FullPivLU.h +877 -0
  363. roboticstoolbox/core/Eigen/src/LU/InverseImpl.h +432 -0
  364. roboticstoolbox/core/Eigen/src/LU/PartialPivLU.h +624 -0
  365. roboticstoolbox/core/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  366. roboticstoolbox/core/Eigen/src/LU/arch/InverseSize4.h +351 -0
  367. roboticstoolbox/core/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  368. roboticstoolbox/core/Eigen/src/OrderingMethods/Amd.h +435 -0
  369. roboticstoolbox/core/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  370. roboticstoolbox/core/Eigen/src/OrderingMethods/Ordering.h +153 -0
  371. roboticstoolbox/core/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  372. roboticstoolbox/core/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  373. roboticstoolbox/core/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  374. roboticstoolbox/core/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  375. roboticstoolbox/core/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  376. roboticstoolbox/core/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  377. roboticstoolbox/core/Eigen/src/QR/HouseholderQR.h +434 -0
  378. roboticstoolbox/core/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  379. roboticstoolbox/core/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  380. roboticstoolbox/core/Eigen/src/SVD/BDCSVD.h +1366 -0
  381. roboticstoolbox/core/Eigen/src/SVD/JacobiSVD.h +812 -0
  382. roboticstoolbox/core/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  383. roboticstoolbox/core/Eigen/src/SVD/SVDBase.h +376 -0
  384. roboticstoolbox/core/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  385. roboticstoolbox/core/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  386. roboticstoolbox/core/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  387. roboticstoolbox/core/Eigen/src/SparseCore/AmbiVector.h +378 -0
  388. roboticstoolbox/core/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  389. roboticstoolbox/core/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  390. roboticstoolbox/core/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  391. roboticstoolbox/core/Eigen/src/SparseCore/SparseAssign.h +270 -0
  392. roboticstoolbox/core/Eigen/src/SparseCore/SparseBlock.h +571 -0
  393. roboticstoolbox/core/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  394. roboticstoolbox/core/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  395. roboticstoolbox/core/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  396. roboticstoolbox/core/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  397. roboticstoolbox/core/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  398. roboticstoolbox/core/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  399. roboticstoolbox/core/Eigen/src/SparseCore/SparseDot.h +98 -0
  400. roboticstoolbox/core/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  401. roboticstoolbox/core/Eigen/src/SparseCore/SparseMap.h +305 -0
  402. roboticstoolbox/core/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  403. roboticstoolbox/core/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  404. roboticstoolbox/core/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  405. roboticstoolbox/core/Eigen/src/SparseCore/SparseProduct.h +181 -0
  406. roboticstoolbox/core/Eigen/src/SparseCore/SparseRedux.h +49 -0
  407. roboticstoolbox/core/Eigen/src/SparseCore/SparseRef.h +397 -0
  408. roboticstoolbox/core/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  409. roboticstoolbox/core/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  410. roboticstoolbox/core/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  411. roboticstoolbox/core/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  412. roboticstoolbox/core/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  413. roboticstoolbox/core/Eigen/src/SparseCore/SparseUtil.h +186 -0
  414. roboticstoolbox/core/Eigen/src/SparseCore/SparseVector.h +478 -0
  415. roboticstoolbox/core/Eigen/src/SparseCore/SparseView.h +254 -0
  416. roboticstoolbox/core/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  417. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU.h +923 -0
  418. roboticstoolbox/core/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  419. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  420. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  421. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  422. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  423. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  424. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  425. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  426. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  427. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  428. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  429. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  430. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  431. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  432. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  433. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  434. roboticstoolbox/core/Eigen/src/SparseQR/SparseQR.h +758 -0
  435. roboticstoolbox/core/Eigen/src/StlSupport/StdDeque.h +116 -0
  436. roboticstoolbox/core/Eigen/src/StlSupport/StdList.h +106 -0
  437. roboticstoolbox/core/Eigen/src/StlSupport/StdVector.h +131 -0
  438. roboticstoolbox/core/Eigen/src/StlSupport/details.h +84 -0
  439. roboticstoolbox/core/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  440. roboticstoolbox/core/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  441. roboticstoolbox/core/Eigen/src/misc/Image.h +82 -0
  442. roboticstoolbox/core/Eigen/src/misc/Kernel.h +79 -0
  443. roboticstoolbox/core/Eigen/src/misc/RealSvd2x2.h +55 -0
  444. roboticstoolbox/core/Eigen/src/misc/blas.h +440 -0
  445. roboticstoolbox/core/Eigen/src/misc/lapack.h +152 -0
  446. roboticstoolbox/core/Eigen/src/misc/lapacke.h +16292 -0
  447. roboticstoolbox/core/Eigen/src/misc/lapacke_mangling.h +17 -0
  448. roboticstoolbox/core/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  449. roboticstoolbox/core/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  450. roboticstoolbox/core/Eigen/src/plugins/BlockMethods.h +1442 -0
  451. roboticstoolbox/core/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  452. roboticstoolbox/core/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  453. roboticstoolbox/core/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  454. roboticstoolbox/core/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  455. roboticstoolbox/core/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  456. roboticstoolbox/core/Eigen/src/plugins/ReshapedMethods.h +149 -0
  457. roboticstoolbox/core/fknm.cpp +1557 -0
  458. roboticstoolbox/core/fknm.h +55 -0
  459. roboticstoolbox/core/frne.c +351 -0
  460. roboticstoolbox/core/frne.h +96 -0
  461. roboticstoolbox/core/ik.cpp +301 -0
  462. roboticstoolbox/core/ik.h +59 -0
  463. roboticstoolbox/core/linalg.cpp +316 -0
  464. roboticstoolbox/core/linalg.h +64 -0
  465. roboticstoolbox/core/methods.cpp +372 -0
  466. roboticstoolbox/core/methods.h +32 -0
  467. roboticstoolbox/core/ne.c +493 -0
  468. roboticstoolbox/core/structs.cpp +24 -0
  469. roboticstoolbox/core/structs.h +62 -0
  470. roboticstoolbox/core/vmath.c +163 -0
  471. roboticstoolbox/core/vmath.h +32 -0
  472. roboticstoolbox/fknm.cp312-win_amd64.pyd +0 -0
  473. roboticstoolbox/frne.cp312-win_amd64.pyd +0 -0
  474. roboticstoolbox/mobile/Animations.py +485 -0
  475. roboticstoolbox/mobile/Bug2.py +455 -0
  476. roboticstoolbox/mobile/CurvaturePolyPlanner.py +179 -0
  477. roboticstoolbox/mobile/DistanceTransformPlanner.py +395 -0
  478. roboticstoolbox/mobile/DstarPlanner.py +591 -0
  479. roboticstoolbox/mobile/DubinsPlanner.py +474 -0
  480. roboticstoolbox/mobile/EKF.py +1617 -0
  481. roboticstoolbox/mobile/LatticePlanner.py +419 -0
  482. roboticstoolbox/mobile/OccGrid.py +613 -0
  483. roboticstoolbox/mobile/PRMPlanner.py +348 -0
  484. roboticstoolbox/mobile/ParticleFilter.py +706 -0
  485. roboticstoolbox/mobile/PlannerBase.py +1009 -0
  486. roboticstoolbox/mobile/PoseGraph.py +544 -0
  487. roboticstoolbox/mobile/QuinticPolyPlanner.py +349 -0
  488. roboticstoolbox/mobile/RRTPlanner.py +359 -0
  489. roboticstoolbox/mobile/ReedsSheppPlanner.py +545 -0
  490. roboticstoolbox/mobile/Vehicle.py +1909 -0
  491. roboticstoolbox/mobile/__init__.py +193 -0
  492. roboticstoolbox/mobile/drivers.py +390 -0
  493. roboticstoolbox/mobile/landmarkmap.py +181 -0
  494. roboticstoolbox/mobile/sensors.py +771 -0
  495. roboticstoolbox/models/DH/AL5D.py +121 -0
  496. roboticstoolbox/models/DH/Ball.py +87 -0
  497. roboticstoolbox/models/DH/Baxter.py +91 -0
  498. roboticstoolbox/models/DH/Cobra600.py +63 -0
  499. roboticstoolbox/models/DH/Coil.py +80 -0
  500. roboticstoolbox/models/DH/Hyper.py +83 -0
  501. roboticstoolbox/models/DH/Hyper3d.py +85 -0
  502. roboticstoolbox/models/DH/IRB140.py +159 -0
  503. roboticstoolbox/models/DH/Jaco.py +102 -0
  504. roboticstoolbox/models/DH/KR5.py +112 -0
  505. roboticstoolbox/models/DH/LWR4.py +85 -0
  506. roboticstoolbox/models/DH/Mico.py +102 -0
  507. roboticstoolbox/models/DH/Orion5.py +91 -0
  508. roboticstoolbox/models/DH/P8.py +80 -0
  509. roboticstoolbox/models/DH/Panda.py +178 -0
  510. roboticstoolbox/models/DH/Planar2.py +69 -0
  511. roboticstoolbox/models/DH/Planar3.py +51 -0
  512. roboticstoolbox/models/DH/Puma560.py +326 -0
  513. roboticstoolbox/models/DH/README.md +216 -0
  514. roboticstoolbox/models/DH/Sawyer.py +85 -0
  515. roboticstoolbox/models/DH/Stanford.py +147 -0
  516. roboticstoolbox/models/DH/TwoLink.py +109 -0
  517. roboticstoolbox/models/DH/UR10.py +124 -0
  518. roboticstoolbox/models/DH/UR3.py +98 -0
  519. roboticstoolbox/models/DH/UR5.py +98 -0
  520. roboticstoolbox/models/DH/Uprighttl.py +24 -0
  521. roboticstoolbox/models/DH/__init__.py +52 -0
  522. roboticstoolbox/models/ETS/Frankie.py +90 -0
  523. roboticstoolbox/models/ETS/GenericSeven.py +54 -0
  524. roboticstoolbox/models/ETS/Omni.py +74 -0
  525. roboticstoolbox/models/ETS/Panda.py +69 -0
  526. roboticstoolbox/models/ETS/Planar2.py +49 -0
  527. roboticstoolbox/models/ETS/Planar_Y.py +65 -0
  528. roboticstoolbox/models/ETS/Puma560.py +69 -0
  529. roboticstoolbox/models/ETS/XYPanda.py +84 -0
  530. roboticstoolbox/models/ETS/__init__.py +20 -0
  531. roboticstoolbox/models/README.md +9 -0
  532. roboticstoolbox/models/URDF/AL5D.py +54 -0
  533. roboticstoolbox/models/URDF/Fetch.py +70 -0
  534. roboticstoolbox/models/URDF/FetchCamera.py +71 -0
  535. roboticstoolbox/models/URDF/Frankie.py +75 -0
  536. roboticstoolbox/models/URDF/FrankieOmni.py +94 -0
  537. roboticstoolbox/models/URDF/KinovaGen3.py +71 -0
  538. roboticstoolbox/models/URDF/LBR.py +59 -0
  539. roboticstoolbox/models/URDF/Mico.py +68 -0
  540. roboticstoolbox/models/URDF/PR2.py +64 -0
  541. roboticstoolbox/models/URDF/Panda.py +67 -0
  542. roboticstoolbox/models/URDF/Puma560.py +97 -0
  543. roboticstoolbox/models/URDF/UR10.py +53 -0
  544. roboticstoolbox/models/URDF/UR3.py +53 -0
  545. roboticstoolbox/models/URDF/UR5.py +74 -0
  546. roboticstoolbox/models/URDF/Valkyrie.py +84 -0
  547. roboticstoolbox/models/URDF/YuMi.py +109 -0
  548. roboticstoolbox/models/URDF/__init__.py +53 -0
  549. roboticstoolbox/models/URDF/px100.py +56 -0
  550. roboticstoolbox/models/URDF/px150.py +56 -0
  551. roboticstoolbox/models/URDF/rx150.py +56 -0
  552. roboticstoolbox/models/URDF/rx200.py +56 -0
  553. roboticstoolbox/models/URDF/vx300.py +56 -0
  554. roboticstoolbox/models/URDF/vx300s.py +56 -0
  555. roboticstoolbox/models/URDF/wx200.py +56 -0
  556. roboticstoolbox/models/URDF/wx250.py +56 -0
  557. roboticstoolbox/models/URDF/wx250s.py +56 -0
  558. roboticstoolbox/models/__init__.py +7 -0
  559. roboticstoolbox/models/list.py +119 -0
  560. roboticstoolbox/robot/BaseRobot.py +3133 -0
  561. roboticstoolbox/robot/DHFactor.py +522 -0
  562. roboticstoolbox/robot/DHLink.py +981 -0
  563. roboticstoolbox/robot/DHRobot.py +2520 -0
  564. roboticstoolbox/robot/Dynamics.py +1620 -0
  565. roboticstoolbox/robot/ELink.py +23 -0
  566. roboticstoolbox/robot/ERobot.py +25 -0
  567. roboticstoolbox/robot/ET.py +1097 -0
  568. roboticstoolbox/robot/ETS.py +3542 -0
  569. roboticstoolbox/robot/Gripper.py +282 -0
  570. roboticstoolbox/robot/IK.py +1522 -0
  571. roboticstoolbox/robot/Link.py +1698 -0
  572. roboticstoolbox/robot/PoERobot.py +348 -0
  573. roboticstoolbox/robot/Robot.py +2100 -0
  574. roboticstoolbox/robot/RobotKinematics.py +1725 -0
  575. roboticstoolbox/robot/RobotProto.py +92 -0
  576. roboticstoolbox/robot/__init__.py +54 -0
  577. roboticstoolbox/tools/DHFactor.py +375 -0
  578. roboticstoolbox/tools/Ticker.py +53 -0
  579. roboticstoolbox/tools/__init__.py +54 -0
  580. roboticstoolbox/tools/data.py +187 -0
  581. roboticstoolbox/tools/jsingu.py +51 -0
  582. roboticstoolbox/tools/null.py +48 -0
  583. roboticstoolbox/tools/numerical.py +96 -0
  584. roboticstoolbox/tools/p_servo.py +106 -0
  585. roboticstoolbox/tools/params.py +11 -0
  586. roboticstoolbox/tools/plot.py +109 -0
  587. roboticstoolbox/tools/trajectory.py +1152 -0
  588. roboticstoolbox/tools/types.py +13 -0
  589. roboticstoolbox/tools/urdf/__init__.py +45 -0
  590. roboticstoolbox/tools/urdf/tests/data/ur5.urdf +341 -0
  591. roboticstoolbox/tools/urdf/tests/test_urdf.py +116 -0
  592. roboticstoolbox/tools/urdf/urdf.py +1976 -0
  593. roboticstoolbox/tools/urdf/utils.py +50 -0
  594. roboticstoolbox/tools/xacro/__init__.py +1148 -0
  595. roboticstoolbox/tools/xacro/cli.py +128 -0
  596. roboticstoolbox/tools/xacro/color.py +66 -0
  597. roboticstoolbox/tools/xacro/tests/CMakeLists.txt +4 -0
  598. roboticstoolbox/tools/xacro/tests/broken.xacro +1 -0
  599. roboticstoolbox/tools/xacro/tests/emoji.xacro +5 -0
  600. roboticstoolbox/tools/xacro/tests/include1.xacro +4 -0
  601. roboticstoolbox/tools/xacro/tests/include1.xml +1 -0
  602. roboticstoolbox/tools/xacro/tests/include2.xacro +4 -0
  603. roboticstoolbox/tools/xacro/tests/include2.xml +1 -0
  604. roboticstoolbox/tools/xacro/tests/robots/README +4 -0
  605. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.gazebo.xacro +59 -0
  606. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.transmission.xacro +24 -0
  607. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.urdf.xacro +264 -0
  608. roboticstoolbox/tools/xacro/tests/robots/pr2/common.xacro +71 -0
  609. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.gazebo.xacro +36 -0
  610. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.transmission.xacro +20 -0
  611. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.urdf.xacro +130 -0
  612. roboticstoolbox/tools/xacro/tests/robots/pr2/gazebo/gazebo.urdf.xacro +24 -0
  613. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.gazebo.xacro +288 -0
  614. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.transmission.xacro +50 -0
  615. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.urdf.xacro +374 -0
  616. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.gazebo.xacro +16 -0
  617. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.transmission.xacro +34 -0
  618. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.urdf.xacro +147 -0
  619. roboticstoolbox/tools/xacro/tests/robots/pr2/materials.urdf.xacro +52 -0
  620. roboticstoolbox/tools/xacro/tests/robots/pr2/pr2.urdf.xacro +157 -0
  621. roboticstoolbox/tools/xacro/tests/robots/pr2/pr2_1.11.4.xml +3781 -0
  622. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/double_stereo_camera.gazebo.xacro +16 -0
  623. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/double_stereo_camera.urdf.xacro +61 -0
  624. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/head_sensor_package.gazebo.xacro +20 -0
  625. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/head_sensor_package.urdf.xacro +63 -0
  626. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/hokuyo_lx30_laser.gazebo.xacro +39 -0
  627. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/hokuyo_lx30_laser.urdf.xacro +27 -0
  628. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_camera.gazebo.xacro +87 -0
  629. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_camera.urdf.xacro +55 -0
  630. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_prosilica_camera.gazebo.xacro +193 -0
  631. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_prosilica_camera.urdf.xacro +181 -0
  632. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/microstrain_3dmgx2_imu.gazebo.xacro +20 -0
  633. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/microstrain_3dmgx2_imu.urdf.xacro +25 -0
  634. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/projector_wg6802418.gazebo.xacro +31 -0
  635. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/projector_wg6802418.urdf.xacro +42 -0
  636. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/prosilica_gc2450_camera.gazebo.xacro +43 -0
  637. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/prosilica_gc2450_camera.urdf.xacro +49 -0
  638. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/stereo_camera.gazebo.xacro +23 -0
  639. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/stereo_camera.urdf.xacro +71 -0
  640. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/wge100_camera.gazebo.xacro +46 -0
  641. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/wge100_camera.urdf.xacro +47 -0
  642. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.gazebo.xacro +40 -0
  643. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.transmission.xacro +35 -0
  644. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.urdf.xacro +167 -0
  645. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.gazebo.xacro +11 -0
  646. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.transmission.xacro +14 -0
  647. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.urdf.xacro +60 -0
  648. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.gazebo.xacro +37 -0
  649. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.transmission.xacro +22 -0
  650. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.urdf.xacro +122 -0
  651. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.gazebo.xacro +39 -0
  652. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.transmission.xacro +28 -0
  653. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.urdf.xacro +173 -0
  654. roboticstoolbox/tools/xacro/tests/settings.yaml +9 -0
  655. roboticstoolbox/tools/xacro/tests/subdir/foo.xacro +3 -0
  656. roboticstoolbox/tools/xacro/tests/subdir/include-recursive.xacro +5 -0
  657. roboticstoolbox/tools/xacro/tests/subdir/include1.xml +1 -0
  658. roboticstoolbox/tools/xacro/tests/test_xacro.py +1418 -0
  659. roboticstoolbox/tools/xacro/xmlutils.py +152 -0
  660. roboticstoolbox_python-1.3.0.dist-info/METADATA +552 -0
  661. roboticstoolbox_python-1.3.0.dist-info/RECORD +673 -0
  662. roboticstoolbox_python-1.3.0.dist-info/WHEEL +5 -0
  663. roboticstoolbox_python-1.3.0.dist-info/entry_points.txt +6 -0
  664. roboticstoolbox_python-1.3.0.dist-info/licenses/LICENSE +21 -0
  665. spatialgeometry/__init__.py +32 -0
  666. spatialgeometry/geom/CollisionShape.py +419 -0
  667. spatialgeometry/geom/SceneGroup.py +26 -0
  668. spatialgeometry/geom/SceneNode.py +315 -0
  669. spatialgeometry/geom/Shape.py +420 -0
  670. spatialgeometry/geom/__init__.py +26 -0
  671. spatialgeometry/scene.py +107 -0
  672. spatialgeometry/tools/__init__.py +0 -0
  673. spatialgeometry/tools/stdout_supress.py +302 -0
@@ -0,0 +1,3542 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ @author: Jesse Haviland
5
+ @author: Peter Corke
6
+ """
7
+
8
+ from __future__ import annotations
9
+ from collections import UserList
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 import rtb_get_param
26
+ from roboticstoolbox.robot.IK import IK_GN, IK_LM, IK_NR, IK_QP
27
+
28
+ from roboticstoolbox.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.robot.ET import ET, ET2, BaseET
41
+ from typing import Union, overload, List, Set, Tuple, TypeVar
42
+ from typing_extensions import Literal as L
43
+ from sys import version_info
44
+ from roboticstoolbox.tools.types import ArrayLike, NDArray
45
+
46
+ py_ver = version_info
47
+
48
+ if version_info >= (3, 9):
49
+ from functools import cached_property
50
+
51
+ c_property = cached_property
52
+ else: # pragma: nocover
53
+ c_property = property
54
+
55
+ T = TypeVar("T", bound="BaseETS")
56
+
57
+
58
+ class BaseETS(UserList):
59
+ def __init__(self, *args):
60
+ super().__init__(*args)
61
+
62
+ def _update_internals(self):
63
+ self._m = len(self.data)
64
+ self._n = len([True for et in self.data if et.isjoint])
65
+ self._fknm = ETS_init(
66
+ [et.fknm for et in self.data],
67
+ self._n,
68
+ self._m,
69
+ )
70
+ # self._fknm = [et.fknm for et in self.data]
71
+
72
+ def __str__(self, q: Union[str, None] = None):
73
+ """
74
+ Pretty prints the ETS
75
+
76
+ ``q`` controls how the joint variables are displayed:
77
+
78
+ - None, format depends on number of joint variables
79
+ - one, display joint variable as q
80
+ - more, display joint variables as q0, q1, ...
81
+ - if a joint index was provided, use this value
82
+ - "", display all joint variables as empty parentheses ``()``
83
+ - "θ", display all joint variables as ``(θ)``
84
+ - format string with passed joint variables ``(j, j+1)``, so "θ{0}"
85
+ would display joint variables as θ0, θ1, ... while "θ{1}" would
86
+ display joint variables as θ1, θ2, ... ``j`` is either the joint
87
+ index, if provided, otherwise a sequential value.
88
+
89
+ Parameters
90
+ ----------
91
+ q
92
+ control how joint variables are displayed
93
+
94
+ Returns
95
+ -------
96
+ str
97
+ Pretty printed ETS
98
+
99
+ Examples
100
+ --------
101
+ .. runblock:: pycon
102
+ >>> from roboticstoolbox import ET
103
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz()
104
+ >>> print(e[:2])
105
+ >>> print(e)
106
+ >>> print(e.__str__(""))
107
+ >>> print(e.__str__("θ{0}")) # numbering from 0
108
+ >>> print(e.__str__("θ{1}")) # numbering from 1
109
+ >>> # explicit joint indices
110
+ >>> e = ET.Rz(jindex=3) * ET.tx(1) * ET.Rz(jindex=4)
111
+ >>> print(e)
112
+ >>> print(e.__str__("θ{0}"))
113
+
114
+ Angular parameters are converted to degrees, except if they
115
+ are symbolic.
116
+
117
+ .. runblock:: pycon
118
+ >>> from roboticstoolbox import ET
119
+ >>> from spatialmath.base import symbol
120
+ >>> theta, d = symbol('theta, d')
121
+ >>> e = ET.Rx(theta) * ET.tx(2) * ET.Rx(45, 'deg') * ET.Ry(0.2) * ET.ty(d)
122
+ >>> str(e)
123
+
124
+ """
125
+
126
+ es = []
127
+ j = 0
128
+ c = 0
129
+ s = None
130
+ unicode = rtb_get_param("unicode")
131
+
132
+ # An empty SE3
133
+ if len(self.data) == 0:
134
+ return "SE3()"
135
+
136
+ if q is None:
137
+ if len(self.joints()) > 1:
138
+ q = "q{0}"
139
+ else:
140
+ q = "q"
141
+
142
+ # For et in the object, display it, data comes from properties
143
+ # which come from the named tuple
144
+ for et in self.data:
145
+ if et.isjoint:
146
+ if q is not None:
147
+ if et.jindex is None: # pragma: nocover this is no longer possible
148
+ _j = j
149
+ else:
150
+ _j = et.jindex
151
+ qvar = q.format( # lgtm [py/str-format/surplus-argument] # noqa
152
+ _j, _j + 1
153
+ )
154
+ # else:
155
+ # qvar = ""
156
+
157
+ if et.isflip:
158
+ s = f"{et.axis}(-{qvar})"
159
+ else:
160
+ s = f"{et.axis}({qvar})"
161
+ j += 1
162
+
163
+ elif et.isrotation:
164
+ if issymbol(et.eta):
165
+ s = f"{et.axis}({et.eta})"
166
+ else:
167
+ s = f"{et.axis}({et.eta * 180 / np.pi:.4g}°)"
168
+
169
+ elif et.istranslation:
170
+ try:
171
+ s = f"{et.axis}({et.eta:.4g})"
172
+ except TypeError: # pragma: nocover
173
+ s = f"{et.axis}({et.eta})"
174
+
175
+ elif not et.iselementary:
176
+ s = str(et)
177
+ c += 1
178
+
179
+ es.append(s)
180
+
181
+ if unicode:
182
+ return " \u2295 ".join(es)
183
+ else: # pragma: nocover
184
+ return " * ".join(es)
185
+
186
+ def _repr_pretty_(self, p, cycle):
187
+ """
188
+ Pretty string for IPython
189
+
190
+ Print stringified version when variable is displayed in IPython, ie. on
191
+ a line by itself.
192
+
193
+ Parameters
194
+ ----------
195
+ p
196
+ pretty printer handle (ignored)
197
+ cycle
198
+ pretty printer flag (ignored)
199
+
200
+ Examples
201
+ --------
202
+ In [1]: e
203
+ Out [1]: R(q0) ⊕ tx(1) ⊕ R(q1) ⊕ tx(1)
204
+
205
+ """
206
+
207
+ print(self.__str__()) # pragma: nocover
208
+
209
+ def joint_idx(self) -> List[int]:
210
+ """
211
+ Get index of joint transforms
212
+
213
+ Returns
214
+ -------
215
+ joint_idx
216
+ indices of transforms that are joints
217
+
218
+ Examples
219
+ --------
220
+ .. runblock:: pycon
221
+ >>> from roboticstoolbox import ET
222
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
223
+ >>> e.joint_idx()
224
+
225
+ """
226
+
227
+ return np.where([e.isjoint for e in self])[0] # type: ignore
228
+
229
+ def joints(self) -> List[ET]:
230
+ """
231
+ Get a list of the variable ETs with this ETS
232
+
233
+ Returns
234
+ -------
235
+ joints
236
+ list of ETs that are joints
237
+
238
+ Examples
239
+ --------
240
+ .. runblock:: pycon
241
+ >>> from roboticstoolbox import ET
242
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
243
+ >>> e.joints()
244
+
245
+ """
246
+
247
+ return [e for e in self if e.isjoint]
248
+
249
+ def jindex_set(self) -> Set[int]: #
250
+ """
251
+ Get set of joint indices
252
+
253
+ Returns
254
+ -------
255
+ jindex_set
256
+ set of unique joint indices
257
+
258
+ Examples
259
+ --------
260
+ .. runblock:: pycon
261
+ >>> from roboticstoolbox import ET
262
+ >>> e = ET.Rz(jindex=1) * ET.tx(jindex=2) * ET.Rz(jindex=1) * ET.tx(1)
263
+ >>> e.jointset()
264
+
265
+ """
266
+
267
+ return set([self[j].jindex for j in self.joint_idx()]) # type: ignore
268
+
269
+ @c_property
270
+ def jindices(self) -> NDArray:
271
+ """
272
+ Get an array of joint indices
273
+
274
+ Returns
275
+ -------
276
+ jindices
277
+ array of unique joint indices
278
+
279
+ Examples
280
+ --------
281
+ .. runblock:: pycon
282
+ >>> from roboticstoolbox import ET
283
+ >>> e = ET.Rz(jindex=1) * ET.tx(jindex=2) * ET.Rz(jindex=1) * ET.tx(1)
284
+ >>> e.jointset()
285
+
286
+ """
287
+
288
+ return np.array([j.jindex for j in self.joints()]) # type: ignore
289
+
290
+ @property
291
+ def qlim(self):
292
+ r"""
293
+ Get/Set Joint limits
294
+
295
+ Limits are extracted from the link objects. If joints limits are
296
+ not set for:
297
+
298
+ - a revolute joint [-𝜋. 𝜋] is returned
299
+ - a prismatic joint an exception is raised
300
+
301
+ Parameters
302
+ ----------
303
+ new_qlim
304
+ An ndarray(2, n) of the new joint limits to set
305
+
306
+ Returns
307
+ -------
308
+ :return: Array of joint limit values
309
+ :rtype: ndarray(2,n)
310
+
311
+ Raises
312
+ ------
313
+ ValueError
314
+ unset limits for a prismatic joint
315
+
316
+ Examples
317
+ --------
318
+ .. runblock:: pycon
319
+ >>> import roboticstoolbox as rtb
320
+ >>> robot = rtb.models.DH.Puma560()
321
+ >>> robot.qlim
322
+
323
+ """
324
+
325
+ limits = np.zeros((2, self.n))
326
+
327
+ for i, et in enumerate(self.joints()):
328
+ if et.isrotation:
329
+ if et.qlim is None:
330
+ v = [-np.pi, np.pi]
331
+ else:
332
+ v = et.qlim
333
+ elif et.istranslation:
334
+ if et.qlim is None:
335
+ raise ValueError("undefined prismatic joint limit")
336
+ else:
337
+ v = et.qlim
338
+ else:
339
+ raise ValueError("Undefined Joint Type") # pragma: nocover
340
+ limits[:, i] = v
341
+
342
+ return limits
343
+
344
+ @qlim.setter
345
+ def qlim(self, new_qlim: ArrayLike):
346
+ new_qlim = np.array(new_qlim)
347
+
348
+ if new_qlim.shape == (2,) and self.n == 1:
349
+ new_qlim = new_qlim.reshape(2, 1)
350
+
351
+ if new_qlim.shape != (2, self.n):
352
+ raise ValueError("new_qlim must be of shape (2, n)")
353
+
354
+ for j, i in enumerate(self.joint_idx()):
355
+ et = self[i]
356
+ et.qlim = new_qlim[:, j]
357
+
358
+ self[i] = et
359
+
360
+ self._update_internals()
361
+
362
+ @property
363
+ def structure(self) -> str:
364
+ """
365
+ Joint structure string
366
+
367
+ A string comprising the characters 'R' or 'P' which indicate the types
368
+ of joints in order from left to right.
369
+
370
+ Returns
371
+ -------
372
+ structure
373
+ A string indicating the joint types
374
+
375
+
376
+
377
+ Examples
378
+ --------
379
+ .. runblock:: pycon
380
+ >>> from roboticstoolbox import ET
381
+ >>> e = ET.tz() * ET.tx(1) * ET.Rz() * ET.tx(1)
382
+ >>> e.structure
383
+
384
+ """
385
+
386
+ return "".join(
387
+ ["R" if self.data[i].isrotation else "P" for i in self.joint_idx()]
388
+ )
389
+
390
+ @property
391
+ def n(self) -> int:
392
+ """
393
+ Number of joints
394
+
395
+ Counts the number of joints in the ETS.
396
+
397
+ Returns
398
+ -------
399
+ n
400
+ the number of joints in the ETS
401
+
402
+ Examples
403
+ --------
404
+ .. runblock:: pycon
405
+ >>> from roboticstoolbox import ET
406
+ >>> e = ET.Rx() * ET.tx(1) * ET.tz()
407
+ >>> e.n
408
+
409
+ See Also
410
+ --------
411
+ :func:`joints`
412
+
413
+ """
414
+
415
+ return self._n
416
+
417
+ @property
418
+ def m(self) -> int:
419
+ """
420
+ Number of transforms
421
+
422
+ Counts the number of transforms in the ETS.
423
+
424
+ Returns
425
+ -------
426
+ m
427
+ the number of transforms in the ETS
428
+
429
+ Examples
430
+ --------
431
+ .. runblock:: pycon
432
+ >>> from roboticstoolbox import ET
433
+ >>> e = ET.Rx() * ET.tx(1) * ET.tz()
434
+ >>> e.m
435
+
436
+ """
437
+
438
+ return self._m
439
+
440
+ @overload
441
+ def data(self: "ETS") -> List[ET]: ... # pragma: nocover
442
+
443
+ @overload
444
+ def data(self: "ETS2") -> List[ET2]: ... # pragma: nocover
445
+
446
+ @property
447
+ def data(self):
448
+ return self._data
449
+
450
+ @data.setter
451
+ @overload
452
+ def data(self: "ETS", new_data: List[ET]): ... # pragma: nocover
453
+
454
+ @data.setter
455
+ @overload
456
+ def data(self: "ETS", new_data: List[ET2]): ... # pragma: nocover
457
+
458
+ @data.setter
459
+ def data(self, new_data):
460
+ self._data = new_data
461
+
462
+ @overload
463
+ def pop(self: "ETS", i: int = -1) -> ET: ... # pragma: nocover
464
+
465
+ @overload
466
+ def pop(self: "ETS2", i: int = -1) -> ET2: ... # pragma: nocover
467
+
468
+ def pop(self, i=-1):
469
+ """
470
+ Pop value
471
+
472
+ Removes a value from the value list and returns it. The original
473
+ instance is modified.
474
+
475
+ Parameters
476
+ ----------
477
+ i
478
+ item in the list to pop, default is last
479
+
480
+ Returns
481
+ -------
482
+ pop
483
+ the popped value
484
+
485
+ Raises
486
+ ------
487
+ IndexError
488
+ if there are no values to pop
489
+
490
+ Examples
491
+ --------
492
+ .. runblock:: pycon
493
+ >>> from roboticstoolbox import ET
494
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
495
+ >>> tail = e.pop()
496
+ >>> tail
497
+ >>> e
498
+
499
+ """
500
+
501
+ item = super().pop(i)
502
+ self._update_internals()
503
+ return item
504
+
505
+ @overload
506
+ def split(self: "ETS") -> List["ETS"]: ... # pragma: nocover
507
+
508
+ @overload
509
+ def split(self: "ETS2") -> List["ETS2"]: ... # pragma: nocover
510
+
511
+ def split(self):
512
+ """
513
+ Split ETS into link segments
514
+
515
+ Returns
516
+ -------
517
+ split
518
+ a list of ETS, each one, apart from the last,
519
+ ends with a variable ET.
520
+
521
+ """
522
+
523
+ segments = []
524
+ start = 0
525
+
526
+ for j, k in enumerate(self.joint_idx()):
527
+ ets_j = self.data[start : k + 1]
528
+ start = k + 1
529
+ segments.append(ets_j)
530
+
531
+ tail = self.data[start:]
532
+
533
+ if isinstance(tail, list):
534
+ tail_len = len(tail)
535
+ elif tail is not None: # pragma: nocover
536
+ tail_len = 1
537
+ else: # pragma: nocover
538
+ tail_len = 0
539
+
540
+ if tail_len > 0:
541
+ segments.append(tail)
542
+
543
+ return segments
544
+
545
+ def inv(self: T) -> T:
546
+ r"""
547
+ Inverse of ETS
548
+
549
+ The inverse of a given ETS. It is computed as the inverse of the
550
+ individual ETs in the reverse order.
551
+
552
+ .. math::
553
+
554
+ (\mathbf{E}_0, \mathbf{E}_1 \cdots \mathbf{E}_{n-1} )^{-1} = (\mathbf{E}_{n-1}^{-1}, \mathbf{E}_{n-2}^{-1} \cdots \mathbf{E}_0^{-1}{n-1} )
555
+
556
+ Returns
557
+ -------
558
+ inv
559
+ Inverse of the ETS
560
+
561
+ Examples
562
+ --------
563
+ .. runblock:: pycon
564
+ >>> from roboticstoolbox import ET
565
+ >>> e = ET.Rz(jindex=2) * ET.tx(1) * ET.Rx(jindex=3,flip=True) * ET.tx(1)
566
+ >>> print(e)
567
+ >>> print(e.inv())
568
+
569
+ Notes
570
+ -----
571
+ - It is essential to use explicit joint indices to account for
572
+ the reversed order of the transforms.
573
+
574
+ """ # noqa
575
+
576
+ return self.__class__([et.inv() for et in reversed(self.data)])
577
+
578
+ @overload
579
+ def __getitem__(self: "BaseETS", i: int) -> BaseET: ...
580
+
581
+ @overload
582
+ def __getitem__(self: "ETS", i: int) -> ET: ...
583
+
584
+ @overload
585
+ def __getitem__(self: "ETS", i: slice) -> List[ET]: ...
586
+
587
+ @overload
588
+ def __getitem__(self: "ETS2", i: int) -> ET2: ...
589
+
590
+ @overload
591
+ def __getitem__(self: "ETS2", i: slice) -> List[ET2]: ...
592
+
593
+ def __getitem__(self, i):
594
+ """
595
+ Index or slice an ETS
596
+
597
+ Parameters
598
+ ----------
599
+ i
600
+ the index or slince
601
+
602
+ Returns
603
+ -------
604
+ et
605
+ Elementary transform
606
+
607
+ Examples
608
+ --------
609
+ .. runblock:: pycon
610
+ >>> from roboticstoolbox import ET
611
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
612
+ >>> e[0]
613
+ >>> e[1]
614
+ >>> e[1:3]
615
+
616
+ """
617
+ return self.data[i] # can be [2] or slice, eg. [3:5]
618
+
619
+ @overload
620
+ def __setitem__(self: "BaseETS", i: int, value: BaseET): ...
621
+
622
+ @overload
623
+ def __setitem__(self: "ETS", i: int, value: ET): ...
624
+
625
+ @overload
626
+ def __setitem__(self: "ETS", i: slice, value: List[ET]): ...
627
+
628
+ @overload
629
+ def __setitem__(self: "ETS2", i: int, value: ET2): ...
630
+
631
+ @overload
632
+ def __setitem__(self: "ETS2", i: slice, value: List[ET2]): ...
633
+
634
+ def __setitem__(self, i, value):
635
+ """
636
+ Set an item in the ETS
637
+
638
+ Parameters
639
+ ----------
640
+ i
641
+ the index
642
+ value
643
+ the value to set
644
+
645
+ Examples
646
+ --------
647
+ .. runblock:: pycon
648
+ >>> from roboticstoolbox import ET
649
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
650
+ >>> e[1] = ET.tx(2)
651
+ >>> e
652
+
653
+ """
654
+ self.data[i] = value
655
+ self._update_internals()
656
+
657
+ def __deepcopy__(self, memo):
658
+ new_data = []
659
+
660
+ for data in self:
661
+ new_data.append(deepcopy(data))
662
+
663
+ cls = self.__class__
664
+ result = cls(new_data)
665
+ memo[id(self)] = result
666
+ return result
667
+
668
+ def plot(self, *args, **kwargs):
669
+ from roboticstoolbox.robot.Robot import Robot, Robot2
670
+
671
+ if isinstance(self, ETS):
672
+ robot = Robot(self)
673
+ else:
674
+ robot = Robot2(self)
675
+
676
+ robot.plot(*args, **kwargs)
677
+
678
+ def teach(self, *args, **kwargs):
679
+ from roboticstoolbox.robot.Robot import Robot, Robot2
680
+
681
+ if isinstance(self, ETS):
682
+ robot = Robot(self)
683
+ else:
684
+ robot = Robot2(self)
685
+
686
+ robot.teach(*args, **kwargs)
687
+
688
+ def random_q(self, i: int = 1) -> NDArray:
689
+ """
690
+ Generate a random valid joint configuration
691
+
692
+ Generates a random q vector within the joint limits defined by
693
+ `self.qlim`.
694
+
695
+ Parameters
696
+ ----------
697
+ i
698
+ number of configurations to generate
699
+
700
+ Examples
701
+ --------
702
+ .. runblock:: pycon
703
+ >>> import roboticstoolbox as rtb
704
+ >>> robot = rtb.models.Panda()
705
+ >>> ets = robot.ets()
706
+ >>> q = ets.random_q()
707
+ >>> q
708
+
709
+ """
710
+
711
+ if i == 1:
712
+ q = np.zeros(self.n)
713
+
714
+ for i in range(self.n):
715
+ q[i] = uniform(self.qlim[0, i], self.qlim[1, i])
716
+
717
+ else:
718
+ q = np.zeros((i, self.n))
719
+
720
+ for j in range(i):
721
+ for i in range(self.n):
722
+ q[j, i] = uniform(self.qlim[0, i], self.qlim[1, i])
723
+
724
+ return q
725
+
726
+
727
+ class ETS(BaseETS):
728
+ """
729
+ This class implements an elementary transform sequence (ETS) for 3D
730
+
731
+ An instance can contain an elementary transform (ET) or an elementary
732
+ transform sequence (ETS). It has list-like properties by subclassing
733
+ UserList, which means we can perform indexing, slicing pop, insert, as well
734
+ as using it as an iterator over its values.
735
+
736
+ - ``ETS()`` an empty ETS list
737
+ - ``ETS(et)`` an ETS containing a single ET
738
+ - ``ETS([et0, et1, et2])`` an ETS consisting of three ET's
739
+
740
+ Parameters
741
+ ----------
742
+ arg
743
+ Function to compute ET value
744
+
745
+ Examples
746
+ --------
747
+ .. runblock:: pycon
748
+ >>> from roboticstoolbox import ETS, ET
749
+ >>> e = ET.Rz(0.3) # a single ET, rotation about z
750
+ >>> ets1 = ETS(e)
751
+ >>> len(ets1)
752
+ >>> ets2 = ET.Rz(0.3) * ET.tx(2) # an ETS
753
+ >>> len(ets2) # of length 2
754
+ >>> ets2[1] # an ET sliced from the ETS
755
+
756
+ References
757
+ ----------
758
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
759
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
760
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
761
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
762
+
763
+
764
+ See Also
765
+ --------
766
+ :func:`rx`
767
+ :func:`ry`
768
+ :func:`rz`
769
+ :func:`tx`
770
+ :func:`ty`
771
+ :func:`tz`
772
+
773
+ """
774
+
775
+ def __init__(
776
+ self,
777
+ arg: Union[
778
+ List[Union["ETS", ET]], List[ET], List["ETS"], ET, "ETS", None
779
+ ] = None,
780
+ ):
781
+ super().__init__()
782
+ if isinstance(arg, list):
783
+ for item in arg:
784
+ if isinstance(item, ET):
785
+ self.data.append(deepcopy(item))
786
+ elif isinstance(item, ETS):
787
+ for ets_item in item:
788
+ self.data.append(deepcopy(ets_item))
789
+ else:
790
+ raise TypeError("Invalid arg")
791
+ elif isinstance(arg, ET):
792
+ self.data.append(deepcopy(arg))
793
+ elif isinstance(arg, ETS):
794
+ for ets_item in arg:
795
+ self.data.append(deepcopy(ets_item))
796
+ elif arg is None:
797
+ self.data = []
798
+ else:
799
+ raise TypeError("Invalid arg")
800
+
801
+ super()._update_internals()
802
+
803
+ self._auto_jindex = False
804
+
805
+ # Check if jindices are set
806
+ joints = self.joints()
807
+
808
+ # Number of joints with a jindex
809
+ jindices = 0
810
+
811
+ # Number of joints with a sequential jindex (j[2] -> jindex = 2)
812
+ seq_jindex = 0
813
+
814
+ # Count them up
815
+ for j, joint in enumerate(joints):
816
+ if joint.jindex is not None:
817
+ jindices += 1
818
+ if joint.jindex == j:
819
+ seq_jindex += 1
820
+
821
+ if (
822
+ jindices == self.n - 1
823
+ and seq_jindex == self.n - 1
824
+ and joints[-1].jindex is None
825
+ ):
826
+ # ets has sequential jindicies, except for the last.
827
+ joints[-1].jindex = self.n - 1
828
+ self._auto_jindex = True
829
+
830
+ elif jindices > 0 and not jindices == self.n:
831
+ raise ValueError(
832
+ "You can not have some jindices set for the ET's in arg. It must be all"
833
+ " or none"
834
+ ) # pragma: nocover
835
+ elif jindices == 0 and self.n > 0:
836
+ # Set them ourself
837
+ for j, joint in enumerate(joints):
838
+ joint.jindex = j
839
+
840
+ self._auto_jindex = True
841
+
842
+ def __mul__(self, other: Union["ET", "ETS"]) -> "ETS":
843
+ if isinstance(other, ET):
844
+ return ETS([*self.data, other])
845
+ else:
846
+ return ETS([*self.data, *other.data]) # pragma: nocover
847
+
848
+ def __rmul__(self, other: Union["ET", "ETS"]) -> "ETS":
849
+ return ETS([other, *self.data]) # pragma: nocover
850
+
851
+ def __imul__(self, rest: "ETS"):
852
+ return self + rest # pragma: nocover
853
+
854
+ def __add__(self, rest) -> "ETS":
855
+ return self.__mul__(rest) # pragma: nocover
856
+
857
+ def compile(self) -> "ETS":
858
+ """
859
+ Compile an ETS
860
+
861
+ Perform constant folding for faster evaluation. Consecutive constant
862
+ ETs are compounded, leading to a constant ET which is denoted by
863
+ ``SE3`` when displayed.
864
+
865
+ Returns
866
+ -------
867
+ compile
868
+ optimised ETS
869
+
870
+ Examples
871
+ --------
872
+ .. runblock:: pycon
873
+ >>> import roboticstoolbox as rtb
874
+ >>> robot = rtb.models.ETS.Panda()
875
+ >>> ets = robot.ets()
876
+ >>> ets
877
+ >>> ets.compile()
878
+
879
+ See Also
880
+ --------
881
+ :func:`isconstant`
882
+ """
883
+ const = None
884
+ ets = ETS()
885
+
886
+ for et in self:
887
+ if et.isjoint:
888
+ # a joint
889
+ if const is not None:
890
+ # flush the constant
891
+ if not np.array_equal(const, np.eye(4)):
892
+ ets *= ET.SE3(const)
893
+ const = None
894
+ ets *= et # emit the joint ET
895
+ else:
896
+ # not a joint
897
+ if const is None:
898
+ const = et.A()
899
+ else:
900
+ const = const @ et.A()
901
+
902
+ if const is not None:
903
+ # flush the constant, tool transform
904
+ if not np.array_equal(const, np.eye(4)):
905
+ ets *= ET.SE3(const)
906
+ return ets
907
+
908
+ def insert(
909
+ self,
910
+ arg: Union[ET, "ETS"],
911
+ i: int = -1,
912
+ ) -> None:
913
+ """
914
+ Insert value
915
+
916
+ Inserts an ET or ETS into the ET sequence. The inserted value is at position
917
+ ``i``.
918
+
919
+ Parameters
920
+ ----------
921
+ i
922
+ insert an ET or ETS into the ETS, default is at the end
923
+ arg
924
+ the elementary transform or sequence to insert
925
+
926
+ Examples
927
+ --------
928
+ .. runblock:: pycon
929
+ >>> from roboticstoolbox import ET
930
+ >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1)
931
+ >>> f = ET.Ry()
932
+ >>> e.insert(f, 2)
933
+ >>> e
934
+
935
+ """
936
+
937
+ if isinstance(arg, ET):
938
+ if i == -1:
939
+ self.data.append(arg)
940
+ else:
941
+ self.data.insert(i, arg)
942
+ elif isinstance(arg, ETS):
943
+ if i == -1:
944
+ for et in arg:
945
+ self.data.append(et)
946
+ else:
947
+ for j, et in enumerate(arg):
948
+ self.data.insert(i + j, et)
949
+ self._update_internals()
950
+
951
+ def fkine(
952
+ self,
953
+ q: ArrayLike,
954
+ base: Union[NDArray, SE3, None] = None,
955
+ tool: Union[NDArray, SE3, None] = None,
956
+ include_base: bool = True,
957
+ ) -> SE3:
958
+ """
959
+ Forward kinematics
960
+
961
+ ``T = ets.fkine(q)`` evaluates forward kinematics for the ets at
962
+ joint configuration ``q``.
963
+
964
+ **Trajectory operation**:
965
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
966
+ result is an ``SE3`` instance with ``m`` values.
967
+
968
+ Parameters
969
+ ----------
970
+ q
971
+ Joint coordinates
972
+ base
973
+ A base transform applied before the ETS
974
+ tool
975
+ tool transform, optional
976
+ include_base
977
+ set to True if the base transform should be considered
978
+
979
+ Returns
980
+ -------
981
+ The transformation matrix representing the pose of the
982
+ end-effector
983
+
984
+ Examples
985
+ --------
986
+ The following example makes a ``panda`` robot object, gets the ets, and
987
+ solves for the forward kinematics at the listed configuration.
988
+
989
+ .. runblock:: pycon
990
+ >>> import roboticstoolbox as rtb
991
+ >>> panda = rtb.models.Panda().ets()
992
+ >>> panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
993
+
994
+ Notes
995
+ -----
996
+ - A tool transform, if provided, is incorporated into the result.
997
+ - Works from the end-effector link to the base
998
+
999
+ References
1000
+ ----------
1001
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1002
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1003
+
1004
+ """ # noqa
1005
+
1006
+ ret = SE3.Empty()
1007
+ fk = self.eval(q, base, tool, include_base)
1008
+
1009
+ if fk.dtype == "O":
1010
+ # symbolic
1011
+ fk = np.array(simplify(fk))
1012
+
1013
+ if fk.ndim == 3:
1014
+ for T in fk:
1015
+ ret.append(SE3(T, check=False)) # type: ignore
1016
+ else:
1017
+ ret = SE3(fk, check=False)
1018
+
1019
+ return ret
1020
+
1021
+ def eval(
1022
+ self,
1023
+ q: ArrayLike,
1024
+ base: Union[NDArray, SE3, None] = None,
1025
+ tool: Union[NDArray, SE3, None] = None,
1026
+ include_base: bool = True,
1027
+ ) -> NDArray:
1028
+ """
1029
+ Forward kinematics
1030
+
1031
+ ``T = ets.fkine(q)`` evaluates forward kinematics for the ets at
1032
+ joint configuration ``q``.
1033
+
1034
+ **Trajectory operation**:
1035
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
1036
+ result is an ``SE3`` instance with ``m`` values.
1037
+
1038
+ Parameters
1039
+ ----------
1040
+ q
1041
+ Joint coordinates
1042
+ base
1043
+ A base transform applied before the ETS
1044
+ tool
1045
+ tool transform, optional
1046
+ include_base
1047
+ set to True if the base transform should be considered
1048
+ Returns
1049
+ -------
1050
+ The transformation matrix representing the pose of the
1051
+ end-effector
1052
+
1053
+ Examples
1054
+ --------
1055
+ The following example makes a ``panda`` robot object, gets the ets, and
1056
+ solves for the forward kinematics at the listed configuration.
1057
+
1058
+ .. runblock:: pycon
1059
+ >>> import roboticstoolbox as rtb
1060
+ >>> panda = rtb.models.Panda().ets()
1061
+ >>> panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1062
+
1063
+ Notes
1064
+ -----
1065
+ - A tool transform, if provided, is incorporated into the result.
1066
+ - Works from the end-effector link to the base
1067
+
1068
+ References
1069
+ ----------
1070
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1071
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1072
+
1073
+ """ # noqa
1074
+
1075
+ try:
1076
+ return ETS_fkine(self._fknm, q, base, tool, include_base)
1077
+ except BaseException:
1078
+ pass
1079
+
1080
+ q = getmatrix(q, (None, None))
1081
+ l, _ = q.shape # type: ignore
1082
+ end = self.data[-1]
1083
+
1084
+ if isinstance(tool, SE3):
1085
+ tool = np.array(tool.A)
1086
+
1087
+ if isinstance(base, SE3):
1088
+ base = np.array(base.A)
1089
+
1090
+ if base is None:
1091
+ bases = None
1092
+ elif np.array_equal(base, np.eye(3)): # pragma: nocover
1093
+ bases = None
1094
+ else: # pragma: nocover
1095
+ bases = base
1096
+
1097
+ if tool is None:
1098
+ tools = None
1099
+ elif np.array_equal(tool, np.eye(3)): # pragma: nocover
1100
+ tools = None
1101
+ else: # pragma: nocover
1102
+ tools = tool
1103
+
1104
+ if l > 1:
1105
+ T = np.zeros((l, 4, 4), dtype=object)
1106
+ else:
1107
+ T = np.zeros((4, 4), dtype=object)
1108
+
1109
+ # Tk = None
1110
+
1111
+ for k, qk in enumerate(q): # type: ignore
1112
+ link = end # start with last link
1113
+
1114
+ jindex = 0 if link.jindex is None and link.isjoint else link.jindex
1115
+
1116
+ Tk = link.A(qk[jindex])
1117
+
1118
+ if tools is not None:
1119
+ Tk = Tk @ tools
1120
+
1121
+ # add remaining links, back toward the base
1122
+ for i in range(self.m - 2, -1, -1):
1123
+ link = self.data[i]
1124
+
1125
+ jindex = 0 if link.jindex is None and link.isjoint else link.jindex
1126
+ A = link.A(qk[jindex])
1127
+
1128
+ if A is not None:
1129
+ Tk = A @ Tk
1130
+
1131
+ # add base transform if it is set
1132
+ if include_base is True and bases is not None:
1133
+ Tk = bases @ Tk
1134
+
1135
+ # append
1136
+ if l > 1:
1137
+ T[k, :, :] = Tk
1138
+ else:
1139
+ T = Tk
1140
+
1141
+ return T
1142
+
1143
+ def jacob0(
1144
+ self,
1145
+ q: ArrayLike,
1146
+ tool: Union[NDArray, SE3, None] = None,
1147
+ ) -> NDArray:
1148
+ r"""
1149
+ Manipulator geometric Jacobian in the base frame
1150
+
1151
+ ``robot.jacobo(q)`` is the manipulator Jacobian matrix which maps
1152
+ joint velocity to end-effector spatial velocity expressed in the
1153
+ base frame.
1154
+
1155
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
1156
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
1157
+
1158
+ Parameters
1159
+ ----------
1160
+ q
1161
+ Joint coordinate vector
1162
+ tool
1163
+ a static tool transformation matrix to apply to the
1164
+ end of end, defaults to None
1165
+
1166
+ Returns
1167
+ -------
1168
+ J0
1169
+ Manipulator Jacobian in the base frame
1170
+
1171
+ Examples
1172
+ --------
1173
+ The following example makes a ``Puma560`` robot object, and solves for the
1174
+ base-frame Jacobian at the zero joint angle configuration
1175
+
1176
+ .. runblock:: pycon
1177
+ >>> import roboticstoolbox as rtb
1178
+ >>> puma = rtb.models.Puma560().ets()
1179
+ >>> puma.jacob0([0, 0, 0, 0, 0, 0])
1180
+
1181
+ Notes
1182
+ -----
1183
+ - This is the geometric Jacobian as described in texts by
1184
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
1185
+ described in terms of translational and angular velocity, not a
1186
+ velocity twist as per the text by Lynch & Park.
1187
+
1188
+ References
1189
+ ----------
1190
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1191
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1192
+
1193
+ """ # noqa
1194
+
1195
+ # Use c extension
1196
+ try:
1197
+ return ETS_jacob0(self._fknm, q, tool)
1198
+ except TypeError:
1199
+ pass
1200
+
1201
+ # Otherwise use Python
1202
+ if tool is None:
1203
+ tools = np.eye(4)
1204
+ elif isinstance(tool, SE3):
1205
+ tools = np.array(tool.A)
1206
+ else: # pragma: nocover
1207
+ tools = np.eye(4)
1208
+
1209
+ q = getvector(q, None)
1210
+
1211
+ T = self.eval(q, include_base=False) @ tools
1212
+
1213
+ U = np.eye(4)
1214
+ j = 0
1215
+ J = np.zeros((6, self.n), dtype="object")
1216
+ zero = np.array([0, 0, 0])
1217
+ end = self.data[-1]
1218
+
1219
+ for link in self.data:
1220
+ jindex = 0 if link.jindex is None and link.isjoint else link.jindex
1221
+
1222
+ if link.isjoint:
1223
+ U = U @ link.A(q[jindex]) # type: ignore
1224
+
1225
+ if link == end:
1226
+ U = U @ tools
1227
+
1228
+ Tu = SE3(U, check=False).inv().A @ T
1229
+ n = U[:3, 0]
1230
+ o = U[:3, 1]
1231
+ a = U[:3, 2]
1232
+ x = Tu[0, 3]
1233
+ y = Tu[1, 3]
1234
+ z = Tu[2, 3]
1235
+
1236
+ if link.axis == "Rz":
1237
+ J[:3, j] = (o * x) - (n * y)
1238
+ J[3:, j] = a
1239
+
1240
+ elif link.axis == "Ry":
1241
+ J[:3, j] = (n * z) - (a * x)
1242
+ J[3:, j] = o
1243
+
1244
+ elif link.axis == "Rx":
1245
+ J[:3, j] = (a * y) - (o * z)
1246
+ J[3:, j] = n
1247
+
1248
+ elif link.axis == "tx":
1249
+ J[:3, j] = n
1250
+ J[3:, j] = zero
1251
+
1252
+ elif link.axis == "ty":
1253
+ J[:3, j] = o
1254
+ J[3:, j] = zero
1255
+
1256
+ elif link.axis == "tz":
1257
+ J[:3, j] = a
1258
+ J[3:, j] = zero
1259
+
1260
+ j += 1
1261
+ else:
1262
+ A = link.A()
1263
+ if A is not None:
1264
+ U = U @ A
1265
+
1266
+ return J
1267
+
1268
+ def jacobe(
1269
+ self,
1270
+ q: ArrayLike,
1271
+ tool: Union[NDArray, SE3, None] = None,
1272
+ ) -> NDArray:
1273
+ r"""
1274
+ Manipulator geometric Jacobian in the end-effector frame
1275
+
1276
+ ``robot.jacobe(q)`` is the manipulator Jacobian matrix which maps
1277
+ joint velocity to end-effector spatial velocity expressed in the
1278
+ ``end`` frame.
1279
+
1280
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
1281
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
1282
+
1283
+ Parameters
1284
+ ----------
1285
+ q
1286
+ Joint coordinate vector
1287
+ end
1288
+ the particular link or gripper whose velocity the Jacobian
1289
+ describes, defaults to the end-effector if only one is present
1290
+ start
1291
+ the link considered as the base frame, defaults to the robots's base frame
1292
+ tool
1293
+ a static tool transformation matrix to apply to the
1294
+ end of end, defaults to None
1295
+
1296
+ Returns
1297
+ -------
1298
+ Je
1299
+ Manipulator Jacobian in the ``end`` frame
1300
+
1301
+ Examples
1302
+ --------
1303
+ The following example makes a ``Puma560`` robot object, and solves for the
1304
+ end-effector frame Jacobian at the zero joint angle configuration
1305
+
1306
+ .. runblock:: pycon
1307
+ >>> import roboticstoolbox as rtb
1308
+ >>> puma = rtb.models.Puma560().ets()
1309
+ >>> puma.jacobe([0, 0, 0, 0, 0, 0])
1310
+
1311
+ Notes
1312
+ -----
1313
+ - This is the geometric Jacobian as described in texts by
1314
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
1315
+ described in terms of translational and angular velocity, not a
1316
+ velocity twist as per the text by Lynch & Park.
1317
+
1318
+ References
1319
+ ----------
1320
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1321
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1322
+
1323
+ """ # noqa
1324
+
1325
+ # Use c extension
1326
+ try:
1327
+ return ETS_jacobe(self._fknm, q, tool)
1328
+ except TypeError:
1329
+ pass
1330
+
1331
+ T = self.eval(q, tool=tool, include_base=False)
1332
+ return tr2jac(T.T) @ self.jacob0(q, tool=tool)
1333
+
1334
+ def hessian0(
1335
+ self,
1336
+ q: Union[ArrayLike, None] = None,
1337
+ J0: Union[NDArray, None] = None,
1338
+ tool: Union[NDArray, SE3, None] = None,
1339
+ ) -> NDArray:
1340
+ r"""
1341
+ Manipulator Hessian
1342
+
1343
+ The manipulator Hessian tensor maps joint acceleration to end-effector
1344
+ spatial acceleration, expressed in the base frame. This
1345
+ function calulcates this based on the ETS of the robot. One of J0 or q
1346
+ is required. Supply J0 if already calculated to save computation time
1347
+
1348
+ Parameters
1349
+ ----------
1350
+ q
1351
+ The joint angles/configuration of the robot (Optional,
1352
+ if not supplied will use the stored q values).
1353
+ J0
1354
+ The manipulator Jacobian in the base frame
1355
+ tool
1356
+ a static tool transformation matrix to apply to the
1357
+ end of end, defaults to None
1358
+
1359
+ Returns
1360
+ -------
1361
+ h0
1362
+ The manipulator Hessian in the base frame
1363
+
1364
+ Synopsis
1365
+ --------
1366
+ This method computes the manipulator Hessian in the base frame. If
1367
+ we take the time derivative of the differential kinematic relationship
1368
+
1369
+ .. math::
1370
+
1371
+ \nu &= \mat{J}(\vec{q}) \dvec{q} \\
1372
+ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}
1373
+
1374
+ where
1375
+
1376
+ .. math::
1377
+
1378
+ \dmat{J} = \mat{H} \dvec{q}
1379
+
1380
+ and :math:`\mat{H} \in \mathbb{R}^{6\times n \times n}` is the
1381
+ Hessian tensor.
1382
+
1383
+ The elements of the Hessian are
1384
+
1385
+ .. math::
1386
+
1387
+ \mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}
1388
+
1389
+ where :math:`u = \{t_x, t_y, t_z, r_x, r_y, r_z\}` are the elements
1390
+ of the spatial velocity vector.
1391
+
1392
+ Similarly, we can write
1393
+
1394
+ .. math::
1395
+
1396
+ \mat{J}_{i,j} = \frac{d u_i}{d q_j}
1397
+
1398
+ Examples
1399
+ --------
1400
+ The following example makes a ``Panda`` robot object, and solves for the
1401
+ base frame Hessian at the given joint angle configuration
1402
+
1403
+ .. runblock:: pycon
1404
+ >>> import roboticstoolbox as rtb
1405
+ >>> panda = rtb.models.Panda().ets()
1406
+ >>> panda.hessian0([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1407
+
1408
+ References
1409
+ ----------
1410
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1411
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1412
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1413
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1414
+
1415
+ """ # noqa
1416
+
1417
+ # Use c extension
1418
+ try:
1419
+ return ETS_hessian0(self._fknm, q, J0, tool)
1420
+ except TypeError:
1421
+ pass
1422
+
1423
+ def cross(a, b):
1424
+ x = a[1] * b[2] - a[2] * b[1]
1425
+ y = a[2] * b[0] - a[0] * b[2]
1426
+ z = a[0] * b[1] - a[1] * b[0]
1427
+ return np.array([x, y, z])
1428
+
1429
+ n = self.n
1430
+
1431
+ if J0 is None:
1432
+ if q is None:
1433
+ raise ValueError("Either J0 or q must be provided")
1434
+
1435
+ q = getvector(q, None)
1436
+ J0 = self.jacob0(q, tool=tool)
1437
+ else:
1438
+ verifymatrix(J0, (6, self.n))
1439
+
1440
+ H = np.zeros((n, 6, n))
1441
+
1442
+ for j in range(n):
1443
+ for i in range(j, n):
1444
+ H[j, :3, i] = cross(J0[3:, j], J0[:3, i])
1445
+ H[j, 3:, i] = cross(J0[3:, j], J0[3:, i])
1446
+
1447
+ if i != j:
1448
+ H[i, :3, j] = H[j, :3, i]
1449
+
1450
+ return H
1451
+
1452
+ def hessiane(
1453
+ self,
1454
+ q: Union[ArrayLike, None] = None,
1455
+ Je: Union[NDArray, None] = None,
1456
+ tool: Union[NDArray, SE3, None] = None,
1457
+ ) -> NDArray:
1458
+ r"""
1459
+ Manipulator Hessian
1460
+
1461
+ The manipulator Hessian tensor maps joint acceleration to end-effector
1462
+ spatial acceleration, expressed in the end-effector coordinate frame. This
1463
+ function calulcates this based on the ETS of the robot. One of J0 or q
1464
+ is required. Supply J0 if already calculated to save computation time
1465
+
1466
+ Parameters
1467
+ ----------
1468
+ q
1469
+ The joint angles/configuration of the robot (Optional,
1470
+ if not supplied will use the stored q values).
1471
+ J0
1472
+ The manipulator Jacobian in the end-effector frame
1473
+ tool
1474
+ a static tool transformation matrix to apply to the
1475
+ end of end, defaults to None
1476
+
1477
+ Returns
1478
+ -------
1479
+ he
1480
+ The manipulator Hessian in end-effector frame
1481
+
1482
+ Synopsis
1483
+ --------
1484
+ This method computes the manipulator Hessian in the end-effector frame. If
1485
+ we take the time derivative of the differential kinematic relationship
1486
+
1487
+ .. math::
1488
+
1489
+ \nu &= \mat{J}(\vec{q}) \dvec{q} \\
1490
+ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}
1491
+
1492
+ where
1493
+
1494
+ .. math::
1495
+
1496
+ \dmat{J} = \mat{H} \dvec{q}
1497
+
1498
+ and :math:`\mat{H} \in \mathbb{R}^{6\times n \times n}` is the
1499
+ Hessian tensor.
1500
+
1501
+ The elements of the Hessian are
1502
+
1503
+ .. math::
1504
+
1505
+ \mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}
1506
+
1507
+ where :math:`u = \{t_x, t_y, t_z, r_x, r_y, r_z\}` are the elements
1508
+ of the spatial velocity vector.
1509
+
1510
+ Similarly, we can write
1511
+
1512
+ .. math::
1513
+
1514
+ \mat{J}_{i,j} = \frac{d u_i}{d q_j}
1515
+
1516
+ Examples
1517
+ --------
1518
+ The following example makes a ``Panda`` robot object, and solves for the
1519
+ end-effector frame Hessian at the given joint angle configuration
1520
+
1521
+ .. runblock:: pycon
1522
+ >>> import roboticstoolbox as rtb
1523
+ >>> panda = rtb.models.Panda().ets()
1524
+ >>> panda.hessiane([0, -0.3, 0, -2.2, 0, 2, 0.7854])
1525
+
1526
+ References
1527
+ ----------
1528
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1529
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1530
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1531
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1532
+
1533
+ """ # noqa
1534
+
1535
+ # Use c extension
1536
+ try:
1537
+ return ETS_hessiane(self._fknm, q, Je, tool)
1538
+ except TypeError:
1539
+ pass
1540
+
1541
+ def cross(a, b):
1542
+ x = a[1] * b[2] - a[2] * b[1]
1543
+ y = a[2] * b[0] - a[0] * b[2]
1544
+ z = a[0] * b[1] - a[1] * b[0]
1545
+ return np.array([x, y, z])
1546
+
1547
+ n = self.n
1548
+
1549
+ if Je is None:
1550
+ if q is None:
1551
+ raise ValueError("Either Je or q must be provided")
1552
+
1553
+ q = getvector(q, None)
1554
+ Je = self.jacobe(q, tool=tool)
1555
+ else:
1556
+ verifymatrix(Je, (6, self.n))
1557
+
1558
+ H = np.zeros((n, 6, n))
1559
+
1560
+ for j in range(n):
1561
+ for i in range(j, n):
1562
+ H[j, :3, i] = cross(Je[3:, j], Je[:3, i])
1563
+ H[j, 3:, i] = cross(Je[3:, j], Je[3:, i])
1564
+
1565
+ if i != j:
1566
+ H[i, :3, j] = H[j, :3, i]
1567
+
1568
+ return H
1569
+
1570
+ def jacob0_analytical(
1571
+ self,
1572
+ q: ArrayLike,
1573
+ representation: str = "rpy/xyz",
1574
+ tool: Union[NDArray, SE3, None] = None,
1575
+ ):
1576
+ r"""
1577
+ Manipulator analytical Jacobian in the base frame
1578
+
1579
+ ``robot.jacob0_analytical(q)`` is the manipulator Jacobian matrix which maps
1580
+ joint velocity to end-effector spatial velocity expressed in the
1581
+ base frame.
1582
+
1583
+ Parameters
1584
+ ----------
1585
+ q
1586
+ Joint coordinate vector
1587
+ representation
1588
+ angular representation
1589
+ tool
1590
+ a static tool transformation matrix to apply to the
1591
+ end of end, defaults to None
1592
+
1593
+ Returns
1594
+ -------
1595
+ jacob0
1596
+ Manipulator Jacobian in the base frame
1597
+
1598
+ Synopsis
1599
+ --------
1600
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
1601
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
1602
+
1603
+ |``representation`` | Rotational representation |
1604
+ |---------------------|-------------------------------------|
1605
+ |``'rpy/xyz'`` | RPY angular rates in XYZ order |
1606
+ |``'rpy/zyx'`` | RPY angular rates in XYZ order |
1607
+ |``'eul'`` | Euler angular rates in ZYZ order |
1608
+ |``'exp'`` | exponential coordinate rates |
1609
+
1610
+ Examples
1611
+ --------
1612
+ Makes a robot object and computes the analytic Jacobian for the given
1613
+ joint configuration
1614
+
1615
+ .. runblock:: pycon
1616
+ >>> import roboticstoolbox as rtb
1617
+ >>> puma = rtb.models.ETS.Puma560().ets()
1618
+ >>> puma.jacob0_analytical([0, 0, 0, 0, 0, 0])
1619
+
1620
+ """ # noqa
1621
+
1622
+ T = self.eval(q, tool=tool)
1623
+ J = self.jacob0(q, tool=tool)
1624
+ gamma = t2r(T)[:3, :3]
1625
+ A = rotvelxform(gamma, full=True, inverse=True, representation=representation)
1626
+ return A @ J
1627
+
1628
+ def jacobm(self, q: ArrayLike) -> NDArray:
1629
+ r"""
1630
+ The manipulability Jacobian
1631
+
1632
+ This measure relates the rate of change of the manipulability to the
1633
+ joint velocities of the robot. One of J or q is required. Supply J
1634
+ and H if already calculated to save computation time
1635
+
1636
+ Parameters
1637
+ ----------
1638
+ q
1639
+ The joint angles/configuration of the robot (Optional,
1640
+ if not supplied will use the stored q values).
1641
+
1642
+ Returns
1643
+ -------
1644
+ jacobm
1645
+ The manipulability Jacobian
1646
+
1647
+ Synopsis
1648
+ --------
1649
+ Yoshikawa's manipulability measure
1650
+
1651
+ .. math::
1652
+
1653
+ m(\vec{q}) = \sqrt{\mat{J}(\vec{q}) \mat{J}(\vec{q})^T}
1654
+
1655
+ This method returns its Jacobian with respect to configuration
1656
+
1657
+ .. math::
1658
+
1659
+ \frac{\partial m(\vec{q})}{\partial \vec{q}}
1660
+
1661
+ References
1662
+ ----------
1663
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1664
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1665
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1666
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1667
+
1668
+ """ # noqa
1669
+
1670
+ J = self.jacob0(q)
1671
+ H = self.hessian0(q)
1672
+
1673
+ manipulability = self.manipulability(q)
1674
+
1675
+ # J = J[axes, :]
1676
+ # H = H[:, axes, :]
1677
+
1678
+ b = inv(J @ J.T)
1679
+ Jm = np.zeros((self.n, 1))
1680
+
1681
+ for i in range(self.n):
1682
+ c = J @ H[i, :, :].T
1683
+ Jm[i, 0] = manipulability * (c.flatten("F")).T @ b.flatten("F")
1684
+
1685
+ return Jm
1686
+
1687
+ def manipulability(
1688
+ self,
1689
+ q,
1690
+ method: L["yoshikawa", "minsingular", "invcondition"] = "yoshikawa", # noqa
1691
+ axes: Union[L["all", "trans", "rot"], List[bool]] = "all", # noqa
1692
+ ):
1693
+ """
1694
+ Manipulability measure
1695
+
1696
+ ``manipulability(q)`` is the scalar manipulability index
1697
+ for the ets at the joint configuration ``q``. It indicates
1698
+ dexterity, that is, how well conditioned the ets is for motion
1699
+ with respect to the 6 degrees of Cartesian motion. The values is
1700
+ zero if the ets is at a singularity.
1701
+
1702
+ Parameters
1703
+ ----------
1704
+ q
1705
+ Joint coordinates, one of J or q required
1706
+ method
1707
+ method to use, "yoshikawa" (default), "invcondition",
1708
+ "minsingular"
1709
+ axes
1710
+ Task space axes to consider: "all" [default],
1711
+ "trans", or "rot"
1712
+
1713
+ Returns
1714
+ -------
1715
+ manipulability
1716
+ the manipulability metric
1717
+
1718
+ Synopsis
1719
+ --------
1720
+
1721
+ Various measures are supported:
1722
+
1723
+ | Measure | Description |
1724
+ |-------------------|-------------------------------------------------|
1725
+ | ``"yoshikawa"`` | Volume of the velocity ellipsoid, *distance* |
1726
+ | | from singularity [Yoshikawa85]_ |
1727
+ | ``"invcondition"``| Inverse condition number of Jacobian, isotropy |
1728
+ | | of the velocity ellipsoid [Klein87]_ |
1729
+ | ``"minsingular"`` | Minimum singular value of the Jacobian, |
1730
+ | | *distance* from singularity [Klein87]_ |
1731
+
1732
+ **Trajectory operation**:
1733
+
1734
+ If ``q`` is a matrix (m,n) then the result (m,) is a vector of
1735
+ manipulability indices for each joint configuration specified by a row
1736
+ of ``q``.
1737
+
1738
+ Notes
1739
+ -----
1740
+ - Invokes the ``jacob0`` method of the robot if ``J`` is not passed
1741
+ - The "all" option includes rotational and translational
1742
+ dexterity, but this involves adding different units. It can be
1743
+ more useful to look at the translational and rotational
1744
+ manipulability separately.
1745
+ - Examples in the RVC book (1st edition) can be replicated by
1746
+ using the "all" option
1747
+ - Asada's measure requires inertial a robot model with inertial
1748
+ parameters.
1749
+
1750
+ References
1751
+ ----------
1752
+ .. [Yoshikawa85] Manipulability of Robotic Mechanisms. Yoshikawa T.,
1753
+ The International Journal of Robotics Research.
1754
+ 1985;4(2):3-9. doi:10.1177/027836498500400201
1755
+ .. [Klein87] Dexterity Measures for the Design and Control of
1756
+ Kinematically Redundant Manipulators. Klein CA, Blaho BE.
1757
+ The International Journal of Robotics Research.
1758
+ 1987;6(2):72-83. doi:10.1177/027836498700600206
1759
+ - Robotics, Vision & Control in Python, 3e, P. Corke, Springer 2023, Chap 7.
1760
+
1761
+
1762
+ .. versionchanged:: 1.0.4
1763
+ Removed 'both' option for axes, added a custom list option.
1764
+
1765
+ """
1766
+
1767
+ axes_list: List[bool] = []
1768
+
1769
+ if isinstance(axes, list):
1770
+ axes_list = axes
1771
+ elif axes == "all":
1772
+ axes_list = [True, True, True, True, True, True]
1773
+ elif axes.startswith("trans"):
1774
+ axes_list = [True, True, True, False, False, False]
1775
+ elif axes.startswith("rot"):
1776
+ axes_list = [False, False, False, True, True, True]
1777
+ else:
1778
+ raise ValueError("axes must be all, trans, rot or both")
1779
+
1780
+ def yoshikawa(robot, J, q, axes, **kwargs):
1781
+ J = J[axes, :]
1782
+ if J.shape[0] == J.shape[1]:
1783
+ # simplified case for square matrix
1784
+ return abs(det(J))
1785
+ else:
1786
+ m2 = det(J @ J.T)
1787
+ return np.sqrt(abs(m2))
1788
+
1789
+ def condition(robot, J, q, axes, **kwargs):
1790
+ J = J[axes, :]
1791
+ return 1 / cond(J)
1792
+
1793
+ def minsingular(robot, J, q, axes, **kwargs):
1794
+ J = J[axes, :]
1795
+ s = svd(J, compute_uv=False)
1796
+ return s[-1] # return last/smallest singular value of J
1797
+
1798
+ # choose the handler function
1799
+ if method == "yoshikawa":
1800
+ mfunc = yoshikawa
1801
+ elif method == "invcondition":
1802
+ mfunc = condition
1803
+ elif method == "minsingular":
1804
+ mfunc = minsingular
1805
+ else:
1806
+ raise ValueError("Invalid method chosen")
1807
+
1808
+ # Otherwise use the q vector/matrix
1809
+ q = np.array(getmatrix(q, (None, self.n)))
1810
+ w = np.zeros(q.shape[0])
1811
+
1812
+ for k, qk in enumerate(q):
1813
+ Jk = self.jacob0(qk)
1814
+ w[k] = mfunc(self, Jk, qk, axes_list)
1815
+
1816
+ if len(w) == 1:
1817
+ return w[0]
1818
+ else:
1819
+ return w
1820
+
1821
+ def partial_fkine0(self, q: ArrayLike, n: int) -> NDArray:
1822
+ r"""
1823
+ Manipulator Forward Kinematics nth Partial Derivative
1824
+
1825
+ This method computes the nth derivative of the forward kinematics where ``n`` is
1826
+ greater than or equal to 3. This is an extension of the differential kinematics
1827
+ where the Jacobian is the first partial derivative and the Hessian is the
1828
+ second.
1829
+
1830
+ Parameters
1831
+ ----------
1832
+ q
1833
+ The joint angles/configuration of the robot (Optional,
1834
+ if not supplied will use the stored q values).
1835
+ end
1836
+ the final link/Gripper which the Hessian represents
1837
+ start
1838
+ the first link which the Hessian represents
1839
+ tool
1840
+ a static tool transformation matrix to apply to the
1841
+ end of end, defaults to None
1842
+
1843
+ Returns
1844
+ -------
1845
+ A
1846
+ The nth Partial Derivative of the forward kinematics
1847
+
1848
+ Examples
1849
+ --------
1850
+ The following example makes a ``Panda`` robot object, and solves for the
1851
+ base-effector frame 4th defivative of the forward kinematics at the given
1852
+ joint angle configuration
1853
+
1854
+ .. runblock:: pycon
1855
+ >>> import roboticstoolbox as rtb
1856
+ >>> panda = rtb.models.Panda().ets()
1857
+ >>> panda.partial_fkine0([0, -0.3, 0, -2.2, 0, 2, 0.7854], n=4)
1858
+
1859
+ References
1860
+ ----------
1861
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
1862
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
1863
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
1864
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
1865
+
1866
+ """ # noqa
1867
+
1868
+ # Calculate the Jacobian and Hessian
1869
+ J = self.jacob0(q)
1870
+ H = self.hessian0(q)
1871
+
1872
+ # A list of derivatives, starting with the jacobian and hessian
1873
+ dT = [J, H]
1874
+
1875
+ # The tensor dimensions of the latest derivative
1876
+ # Set to the current size of the Hessian
1877
+ size = [self.n, 6, self.n]
1878
+
1879
+ # An array which keeps track of the index of the partial derivative
1880
+ # we are calculating
1881
+ # It stores the indices in the order: "j, k, l. m, n, o, ..."
1882
+ # where count is extended to match oder of the partial derivative
1883
+ count = np.array([0, 0])
1884
+
1885
+ # The order of derivative for which we are calculating
1886
+ # The Hessian is the 2nd-order so we start with c = 2
1887
+ c = 2
1888
+
1889
+ def add_indices(indices, c):
1890
+ total = len(indices * 2)
1891
+ new_indices = []
1892
+
1893
+ for i in range(total):
1894
+ j = i // 2
1895
+ new_indices.append([])
1896
+ new_indices[i].append(indices[j][0].copy())
1897
+ new_indices[i].append(indices[j][1].copy())
1898
+
1899
+ if i % 2 == 0:
1900
+ # if even number
1901
+ new_indices[i][0].append(c)
1902
+ else:
1903
+ # if odd number
1904
+ new_indices[i][1].append(c)
1905
+
1906
+ return new_indices
1907
+
1908
+ def add_pdi(pdi):
1909
+ total = len(pdi * 2)
1910
+ new_pdi = []
1911
+
1912
+ for i in range(total):
1913
+ j = i // 2
1914
+ new_pdi.append([])
1915
+ new_pdi[i].append(pdi[j][0])
1916
+ new_pdi[i].append(pdi[j][1])
1917
+
1918
+ # if even number
1919
+ if i % 2 == 0:
1920
+ new_pdi[i][0] += 1
1921
+ # if odd number
1922
+ else:
1923
+ new_pdi[i][1] += 1
1924
+
1925
+ return new_pdi
1926
+
1927
+ # these are the indices used for the hessian
1928
+ indices = [[[1], [0]]]
1929
+
1930
+ # The partial derivative indices (pdi)
1931
+ # the are the pd indices used in the cross products
1932
+ pdi = [[0, 0]]
1933
+
1934
+ # The length of dT correspods to the number of derivatives we have calculated
1935
+ while len(dT) != n:
1936
+ # Add to the start of the tensor size list
1937
+ size.insert(0, self.n)
1938
+
1939
+ # Add an axis to the count array
1940
+ count = np.concatenate(([0], count))
1941
+
1942
+ # This variables corresponds to indices within the previous
1943
+ # partial derivatives
1944
+ # to be cross prodded
1945
+ # The order is: "[j, k, l, m, n, o, ...]"
1946
+ # Although, our partial derivatives have the order:
1947
+ # pd[..., o, n, m, l, k, cartesian DoF, j]
1948
+ # For example, consider the Hessian Tensor H[n, 6, n],
1949
+ # the index H[k, :, j]. This corrsponds
1950
+ # to the second partial derivative of the kinematics of joint j with
1951
+ # respect to joint k.
1952
+ indices = add_indices(indices, c)
1953
+
1954
+ # This variable corresponds to the indices in Td which corresponds to the
1955
+ # partial derivatives we need to use
1956
+ pdi = add_pdi(pdi)
1957
+
1958
+ c += 1
1959
+
1960
+ # Allocate our new partial derivative tensor
1961
+ pd = np.zeros(size)
1962
+
1963
+ # We need to loop n^c times
1964
+ # There are n^c columns to calculate
1965
+ for _ in range(self.n**c):
1966
+ # Allocate the rotation and translation components
1967
+ rot = np.zeros(3)
1968
+ trn = np.zeros(3)
1969
+
1970
+ # This loop calculates a single column ([trn, rot])
1971
+ # of the tensor for dT(x)
1972
+ for j in range(len(indices)):
1973
+ pdr0 = dT[pdi[j][0]]
1974
+ pdr1 = dT[pdi[j][1]]
1975
+
1976
+ idx0 = count[indices[j][0]]
1977
+ idx1 = count[indices[j][1]]
1978
+
1979
+ # This is a list of indices selecting the slices of the
1980
+ # previous tensor
1981
+ idx0_slices = np.flip(idx0[1:])
1982
+ idx1_slices = np.flip(idx1[1:])
1983
+
1984
+ # This index selecting the column within the 2d slice of the
1985
+ # previous tensor
1986
+ idx0_n = idx0[0]
1987
+ idx1_n = idx1[0]
1988
+
1989
+ # Use our indices to select the rotational column from pdr0 and pdr1
1990
+ col0_rot = pdr0[(*idx0_slices, slice(3, 6), idx0_n)]
1991
+ col1_rot = pdr1[(*idx1_slices, slice(3, 6), idx1_n)]
1992
+
1993
+ # Use our indices to select the translational column from pdr1
1994
+ col1_trn = pdr1[(*idx1_slices, slice(0, 3), idx1_n)]
1995
+
1996
+ # Perform the cross product as described in the maths above
1997
+ rot += np.cross(col0_rot, col1_rot)
1998
+ trn += np.cross(col0_rot, col1_trn)
1999
+
2000
+ pd[(*np.flip(count[1:]), slice(0, 3), count[0])] = trn
2001
+ pd[(*np.flip(count[1:]), slice(3, 6), count[0])] = rot
2002
+
2003
+ count[0] += 1
2004
+ for j in range(len(count)):
2005
+ if count[j] == self.n:
2006
+ count[j] = 0
2007
+ if j != len(count) - 1:
2008
+ count[j + 1] += 1
2009
+
2010
+ dT.append(pd)
2011
+
2012
+ return dT[-1]
2013
+
2014
+ def ik_LM(
2015
+ self,
2016
+ Tep: Union[NDArray, SE3],
2017
+ q0: Union[NDArray, None] = None,
2018
+ ilimit: int = 30,
2019
+ slimit: int = 100,
2020
+ tol: float = 1e-6,
2021
+ mask: Union[NDArray, None] = None,
2022
+ joint_limits: bool = True,
2023
+ k: float = 1.0,
2024
+ method: L["chan", "wampler", "sugihara"] = "chan", # noqa
2025
+ ) -> Tuple[NDArray, int, int, int, float]:
2026
+ r"""
2027
+ Fast levenberg-Marquadt Numerical Inverse Kinematics Solver
2028
+
2029
+ A method which provides functionality to perform numerical inverse kinematics (IK)
2030
+ using the Levemberg-Marquadt method. This
2031
+ is a fast solver implemented in C++.
2032
+
2033
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2034
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2035
+
2036
+ Parameters
2037
+ ----------
2038
+ Tep
2039
+ The desired end-effector pose
2040
+ q0
2041
+ The initial joint coordinate vector
2042
+ ilimit
2043
+ How many iterations are allowed within a search before a new search
2044
+ is started
2045
+ slimit
2046
+ How many searches are allowed before being deemed unsuccessful
2047
+ tol
2048
+ Maximum allowed residual error E
2049
+ mask
2050
+ A 6 vector which assigns weights to Cartesian degrees-of-freedom
2051
+ error priority
2052
+ joint_limits
2053
+ Reject solutions with joint limit violations
2054
+ seed
2055
+ A seed for the private RNG used to generate random joint coordinate
2056
+ vectors
2057
+ k
2058
+ Sets the gain value for the damping matrix Wn in the next iteration. See
2059
+ synopsis
2060
+ method
2061
+ One of "chan", "sugihara" or "wampler". Defines which method is used
2062
+ to calculate the damping matrix Wn in the ``step`` method
2063
+
2064
+ Synopsis
2065
+ --------
2066
+ The operation is defined by the choice of the ``method`` kwarg.
2067
+
2068
+ The step is deined as
2069
+
2070
+ .. math::
2071
+
2072
+ \vec{q}_{k+1}
2073
+ &=
2074
+ \vec{q}_k +
2075
+ \left(
2076
+ \mat{A}_k
2077
+ \right)^{-1}
2078
+ \bf{g}_k \\
2079
+ %
2080
+ \mat{A}_k
2081
+ &=
2082
+ {\mat{J}(\vec{q}_k)}^\top
2083
+ \mat{W}_e \
2084
+ {\mat{J}(\vec{q}_k)}
2085
+ +
2086
+ \mat{W}_n
2087
+
2088
+ where :math:`\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})` is a
2089
+ diagonal damping matrix. The damping matrix ensures that :math:`\mat{A}_k` is
2090
+ non-singular and positive definite. The performance of the LM method largely depends
2091
+ on the choice of :math:`\mat{W}_n`.
2092
+
2093
+ *Chan's Method*
2094
+
2095
+ Chan proposed
2096
+
2097
+ .. math::
2098
+
2099
+ \mat{W}_n
2100
+ =
2101
+ λ E_k \mat{1}_n
2102
+
2103
+ where λ is a constant which reportedly does not have much influence on performance.
2104
+ Use the kwarg `k` to adjust the weighting term λ.
2105
+
2106
+ *Sugihara's Method*
2107
+
2108
+ Sugihara proposed
2109
+
2110
+ .. math::
2111
+
2112
+ \mat{W}_n
2113
+ =
2114
+ E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)
2115
+
2116
+ where :math:`\hat{\vec{w}}_n \in \mathbb{R}^n`, :math:`\hat{w}_{n_i} = l^2 \sim 0.01 l^2`,
2117
+ and :math:`l` is the length of a typical link within the manipulator. We provide the
2118
+ variable `k` as a kwarg to adjust the value of :math:`w_n`.
2119
+
2120
+ *Wampler's Method*
2121
+
2122
+ Wampler proposed :math:`\vec{w_n}` to be a constant. This is set through the `k` kwarg.
2123
+
2124
+ Examples
2125
+ --------
2126
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2127
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2128
+ ``Tep`` using the `ikine_LM` method.
2129
+
2130
+ .. runblock:: pycon
2131
+ >>> import roboticstoolbox as rtb
2132
+ >>> panda = rtb.models.Panda().ets()
2133
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2134
+ >>> panda.ikine_LM(Tep)
2135
+
2136
+ Notes
2137
+ -----
2138
+ The value for the ``k`` kwarg will depend on the ``method`` chosen and the arm you are
2139
+ using. Use the following as a rough guide ``chan, k = 1.0 - 0.01``,
2140
+ ``wampler, k = 0.01 - 0.0001``, and ``sugihara, k = 0.1 - 0.0001``
2141
+
2142
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2143
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2144
+
2145
+ This class supports null-space motion to assist with maximising manipulability and
2146
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
2147
+
2148
+ References
2149
+ ----------
2150
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2151
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2152
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2153
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2154
+
2155
+ See Also
2156
+ --------
2157
+ ik_NR
2158
+ A fast numerical inverse kinematics solver using Newton-Raphson optimisation
2159
+ ik_GN
2160
+ A fast numerical inverse kinematics solver using Gauss-Newton optimisation
2161
+
2162
+
2163
+ .. versionchanged:: 1.0.4
2164
+ Merged the Levemberg-Marquadt IK solvers into the ik_LM method
2165
+
2166
+ """ # noqa
2167
+
2168
+ return IK_LM_c(
2169
+ self._fknm, Tep, q0, ilimit, slimit, tol, joint_limits, mask, k, method
2170
+ )
2171
+
2172
+ def ik_NR(
2173
+ self,
2174
+ Tep: Union[NDArray, SE3],
2175
+ q0: Union[NDArray, None] = None,
2176
+ ilimit: int = 30,
2177
+ slimit: int = 100,
2178
+ tol: float = 1e-6,
2179
+ mask: Union[NDArray, None] = None,
2180
+ joint_limits: bool = True,
2181
+ pinv: int = True,
2182
+ pinv_damping: float = 0.0,
2183
+ ) -> Tuple[NDArray, int, int, int, float]:
2184
+ r"""
2185
+ Fast numerical inverse kinematics using Newton-Raphson optimization
2186
+
2187
+ ``sol = ets.ik_NR(Tep)`` are the joint coordinates (n) corresponding
2188
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2189
+ This method can be used for robots with any number of degrees of freedom. This
2190
+ is a fast solver implemented in C++.
2191
+
2192
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2193
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2194
+
2195
+ Note
2196
+ ----
2197
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``
2198
+
2199
+ Parameters
2200
+ ----------
2201
+ Tep
2202
+ The desired end-effector pose or pose trajectory
2203
+ q0
2204
+ initial joint configuration (default to random valid joint
2205
+ configuration contrained by the joint limits of the robot)
2206
+ ilimit
2207
+ maximum number of iterations per search
2208
+ slimit
2209
+ maximum number of search attempts
2210
+ tol
2211
+ final error tolerance
2212
+ mask
2213
+ a mask vector which weights the end-effector error priority.
2214
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2215
+ respectively
2216
+ joint_limits
2217
+ constrain the solution to being within the joint limits of
2218
+ the robot (reject solution with invalid joint configurations and perfrom
2219
+ another search up to the slimit)
2220
+ pinv
2221
+ Use the psuedo-inverse instad of the normal matrix inverse
2222
+ pinv_damping
2223
+ Damping factor for the psuedo-inverse
2224
+
2225
+ Returns
2226
+ -------
2227
+ sol
2228
+ tuple (q, success, iterations, searches, residual)
2229
+
2230
+ The return value ``sol`` is a tuple with elements:
2231
+
2232
+ ============ ========== ===============================================
2233
+ Element Type Description
2234
+ ============ ========== ===============================================
2235
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2236
+ ``success`` int whether a solution was found
2237
+ ``iterations`` int total number of iterations
2238
+ ``searches`` int total number of searches
2239
+ ``residual`` float final value of cost function
2240
+ ============ ========== ===============================================
2241
+
2242
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2243
+ solution will be in error. The amount of error is indicated by
2244
+ the ``residual``.
2245
+
2246
+ Synopsis
2247
+ --------
2248
+ Each iteration uses the Newton-Raphson optimisation method
2249
+
2250
+ .. math::
2251
+
2252
+ \vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k
2253
+
2254
+ Examples
2255
+ --------
2256
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2257
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2258
+ ``Tep`` using the `ikine_GN` method.
2259
+
2260
+ .. runblock:: pycon
2261
+ >>> import roboticstoolbox as rtb
2262
+ >>> panda = rtb.models.Panda().ets()
2263
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2264
+ >>> panda.ik_NR(Tep)
2265
+
2266
+ Notes
2267
+ -----
2268
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2269
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2270
+
2271
+ References
2272
+ ----------
2273
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2274
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2275
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2276
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2277
+
2278
+ See Also
2279
+ --------
2280
+ ik_LM
2281
+ A fast numerical inverse kinematics solver using Levenberg-Marquadt optimisation
2282
+ ik_GN
2283
+ A fast numerical inverse kinematics solver using Gauss-Newton optimisation
2284
+
2285
+ """ # noqa
2286
+
2287
+ return IK_NR_c(
2288
+ self._fknm,
2289
+ Tep,
2290
+ q0,
2291
+ ilimit,
2292
+ slimit,
2293
+ tol,
2294
+ joint_limits,
2295
+ mask,
2296
+ pinv,
2297
+ pinv_damping,
2298
+ )
2299
+
2300
+ def ik_GN(
2301
+ self,
2302
+ Tep: Union[NDArray, SE3],
2303
+ q0: Union[NDArray, None] = None,
2304
+ ilimit: int = 30,
2305
+ slimit: int = 100,
2306
+ tol: float = 1e-6,
2307
+ mask: Union[NDArray, None] = None,
2308
+ joint_limits: bool = True,
2309
+ pinv: int = True,
2310
+ pinv_damping: float = 0.0,
2311
+ ) -> Tuple[NDArray, int, int, int, float]:
2312
+ r"""
2313
+ Fast numerical inverse kinematics by Gauss-Newton optimization
2314
+
2315
+ ``sol = ets.ik_GN(Tep)`` are the joint coordinates (n) corresponding
2316
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2317
+ This method can be used for robots with any number of degrees of freedom. This
2318
+ is a fast solver implemented in C++.
2319
+
2320
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2321
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2322
+
2323
+ Note
2324
+ ----
2325
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``
2326
+
2327
+ Parameters
2328
+ ----------
2329
+ Tep
2330
+ The desired end-effector pose or pose trajectory
2331
+ q0
2332
+ initial joint configuration (default to random valid joint
2333
+ configuration contrained by the joint limits of the robot)
2334
+ ilimit
2335
+ maximum number of iterations per search
2336
+ slimit
2337
+ maximum number of search attempts
2338
+ tol
2339
+ final error tolerance
2340
+ mask
2341
+ a mask vector which weights the end-effector error priority.
2342
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2343
+ respectively
2344
+ joint_limits
2345
+ constrain the solution to being within the joint limits of
2346
+ the robot (reject solution with invalid joint configurations and perfrom
2347
+ another search up to the slimit)
2348
+ pinv
2349
+ Use the psuedo-inverse instad of the normal matrix inverse
2350
+ pinv_damping
2351
+ Damping factor for the psuedo-inverse
2352
+
2353
+ Returns
2354
+ -------
2355
+ sol
2356
+ tuple (q, success, iterations, searches, residual)
2357
+
2358
+ The return value ``sol`` is a tuple with elements:
2359
+
2360
+ ============ ========== ===============================================
2361
+ Element Type Description
2362
+ ============ ========== ===============================================
2363
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2364
+ ``success`` int whether a solution was found
2365
+ ``iterations`` int total number of iterations
2366
+ ``searches`` int total number of searches
2367
+ ``residual`` float final value of cost function
2368
+ ============ ========== ===============================================
2369
+
2370
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2371
+ solution will be in error. The amount of error is indicated by
2372
+ the ``residual``.
2373
+
2374
+ Synopsis
2375
+ --------
2376
+ Each iteration uses the Gauss-Newton optimisation method
2377
+
2378
+ .. math::
2379
+
2380
+ \vec{q}_{k+1} &= \vec{q}_k +
2381
+ \left(
2382
+ {\mat{J}(\vec{q}_k)}^\top
2383
+ \mat{W}_e \
2384
+ {\mat{J}(\vec{q}_k)}
2385
+ \right)^{-1}
2386
+ \bf{g}_k \\
2387
+ \bf{g}_k &=
2388
+ {\mat{J}(\vec{q}_k)}^\top
2389
+ \mat{W}_e
2390
+ \vec{e}_k
2391
+
2392
+ where :math:`\mat{J} = {^0\mat{J}}` is the base-frame manipulator Jacobian. If
2393
+ :math:`\mat{J}(\vec{q}_k)` is non-singular, and :math:`\mat{W}_e = \mat{1}_n`, then
2394
+ the above provides the pseudoinverse solution. However, if :math:`\mat{J}(\vec{q}_k)`
2395
+ is singular, the above can not be computed and the GN solution is infeasible.
2396
+
2397
+ Examples
2398
+ --------
2399
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2400
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2401
+ ``Tep`` using the `ikine_GN` method.
2402
+
2403
+ .. runblock:: pycon
2404
+ >>> import roboticstoolbox as rtb
2405
+ >>> panda = rtb.models.Panda().ets()
2406
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2407
+ >>> panda.ik_GN(Tep)
2408
+
2409
+ Notes
2410
+ -----
2411
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2412
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2413
+
2414
+ References
2415
+ ----------
2416
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2417
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2418
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2419
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2420
+
2421
+ See Also
2422
+ --------
2423
+ ik_NR
2424
+ A fast numerical inverse kinematics solver using Newton-Raphson optimisation
2425
+ ik_GN
2426
+ A fast numerical inverse kinematics solver using Gauss-Newton optimisation
2427
+
2428
+ """ # noqa
2429
+
2430
+ return IK_GN_c(
2431
+ self._fknm,
2432
+ Tep,
2433
+ q0,
2434
+ ilimit,
2435
+ slimit,
2436
+ tol,
2437
+ joint_limits,
2438
+ mask,
2439
+ pinv,
2440
+ pinv_damping,
2441
+ )
2442
+
2443
+ def ikine_LM(
2444
+ self,
2445
+ Tep: Union[NDArray, SE3],
2446
+ q0: Union[ArrayLike, None] = None,
2447
+ ilimit: int = 30,
2448
+ slimit: int = 100,
2449
+ tol: float = 1e-6,
2450
+ mask: Union[ArrayLike, None] = None,
2451
+ joint_limits: bool = True,
2452
+ seed: Union[int, None] = None,
2453
+ k: float = 1.0,
2454
+ method: L["chan", "wampler", "sugihara"] = "chan", # noqa
2455
+ kq: float = 0.0,
2456
+ km: float = 0.0,
2457
+ ps: float = 0.0,
2458
+ pi: Union[NDArray, float] = 0.3,
2459
+ **kwargs,
2460
+ ):
2461
+ r"""
2462
+ Levemberg-Marquadt Numerical Inverse Kinematics Solver
2463
+
2464
+ A method which provides functionality to perform numerical inverse kinematics (IK)
2465
+ using the Levemberg-Marquadt method.
2466
+
2467
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2468
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2469
+
2470
+ Parameters
2471
+ ----------
2472
+ Tep
2473
+ The desired end-effector pose
2474
+ q0
2475
+ The initial joint coordinate vector
2476
+ ilimit
2477
+ How many iterations are allowed within a search before a new search
2478
+ is started
2479
+ slimit
2480
+ How many searches are allowed before being deemed unsuccessful
2481
+ tol
2482
+ Maximum allowed residual error E
2483
+ mask
2484
+ A 6 vector which assigns weights to Cartesian degrees-of-freedom
2485
+ error priority
2486
+ joint_limits
2487
+ Reject solutions with joint limit violations
2488
+ seed
2489
+ A seed for the private RNG used to generate random joint coordinate
2490
+ vectors
2491
+ k
2492
+ Sets the gain value for the damping matrix Wn in the next iteration. See
2493
+ synopsis
2494
+ method
2495
+ One of "chan", "sugihara" or "wampler". Defines which method is used
2496
+ to calculate the damping matrix Wn in the ``step`` method
2497
+ kq
2498
+ The gain for joint limit avoidance. Setting to 0.0 will remove this
2499
+ completely from the solution
2500
+ km
2501
+ The gain for maximisation. Setting to 0.0 will remove this completely
2502
+ from the solution
2503
+ ps
2504
+ The minimum angle/distance (in radians or metres) in which the joint is
2505
+ allowed to approach to its limit
2506
+ pi
2507
+ The influence angle/distance (in radians or metres) in null space motion
2508
+ becomes active
2509
+
2510
+ Synopsis
2511
+ --------
2512
+ The operation is defined by the choice of the ``method`` kwarg.
2513
+
2514
+ The step is deined as
2515
+
2516
+ .. math::
2517
+
2518
+ \vec{q}_{k+1}
2519
+ &=
2520
+ \vec{q}_k +
2521
+ \left(
2522
+ \mat{A}_k
2523
+ \right)^{-1}
2524
+ \bf{g}_k \\
2525
+ %
2526
+ \mat{A}_k
2527
+ &=
2528
+ {\mat{J}(\vec{q}_k)}^\top
2529
+ \mat{W}_e \
2530
+ {\mat{J}(\vec{q}_k)}
2531
+ +
2532
+ \mat{W}_n
2533
+
2534
+ where :math:`\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})` is a
2535
+ diagonal damping matrix. The damping matrix ensures that :math:`\mat{A}_k` is
2536
+ non-singular and positive definite. The performance of the LM method largely depends
2537
+ on the choice of :math:`\mat{W}_n`.
2538
+
2539
+ *Chan's Method*
2540
+
2541
+ Chan proposed
2542
+
2543
+ .. math::
2544
+
2545
+ \mat{W}_n
2546
+ =
2547
+ λ E_k \mat{1}_n
2548
+
2549
+ where λ is a constant which reportedly does not have much influence on performance.
2550
+ Use the kwarg `k` to adjust the weighting term λ.
2551
+
2552
+ *Sugihara's Method*
2553
+
2554
+ Sugihara proposed
2555
+
2556
+ .. math::
2557
+
2558
+ \mat{W}_n
2559
+ =
2560
+ E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)
2561
+
2562
+ where :math:`\hat{\vec{w}}_n \in \mathbb{R}^n`, :math:`\hat{w}_{n_i} = l^2 \sim 0.01 l^2`,
2563
+ and :math:`l` is the length of a typical link within the manipulator. We provide the
2564
+ variable `k` as a kwarg to adjust the value of :math:`w_n`.
2565
+
2566
+ *Wampler's Method*
2567
+
2568
+ Wampler proposed :math:`\vec{w_n}` to be a constant. This is set through the `k` kwarg.
2569
+
2570
+ Examples
2571
+ --------
2572
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2573
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2574
+ ``Tep`` using the `ikine_LM` method.
2575
+
2576
+ .. runblock:: pycon
2577
+ >>> import roboticstoolbox as rtb
2578
+ >>> panda = rtb.models.Panda().ets()
2579
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2580
+ >>> panda.ikine_LM(Tep)
2581
+
2582
+ Notes
2583
+ -----
2584
+ The value for the ``k`` kwarg will depend on the ``method`` chosen and the arm you are
2585
+ using. Use the following as a rough guide ``chan, k = 1.0 - 0.01``,
2586
+ ``wampler, k = 0.01 - 0.0001``, and ``sugihara, k = 0.1 - 0.0001``
2587
+
2588
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2589
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2590
+
2591
+ This class supports null-space motion to assist with maximising manipulability and
2592
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
2593
+
2594
+ References
2595
+ ----------
2596
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2597
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2598
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2599
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2600
+
2601
+ See Also
2602
+ --------
2603
+ :py:class:`~roboticstoolbox.robot.IK.IK_LM`
2604
+ An IK Solver class which implements the Levemberg Marquadt optimisation technique
2605
+ ikine_NR
2606
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_NR` class as a method within the :py:class:`ETS` class
2607
+ ikine_GN
2608
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_GN` class as a method within the :py:class:`ETS` class
2609
+ ikine_QP
2610
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_QP` class as a method within the :py:class:`ETS` class
2611
+
2612
+
2613
+ .. versionchanged:: 1.0.4
2614
+ Added the Levemberg-Marquadt IK solver method on the `ETS` class
2615
+
2616
+ """ # noqa
2617
+
2618
+ solver = IK_LM(
2619
+ ilimit=ilimit,
2620
+ slimit=slimit,
2621
+ tol=tol,
2622
+ joint_limits=joint_limits,
2623
+ mask=mask,
2624
+ seed=seed,
2625
+ k=k,
2626
+ method=method,
2627
+ kq=kq,
2628
+ km=km,
2629
+ ps=ps,
2630
+ pi=pi,
2631
+ **kwargs,
2632
+ )
2633
+
2634
+ # if isinstance(Tep, SE3):
2635
+ # Tep = Tep.A
2636
+
2637
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
2638
+
2639
+ def ikine_NR(
2640
+ self,
2641
+ Tep: Union[NDArray, SE3],
2642
+ q0: Union[ArrayLike, None] = None,
2643
+ ilimit: int = 30,
2644
+ slimit: int = 100,
2645
+ tol: float = 1e-6,
2646
+ mask: Union[ArrayLike, None] = None,
2647
+ joint_limits: bool = True,
2648
+ seed: Union[int, None] = None,
2649
+ pinv: bool = False,
2650
+ kq: float = 0.0,
2651
+ km: float = 0.0,
2652
+ ps: float = 0.0,
2653
+ pi: Union[NDArray, float] = 0.3,
2654
+ **kwargs,
2655
+ ):
2656
+ r"""
2657
+ Newton-Raphson Numerical Inverse Kinematics Solver
2658
+
2659
+ A method which provides functionality to perform numerical inverse kinematics (IK)
2660
+ using the Newton-Raphson method.
2661
+
2662
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2663
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2664
+
2665
+ Note
2666
+ ----
2667
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``
2668
+
2669
+ Parameters
2670
+ ----------
2671
+ Tep
2672
+ The desired end-effector pose
2673
+ q0
2674
+ The initial joint coordinate vector
2675
+ ilimit
2676
+ How many iterations are allowed within a search before a new search
2677
+ is started
2678
+ slimit
2679
+ How many searches are allowed before being deemed unsuccessful
2680
+ tol
2681
+ Maximum allowed residual error E
2682
+ mask
2683
+ A 6 vector which assigns weights to Cartesian degrees-of-freedom
2684
+ error priority
2685
+ joint_limits
2686
+ Reject solutions with joint limit violations
2687
+ seed
2688
+ A seed for the private RNG used to generate random joint coordinate
2689
+ vectors
2690
+ pinv
2691
+ If True, will use the psuedoinverse in the `step` method instead of
2692
+ the normal inverse
2693
+ kq
2694
+ The gain for joint limit avoidance. Setting to 0.0 will remove this
2695
+ completely from the solution
2696
+ km
2697
+ The gain for maximisation. Setting to 0.0 will remove this completely
2698
+ from the solution
2699
+ ps
2700
+ The minimum angle/distance (in radians or metres) in which the joint is
2701
+ allowed to approach to its limit
2702
+ pi
2703
+ The influence angle/distance (in radians or metres) in null space motion
2704
+ becomes active
2705
+
2706
+ Synopsis
2707
+ --------
2708
+ Each iteration uses the Newton-Raphson optimisation method
2709
+
2710
+ .. math::
2711
+
2712
+ \vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k
2713
+
2714
+ Examples
2715
+ --------
2716
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2717
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2718
+ ``Tep`` using the `ikine_NR` method.
2719
+
2720
+ .. runblock:: pycon
2721
+ >>> import roboticstoolbox as rtb
2722
+ >>> panda = rtb.models.Panda().ets()
2723
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2724
+ >>> panda.ikine_NR(Tep)
2725
+
2726
+ Notes
2727
+ -----
2728
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2729
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2730
+
2731
+ This class supports null-space motion to assist with maximising manipulability and
2732
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
2733
+
2734
+ References
2735
+ ----------
2736
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2737
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2738
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2739
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2740
+
2741
+ See Also
2742
+ --------
2743
+ :py:class:`~roboticstoolbox.robot.IK.IK_NR`
2744
+ An IK Solver class which implements the Newton-Raphson optimisation technique
2745
+ ikine_LM
2746
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_LM` class as a method within the :py:class:`ETS` class
2747
+ ikine_GN
2748
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_GN` class as a method within the :py:class:`ETS` class
2749
+ ikine_QP
2750
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_QP` class as a method within the :py:class:`ETS` class
2751
+
2752
+
2753
+ .. versionchanged:: 1.0.4
2754
+ Added the Newton-Raphson IK solver method on the `ETS` class
2755
+
2756
+ """ # noqa
2757
+
2758
+ solver = IK_NR(
2759
+ ilimit=ilimit,
2760
+ slimit=slimit,
2761
+ tol=tol,
2762
+ joint_limits=joint_limits,
2763
+ mask=mask,
2764
+ seed=seed,
2765
+ pinv=pinv,
2766
+ kq=kq,
2767
+ km=km,
2768
+ ps=ps,
2769
+ pi=pi,
2770
+ **kwargs,
2771
+ )
2772
+
2773
+ # if isinstance(Tep, SE3):
2774
+ # Tep = Tep.A
2775
+
2776
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
2777
+
2778
+ def ikine_GN(
2779
+ self,
2780
+ Tep: Union[NDArray, SE3],
2781
+ q0: Union[ArrayLike, None] = None,
2782
+ ilimit: int = 30,
2783
+ slimit: int = 100,
2784
+ tol: float = 1e-6,
2785
+ mask: Union[ArrayLike, None] = None,
2786
+ joint_limits: bool = True,
2787
+ seed: Union[int, None] = None,
2788
+ pinv: bool = False,
2789
+ kq: float = 0.0,
2790
+ km: float = 0.0,
2791
+ ps: float = 0.0,
2792
+ pi: Union[NDArray, float] = 0.3,
2793
+ **kwargs,
2794
+ ):
2795
+ r"""
2796
+ Gauss-Newton Numerical Inverse Kinematics Solver
2797
+
2798
+ A method which provides functionality to perform numerical inverse kinematics (IK)
2799
+ using the Gauss-Newton method.
2800
+
2801
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2802
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2803
+
2804
+ Note
2805
+ ----
2806
+ When using this method with redundant robots (>6 DoF), ``pinv`` must be set to ``True``
2807
+
2808
+ Parameters
2809
+ ----------
2810
+ Tep
2811
+ The desired end-effector pose
2812
+ q0
2813
+ The initial joint coordinate vector
2814
+ ilimit
2815
+ How many iterations are allowed within a search before a new search
2816
+ is started
2817
+ slimit
2818
+ How many searches are allowed before being deemed unsuccessful
2819
+ tol
2820
+ Maximum allowed residual error E
2821
+ mask
2822
+ A 6 vector which assigns weights to Cartesian degrees-of-freedom
2823
+ error priority
2824
+ joint_limits
2825
+ Reject solutions with joint limit violations
2826
+ seed
2827
+ A seed for the private RNG used to generate random joint coordinate
2828
+ vectors
2829
+ pinv
2830
+ If True, will use the psuedoinverse in the `step` method instead of
2831
+ the normal inverse
2832
+ kq
2833
+ The gain for joint limit avoidance. Setting to 0.0 will remove this
2834
+ completely from the solution
2835
+ km
2836
+ The gain for maximisation. Setting to 0.0 will remove this completely
2837
+ from the solution
2838
+ ps
2839
+ The minimum angle/distance (in radians or metres) in which the joint is
2840
+ allowed to approach to its limit
2841
+ pi
2842
+ The influence angle/distance (in radians or metres) in null space motion
2843
+ becomes active
2844
+
2845
+ Synopsis
2846
+ --------
2847
+ Each iteration uses the Gauss-Newton optimisation method
2848
+
2849
+ .. math::
2850
+
2851
+ \vec{q}_{k+1} &= \vec{q}_k +
2852
+ \left(
2853
+ {\mat{J}(\vec{q}_k)}^\top
2854
+ \mat{W}_e \
2855
+ {\mat{J}(\vec{q}_k)}
2856
+ \right)^{-1}
2857
+ \bf{g}_k \\
2858
+ \bf{g}_k &=
2859
+ {\mat{J}(\vec{q}_k)}^\top
2860
+ \mat{W}_e
2861
+ \vec{e}_k
2862
+
2863
+ where :math:`\mat{J} = {^0\mat{J}}` is the base-frame manipulator Jacobian. If
2864
+ :math:`\mat{J}(\vec{q}_k)` is non-singular, and :math:`\mat{W}_e = \mat{1}_n`, then
2865
+ the above provides the pseudoinverse solution. However, if :math:`\mat{J}(\vec{q}_k)`
2866
+ is singular, the above can not be computed and the GN solution is infeasible.
2867
+
2868
+ Examples
2869
+ --------
2870
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
2871
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
2872
+ ``Tep`` using the `ikine_GN` method.
2873
+
2874
+ .. runblock:: pycon
2875
+ >>> import roboticstoolbox as rtb
2876
+ >>> panda = rtb.models.Panda().ets()
2877
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
2878
+ >>> panda.ikine_GN(Tep)
2879
+
2880
+ Notes
2881
+ -----
2882
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
2883
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
2884
+
2885
+ This class supports null-space motion to assist with maximising manipulability and
2886
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
2887
+
2888
+ References
2889
+ ----------
2890
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
2891
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
2892
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
2893
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
2894
+
2895
+ See Also
2896
+ --------
2897
+ :py:class:`~roboticstoolbox.robot.IK.IK_NR`
2898
+ An IK Solver class which implements the Newton-Raphson optimisation technique
2899
+ ikine_LM
2900
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_LM` class as a method within the :py:class:`ETS` class
2901
+ ikine_NR
2902
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_NR` class as a method within the :py:class:`ETS` class
2903
+ ikine_QP
2904
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_QP` class as a method within the :py:class:`ETS` class
2905
+
2906
+
2907
+ .. versionchanged:: 1.0.4
2908
+ Added the Gauss-Newton IK solver method on the `ETS` class
2909
+
2910
+ """ # noqa
2911
+
2912
+ solver = IK_GN(
2913
+ ilimit=ilimit,
2914
+ slimit=slimit,
2915
+ tol=tol,
2916
+ joint_limits=joint_limits,
2917
+ mask=mask,
2918
+ seed=seed,
2919
+ pinv=pinv,
2920
+ kq=kq,
2921
+ km=km,
2922
+ ps=ps,
2923
+ pi=pi,
2924
+ **kwargs,
2925
+ )
2926
+
2927
+ # if isinstance(Tep, SE3):
2928
+ # Tep = Tep.A
2929
+
2930
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
2931
+
2932
+ def ikine_QP(
2933
+ self,
2934
+ Tep: Union[NDArray, SE3],
2935
+ q0: Union[ArrayLike, None] = None,
2936
+ ilimit: int = 30,
2937
+ slimit: int = 100,
2938
+ tol: float = 1e-6,
2939
+ mask: Union[ArrayLike, None] = None,
2940
+ joint_limits: bool = True,
2941
+ seed: Union[int, None] = None,
2942
+ kj=1.0,
2943
+ ks=1.0,
2944
+ kq: float = 0.0,
2945
+ km: float = 0.0,
2946
+ ps: float = 0.0,
2947
+ pi: Union[NDArray, float] = 0.3,
2948
+ **kwargs,
2949
+ ):
2950
+ r"""
2951
+ Quadratic Programming Numerical Inverse Kinematics Solver
2952
+
2953
+ A method that provides functionality to perform numerical inverse kinematics
2954
+ (IK) using a quadratic progamming approach.
2955
+
2956
+ See the :ref:`Inverse Kinematics Docs Page <IK>` for more details and for a
2957
+ **tutorial** on numerical IK, see `here <https://bit.ly/3ak5GDi>`_.
2958
+
2959
+ Parameters
2960
+ ----------
2961
+ Tep
2962
+ The desired end-effector pose
2963
+ q0
2964
+ The initial joint coordinate vector
2965
+ ilimit
2966
+ How many iterations are allowed within a search before a new search
2967
+ is started
2968
+ slimit
2969
+ How many searches are allowed before being deemed unsuccessful
2970
+ tol
2971
+ Maximum allowed residual error E
2972
+ mask
2973
+ A 6 vector which assigns weights to Cartesian degrees-of-freedom
2974
+ error priority
2975
+ joint_limits
2976
+ Reject solutions with joint limit violations
2977
+ seed
2978
+ A seed for the private RNG used to generate random joint coordinate
2979
+ vectors
2980
+ kj
2981
+ A gain for joint velocity norm minimisation
2982
+ ks
2983
+ A gain which adjusts the cost of slack (intentional error)
2984
+ kq
2985
+ The gain for joint limit avoidance. Setting to 0.0 will remove this
2986
+ completely from the solution
2987
+ km
2988
+ The gain for maximisation. Setting to 0.0 will remove this completely
2989
+ from the solution
2990
+ ps
2991
+ The minimum angle/distance (in radians or metres) in which the joint is
2992
+ allowed to approach to its limit
2993
+ pi
2994
+ The influence angle/distance (in radians or metres) in null space motion
2995
+ becomes active
2996
+
2997
+ Raises
2998
+ ------
2999
+ ImportError
3000
+ If the package ``qpsolvers`` is not installed
3001
+
3002
+ Synopsis
3003
+ --------
3004
+ Each iteration uses the following approach
3005
+
3006
+ .. math::
3007
+
3008
+ \vec{q}_{k+1} = \vec{q}_{k} + \dot{\vec{q}}.
3009
+
3010
+ where the QP is defined as
3011
+
3012
+ .. math::
3013
+
3014
+ \min_x \quad f_o(\vec{x}) &= \frac{1}{2} \vec{x}^\top \mathcal{Q} \vec{x}+ \mathcal{C}^\top \vec{x}, \\
3015
+ \text{subject to} \quad \mathcal{J} \vec{x} &= \vec{\nu}, \\
3016
+ \mathcal{A} \vec{x} &\leq \mathcal{B}, \\
3017
+ \vec{x}^- &\leq \vec{x} \leq \vec{x}^+
3018
+
3019
+ with
3020
+
3021
+ .. math::
3022
+
3023
+ \vec{x} &=
3024
+ \begin{pmatrix}
3025
+ \dvec{q} \\ \vec{\delta}
3026
+ \end{pmatrix} \in \mathbb{R}^{(n+6)} \\
3027
+ \mathcal{Q} &=
3028
+ \begin{pmatrix}
3029
+ \lambda_q \mat{1}_{n} & \mathbf{0}_{6 \times 6} \\ \mathbf{0}_{n \times n} & \lambda_\delta \mat{1}_{6}
3030
+ \end{pmatrix} \in \mathbb{R}^{(n+6) \times (n+6)} \\
3031
+ \mathcal{J} &=
3032
+ \begin{pmatrix}
3033
+ \mat{J}(\vec{q}) & \mat{1}_{6}
3034
+ \end{pmatrix} \in \mathbb{R}^{6 \times (n+6)} \\
3035
+ \mathcal{C} &=
3036
+ \begin{pmatrix}
3037
+ \mat{J}_m \\ \bf{0}_{6 \times 1}
3038
+ \end{pmatrix} \in \mathbb{R}^{(n + 6)} \\
3039
+ \mathcal{A} &=
3040
+ \begin{pmatrix}
3041
+ \mat{1}_{n \times n + 6} \\
3042
+ \end{pmatrix} \in \mathbb{R}^{(l + n) \times (n + 6)} \\
3043
+ \mathcal{B} &=
3044
+ \eta
3045
+ \begin{pmatrix}
3046
+ \frac{\rho_0 - \rho_s}
3047
+ {\rho_i - \rho_s} \\
3048
+ \vdots \\
3049
+ \frac{\rho_n - \rho_s}
3050
+ {\rho_i - \rho_s}
3051
+ \end{pmatrix} \in \mathbb{R}^{n} \\
3052
+ \vec{x}^{-, +} &=
3053
+ \begin{pmatrix}
3054
+ \dvec{q}^{-, +} \\
3055
+ \vec{\delta}^{-, +}
3056
+ \end{pmatrix} \in \mathbb{R}^{(n+6)},
3057
+
3058
+ where :math:`\vec{\delta} \in \mathbb{R}^6` is the slack vector,
3059
+ :math:`\lambda_\delta \in \mathbb{R}^+` is a gain term which adjusts the
3060
+ cost of the norm of the slack vector in the optimiser,
3061
+ :math:`\dvec{q}^{-,+}` are the minimum and maximum joint velocities, and
3062
+ :math:`\dvec{\delta}^{-,+}` are the minimum and maximum slack velocities.
3063
+
3064
+ Examples
3065
+ --------
3066
+ The following example gets the ``ets`` of a ``panda`` robot object, makes a goal
3067
+ pose ``Tep``, and then solves for the joint coordinates which result in the pose
3068
+ ``Tep`` using the `ikine_QP` method.
3069
+
3070
+ .. runblock:: pycon
3071
+ >>> import roboticstoolbox as rtb
3072
+ >>> panda = rtb.models.Panda().ets()
3073
+ >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
3074
+ >>> panda.ikine_QP(Tep)
3075
+
3076
+ Notes
3077
+ -----
3078
+ When using the this method, the initial joint coordinates :math:`q_0`, should correspond
3079
+ to a non-singular manipulator pose, since it uses the manipulator Jacobian.
3080
+
3081
+ This class supports null-space motion to assist with maximising manipulability and
3082
+ avoiding joint limits. These are enabled by setting kq and km to non-zero values.
3083
+
3084
+ References
3085
+ ----------
3086
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part I:
3087
+ Kinematics, Velocity, and Applications." arXiv preprint arXiv:2207.01796 (2022).
3088
+ - J. Haviland, and P. Corke. "Manipulator Differential Kinematics Part II:
3089
+ Acceleration and Advanced Applications." arXiv preprint arXiv:2207.01794 (2022).
3090
+
3091
+ See Also
3092
+ --------
3093
+ :py:class:`~roboticstoolbox.robot.IK.IK_NR`
3094
+ An IK Solver class which implements the Newton-Raphson optimisation technique
3095
+ ikine_LM
3096
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_LM` class as a method within the :py:class:`ETS` class
3097
+ ikine_GN
3098
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_GN` class as a method within the :py:class:`ETS` class
3099
+ ikine_NR
3100
+ Implements the :py:class:`~roboticstoolbox.robot.IK.IK_NR` class as a method within the :py:class:`ETS` class
3101
+
3102
+
3103
+ .. versionchanged:: 1.0.4
3104
+ Added the Quadratic Programming IK solver method on the `ETS` class
3105
+
3106
+ """ # noqa: E501
3107
+
3108
+ solver = IK_QP(
3109
+ ilimit=ilimit,
3110
+ slimit=slimit,
3111
+ tol=tol,
3112
+ joint_limits=joint_limits,
3113
+ mask=mask,
3114
+ seed=seed,
3115
+ kj=kj,
3116
+ ks=ks,
3117
+ kq=kq,
3118
+ km=km,
3119
+ ps=ps,
3120
+ pi=pi,
3121
+ **kwargs,
3122
+ )
3123
+
3124
+ # if isinstance(Tep, SE3):
3125
+ # Tep = Tep.A
3126
+
3127
+ return solver.solve(ets=self, Tep=Tep, q0=q0)
3128
+
3129
+
3130
+ class ETS2(BaseETS):
3131
+ """
3132
+ This class implements an elementary transform sequence (ETS) for 2D
3133
+
3134
+ :param arg: Function to compute ET value
3135
+
3136
+ An instance can contain an elementary transform (ET) or an elementary
3137
+ transform sequence (ETS). It has list-like properties by subclassing
3138
+ UserList, which means we can perform indexing, slicing pop, insert, as well
3139
+ as using it as an iterator over its values.
3140
+
3141
+ - ``ETS()`` an empty ETS list
3142
+ - ``ET2.XY(η)`` is a constant elementary transform
3143
+ - ``ET2.XY(η, 'deg')`` as above but the angle is expressed in degrees
3144
+ - ``ET2.XY()`` is a joint variable, the value is left free until evaluation
3145
+ time
3146
+ - ``ET2.XY(j=J)`` as above but the joint index is explicitly given, this
3147
+ might correspond to the joint number of a multi-joint robot.
3148
+ - ``ET2.XY(flip=True)`` as above but the joint moves in the opposite sense
3149
+
3150
+ where ``XY`` is one of ``R``, ``tx``, ``ty``.
3151
+
3152
+ Example:
3153
+
3154
+ .. runblock:: pycon
3155
+
3156
+ >>> from roboticstoolbox import ETS2 as ET2
3157
+ >>> e = ET2.R(0.3) # a single ET, rotation about z
3158
+ >>> len(e)
3159
+ >>> e = ET2.R(0.3) * ET2.tx(2) # an ETS
3160
+ >>> len(e) # of length 2
3161
+ >>> e[1] # an ET sliced from the ETS
3162
+
3163
+ :references:
3164
+ - Kinematic Derivatives using the Elementary Transform Sequence,
3165
+ J. Haviland and P. Corke
3166
+
3167
+ :seealso: :func:`r`, :func:`tx`, :func:`ty`
3168
+ """
3169
+
3170
+ def __init__(
3171
+ self,
3172
+ arg: Union[
3173
+ List[Union["ETS2", ET2]], List[ET2], List["ETS2"], ET2, "ETS2", None
3174
+ ] = None,
3175
+ ):
3176
+ super().__init__()
3177
+ if isinstance(arg, list):
3178
+ for item in arg:
3179
+ if isinstance(item, ET2):
3180
+ self.data.append(deepcopy(item))
3181
+ elif isinstance(item, ETS2):
3182
+ for ets_item in item:
3183
+ self.data.append(deepcopy(ets_item))
3184
+ else:
3185
+ raise TypeError("bad arg")
3186
+ elif isinstance(arg, ET2):
3187
+ self.data.append(deepcopy(arg))
3188
+ elif isinstance(arg, ETS2):
3189
+ for ets_item in arg:
3190
+ self.data.append(deepcopy(ets_item))
3191
+ elif arg is None:
3192
+ self.data = []
3193
+ else:
3194
+ raise TypeError("Invalid arg")
3195
+
3196
+ self._update_internals()
3197
+ self._ndims = 2
3198
+ self._auto_jindex = False
3199
+
3200
+ # Check if jindices are set
3201
+ joints = self.joints()
3202
+
3203
+ # Number of joints with a jindex
3204
+ jindices = 0
3205
+
3206
+ # Number of joints with a sequential jindex (j[2] -> jindex = 2)
3207
+ seq_jindex = 0
3208
+
3209
+ # Count them up
3210
+ for j, joint in enumerate(joints):
3211
+ if joint.jindex is not None:
3212
+ jindices += 1
3213
+ if joint.jindex == j:
3214
+ seq_jindex += 1
3215
+
3216
+ if (
3217
+ jindices == self.n - 1
3218
+ and seq_jindex == self.n - 1
3219
+ and joints[-1].jindex is None
3220
+ ):
3221
+ # ets has sequential jindicies, except for the last.
3222
+ joints[-1].jindex = self.n - 1
3223
+ self._auto_jindex = True
3224
+ elif jindices > 0 and not jindices == self.n:
3225
+ raise ValueError(
3226
+ "You can not have some jindices set for the ET's in arg. It must be all"
3227
+ " or none"
3228
+ ) # pragma: nocover
3229
+ elif jindices == 0 and self.n > 0:
3230
+ # Set them ourself
3231
+ for j, joint in enumerate(joints):
3232
+ joint.jindex = j
3233
+ self._auto_jindex = True
3234
+
3235
+ def __mul__(self, other: Union[ET2, "ETS2"]) -> "ETS2":
3236
+ if isinstance(other, ET2):
3237
+ return ETS2([*self.data, other])
3238
+ else:
3239
+ return ETS2([*self.data, *other.data]) # pragma: nocover
3240
+
3241
+ def __rmul__(self, other: Union[ET2, "ETS2"]) -> "ETS2":
3242
+ return ETS2([other, self.data]) # pragma: nocover
3243
+
3244
+ def __imul__(self, rest: "ETS2"):
3245
+ return self + rest # pragma: nocover
3246
+
3247
+ def __add__(self, rest) -> "ETS2":
3248
+ return self.__mul__(rest) # pragma: nocover
3249
+
3250
+ def compile(self) -> "ETS2":
3251
+ """
3252
+ Compile an ETS2
3253
+
3254
+ :return: optimised ETS2
3255
+
3256
+ Perform constant folding for faster evaluation. Consecutive constant
3257
+ ETs are compounded, leading to a constant ET which is denoted by
3258
+ ``SE3`` when displayed.
3259
+
3260
+ :seealso: :func:`isconstant`
3261
+ """
3262
+ const = None
3263
+ ets = ETS2()
3264
+
3265
+ for et in self:
3266
+ if et.isjoint:
3267
+ # a joint
3268
+ if const is not None:
3269
+ # flush the constant
3270
+ if not np.array_equal(const, np.eye(3)):
3271
+ ets *= ET2.SE2(const)
3272
+ const = None
3273
+ ets *= et # emit the joint ET
3274
+ else:
3275
+ # not a joint
3276
+ if const is None:
3277
+ const = et.A()
3278
+ else:
3279
+ const = const @ et.A()
3280
+
3281
+ if const is not None:
3282
+ # flush the constant, tool transform
3283
+ if not np.array_equal(const, np.eye(3)):
3284
+ ets *= ET2.SE2(const)
3285
+ return ets
3286
+
3287
+ def insert(
3288
+ self,
3289
+ arg: Union[ET2, "ETS2"],
3290
+ i: int = -1,
3291
+ ) -> None:
3292
+ """
3293
+ Insert value
3294
+
3295
+ :param i: insert an ET or ETS into the ETS, default is at the end
3296
+ :param arg: the elementary transform or sequence to insert
3297
+
3298
+ Inserts an ET or ETS into the ET sequence. The inserted value is at position
3299
+ ``i``.
3300
+
3301
+ Example:
3302
+
3303
+ .. runblock:: pycon
3304
+
3305
+ >>> from roboticstoolbox import ET2
3306
+ >>> e = ET2.R() * ET2.tx(1) * ET2.R() * ET2.tx(1)
3307
+ >>> f = ET2.R()
3308
+ >>> e.insert(f, 2)
3309
+ >>> e
3310
+ """
3311
+
3312
+ if isinstance(arg, ET2):
3313
+ if i == -1:
3314
+ self.data.append(arg)
3315
+ else:
3316
+ self.data.insert(i, arg)
3317
+ elif isinstance(arg, ETS2):
3318
+ if i == -1:
3319
+ for et in arg:
3320
+ self.data.append(et)
3321
+ else:
3322
+ for j, et in enumerate(arg):
3323
+ self.data.insert(i + j, et)
3324
+ self._update_internals()
3325
+
3326
+ def fkine(
3327
+ self,
3328
+ q: ArrayLike,
3329
+ base: Union[NDArray, SE2, None] = None,
3330
+ tool: Union[NDArray, SE2, None] = None,
3331
+ include_base: bool = True,
3332
+ ) -> SE2:
3333
+ """
3334
+ Forward kinematics
3335
+ :param q: Joint coordinates
3336
+ :type q: ArrayLike
3337
+ :param base: base transform, optional
3338
+ :param tool: tool transform, optional
3339
+
3340
+ :return: The transformation matrix representing the pose of the
3341
+ end-effector
3342
+
3343
+ - ``T = ets.fkine(q)`` evaluates forward kinematics for the robot at
3344
+ joint configuration ``q``.
3345
+ **Trajectory operation**:
3346
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
3347
+ result is an ``SE2`` instance with ``m`` values.
3348
+ .. note::
3349
+ - The robot's base tool transform, if set, is incorporated
3350
+ into the result.
3351
+ - A tool transform, if provided, is incorporated into the result.
3352
+ - Works from the end-effector link to the base
3353
+ :references:
3354
+ - Kinematic Derivatives using the Elementary Transform
3355
+ Sequence, J. Haviland and P. Corke
3356
+ """
3357
+
3358
+ ret = SE2.Empty()
3359
+ fk = self.eval(q, base, tool, include_base)
3360
+
3361
+ if fk.dtype == "O":
3362
+ # symbolic
3363
+ fk = np.array(simplify(fk))
3364
+
3365
+ if fk.ndim == 3:
3366
+ for T in fk:
3367
+ ret.append(SE2(T, check=False)) # type: ignore
3368
+ else:
3369
+ ret = SE2(fk, check=False)
3370
+
3371
+ return ret
3372
+
3373
+ def eval(
3374
+ self,
3375
+ q: ArrayLike,
3376
+ base: Union[NDArray, SE2, None] = None,
3377
+ tool: Union[NDArray, SE2, None] = None,
3378
+ include_base: bool = True,
3379
+ ) -> NDArray:
3380
+ """
3381
+ Forward kinematics
3382
+ :param q: Joint coordinates
3383
+ :type q: ArrayLike
3384
+ :param base: base transform, optional
3385
+ :param tool: tool transform, optional
3386
+
3387
+ :return: The transformation matrix representing the pose of the
3388
+ end-effector
3389
+
3390
+ - ``T = ets.fkine(q)`` evaluates forward kinematics for the robot at
3391
+ joint configuration ``q``.
3392
+ **Trajectory operation**:
3393
+ If ``q`` has multiple rows (mxn), it is considered a trajectory and the
3394
+ result is an ``SE2`` instance with ``m`` values.
3395
+ .. note::
3396
+ - The robot's base tool transform, if set, is incorporated
3397
+ into the result.
3398
+ - A tool transform, if provided, is incorporated into the result.
3399
+ - Works from the end-effector link to the base
3400
+ :references:
3401
+ - Kinematic Derivatives using the Elementary Transform
3402
+ Sequence, J. Haviland and P. Corke
3403
+ """
3404
+
3405
+ q = getmatrix(q, (None, None))
3406
+ l, _ = q.shape # type: ignore
3407
+ end = self[-1]
3408
+
3409
+ if base is None:
3410
+ bases = None
3411
+ elif isinstance(base, SE2):
3412
+ bases = np.array(base.A)
3413
+ elif np.array_equal(base, np.eye(3)): # pragma: nocover
3414
+ bases = None
3415
+ else: # pragma: nocover
3416
+ bases = base
3417
+
3418
+ if tool is None:
3419
+ tools = None
3420
+ elif isinstance(tool, SE2):
3421
+ tools = np.array(tool.A)
3422
+ elif np.array_equal(tool, np.eye(3)): # pragma: nocover
3423
+ tools = None
3424
+ else: # pragma: nocover
3425
+ tools = tool
3426
+
3427
+ if l > 1:
3428
+ T = np.zeros((l, 3, 3), dtype=object)
3429
+ else:
3430
+ T = np.zeros((3, 3), dtype=object)
3431
+
3432
+ for k, qk in enumerate(q): # type: ignore
3433
+ link = end # start with last link
3434
+
3435
+ jindex = 0 if link.jindex is None and link.isjoint else link.jindex
3436
+ Tk = link.A(qk[jindex])
3437
+
3438
+ if tools is not None:
3439
+ Tk = Tk @ tools
3440
+
3441
+ # add remaining links, back toward the base
3442
+ for i in range(self.m - 2, -1, -1):
3443
+ link = self.data[i]
3444
+
3445
+ jindex = 0 if link.jindex is None and link.isjoint else link.jindex
3446
+ A = link.A(qk[jindex])
3447
+
3448
+ if A is not None:
3449
+ Tk = A @ Tk
3450
+
3451
+ # add base transform if it is set
3452
+ if include_base is True and bases is not None:
3453
+ Tk = bases @ Tk
3454
+
3455
+ # append
3456
+ if l > 1:
3457
+ T[k, :, :] = Tk
3458
+ # ret.append(SE2(Tk, check=False)) # type: ignore
3459
+ else:
3460
+ T = Tk
3461
+ # ret = SE2(Tk, check=False)
3462
+
3463
+ return T
3464
+
3465
+ def jacob0(
3466
+ self,
3467
+ q: ArrayLike,
3468
+ ) -> NDArray:
3469
+ # very inefficient implementation, just put a 1 in last row
3470
+ # if its a rotation joint
3471
+ q = getvector(q)
3472
+
3473
+ j = 0
3474
+ J = np.zeros((3, self.n))
3475
+ etjoints = self.joint_idx()
3476
+
3477
+ if not np.all(np.array([self[i].jindex for i in etjoints])):
3478
+ # not all joints have a jindex it is required, set them
3479
+ for j in range(self.n):
3480
+ i = etjoints[j]
3481
+ self[i].jindex = j
3482
+
3483
+ for j in range(self.n):
3484
+ i = etjoints[j]
3485
+
3486
+ if self[i].jindex is not None:
3487
+ jindex = self[i].jindex
3488
+ else:
3489
+ jindex = 0 # pragma: nocover
3490
+
3491
+ # jindex = 0 if self[i].jindex is None else self[i].jindex
3492
+
3493
+ axis = self[i].axis
3494
+ if axis == "R":
3495
+ dTdq = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 0]]) @ self[i].A(
3496
+ q[jindex] # type: ignore
3497
+ )
3498
+ elif axis == "tx":
3499
+ dTdq = np.array([[0, 0, 1], [0, 0, 0], [0, 0, 0]])
3500
+ elif axis == "ty":
3501
+ dTdq = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 0]])
3502
+ else: # pragma: nocover
3503
+ raise TypeError("Invalid axes")
3504
+
3505
+ E0 = ETS2(self[:i])
3506
+ if len(E0) > 0:
3507
+ dTdq = E0.fkine(q).A @ dTdq
3508
+
3509
+ Ef = ETS2(self[i + 1 :])
3510
+ if len(Ef) > 0:
3511
+ dTdq = dTdq @ Ef.fkine(q).A
3512
+
3513
+ T = self.fkine(q).A
3514
+ dRdt = dTdq[:2, :2] @ T[:2, :2].T
3515
+
3516
+ J[:2, j] = dTdq[:2, 2]
3517
+ J[2, j] = dRdt[1, 0]
3518
+
3519
+ return J
3520
+
3521
+ def jacobe(
3522
+ self,
3523
+ q: ArrayLike,
3524
+ ):
3525
+ r"""
3526
+ Jacobian in base frame
3527
+
3528
+ :param q: joint coordinates
3529
+ :type q: ArrayLike
3530
+ :return: Jacobian matrix
3531
+
3532
+ ``jacobe(q)`` is the manipulator Jacobian matrix which maps joint
3533
+ velocity to end-effector spatial velocity.
3534
+
3535
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
3536
+ is related to joint velocity by :math:`{}^{e}\nu = {}^{e}\mathbf{J}_0(q) \dot{q}`.
3537
+
3538
+ :seealso: :func:`jacob`, :func:`hessian0`
3539
+ """ # noqa
3540
+
3541
+ T = self.fkine(q, include_base=False).A
3542
+ return tr2jac2(T.T) @ self.jacob0(q)