roboticstoolbox-python 1.3.0__cp313-cp313-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.cp313-win_amd64.pyd +0 -0
  473. roboticstoolbox/frne.cp313-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,2520 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ @author Jesse Haviland
4
+ """
5
+
6
+ from collections import namedtuple
7
+ from email import message
8
+ from roboticstoolbox.tools.data import rtb_path_to_datafile
9
+ import warnings
10
+ import copy
11
+ import numpy as np
12
+ from roboticstoolbox.robot.Robot import Robot # DHLink
13
+ from roboticstoolbox.robot.ETS import ETS, ET
14
+ from roboticstoolbox.robot.DHLink import DHLink
15
+ from roboticstoolbox import rtb_set_param
16
+ from spatialmath.base.argcheck import getvector, isscalar, verifymatrix, getmatrix
17
+
18
+ # from spatialmath import base
19
+ from spatialmath.base import (
20
+ tr2jac,
21
+ tr2eul,
22
+ tr2rpy,
23
+ t2r,
24
+ trlog,
25
+ rotvelxform,
26
+ )
27
+ from spatialmath import SE3, Twist3
28
+ import spatialmath.base.symbolic as sym
29
+
30
+ # from scipy.optimize import minimize, Bounds
31
+ from ansitable import ANSITable, Column
32
+ from scipy.linalg import block_diag
33
+ from roboticstoolbox.robot.DHLink import _check_rne, DHLink
34
+ from roboticstoolbox import rtb_get_param
35
+ from roboticstoolbox.frne import init, frne, delete
36
+ from numpy import any
37
+ from typing import Union, Tuple
38
+ from roboticstoolbox.robot.IK import IKSolution
39
+
40
+ ArrayLike = Union[list, np.ndarray, tuple, set]
41
+
42
+ # iksol = namedtuple("IKsolution", "q, success, reason")
43
+
44
+
45
+ class DHRobot(Robot):
46
+ """
47
+ Class for robots defined using Denavit-Hartenberg notation
48
+
49
+ :param L: List of links which define the robot
50
+ :type L: list(n)
51
+ :param name: Name of the robot
52
+ :type name: str
53
+ :param manufacturer: Manufacturer of the robot
54
+ :type manufacturer: str
55
+ :param base: Location of the base
56
+ :type base: SE3
57
+ :param tool: Location of the tool
58
+ :type tool: SE3
59
+ :param gravity: Gravitational acceleration vector
60
+ :type gravity: ndarray(3)
61
+
62
+ A concrete superclass for arm type robots defined using Denavit-Hartenberg
63
+ notation, that represents a serial-link arm-type robot. Each link and
64
+ joint in the chain is described by a DHLink-class object using
65
+ Denavit-Hartenberg parameters (standard or modified).
66
+
67
+ .. note:: Link subclass elements passed in must be all standard, or all
68
+ modified, DH parameters.
69
+
70
+ :reference:
71
+
72
+ - Robotics, Vision & Control in Python, 3e, P. Corke, Springer 2023, Chap 7-9.
73
+ - Robot, Modeling & Control,
74
+ M.Spong, S. Hutchinson & M. Vidyasagar, Wiley 2006.
75
+
76
+ """
77
+
78
+ def __init__(self, links, meshdir=None, **kwargs):
79
+ # Verify L
80
+ if not isinstance(links, list):
81
+ raise TypeError("The links must be stored in a list.")
82
+
83
+ all_links = []
84
+ self._n = 0
85
+
86
+ # If we are given a list of standard DH Links, we must convert
87
+ # them to modified DH links
88
+ # if any([isinstance(link, StandardDH) for link in links]):
89
+ # links = DHLink.StandardDH(links)
90
+
91
+ for link in links:
92
+ if isinstance(link, DHLink):
93
+ # got a link
94
+ all_links.append(link)
95
+ link.number = self._n + 1
96
+ link.jindex = self._n
97
+ self._n += 1
98
+
99
+ link.name = f"link{self._n}"
100
+
101
+ elif isinstance(link, DHRobot):
102
+ # link is actually a robot
103
+
104
+ # copy the links
105
+ rlinks = copy.copy(link.links)
106
+ for rlink in rlinks:
107
+ all_links.append(rlink)
108
+ rlink.number = self._n
109
+ rlink.jindex = self._n
110
+ self._n += 1
111
+
112
+ rlink.name = f"link{self._n}"
113
+ else:
114
+ raise TypeError("Input can be only DHLink or DHRobot")
115
+
116
+ for i, link in enumerate(all_links):
117
+ if i > 0:
118
+ link.parent = all_links[i - 1]
119
+ else:
120
+ link.parent = None
121
+
122
+ super().__init__(all_links, **kwargs)
123
+
124
+ self._ee_links = [self.links[-1]]
125
+
126
+ # Check the DH convention
127
+ self._mdh = self.links[0].mdh
128
+ if not all([link.mdh == self.mdh for link in self.links]):
129
+ raise ValueError("Robot has mixed D&H link conventions")
130
+
131
+ # load meshes if required
132
+ if meshdir is not None:
133
+ self.meshdir = rtb_path_to_datafile(meshdir)
134
+ self.basemesh = self.meshdir / "link0.stl"
135
+ for j, link in enumerate(self._links, start=1):
136
+ link.mesh = self.meshdir / "link{:d}.stl".format(j)
137
+ self._hasgeometry = True
138
+ else:
139
+ self.basemesh = None
140
+
141
+ # rne parameters
142
+ self._rne_ob = None
143
+
144
+ def __str__(self):
145
+ """
146
+ Pretty prints the DH Model of the robot. Will output angles in degrees
147
+
148
+ :return: Pretty print of the robot model
149
+ :rtype: str
150
+ """
151
+
152
+ if np.array_equal(self.base.A, np.eye(4)):
153
+ base = None
154
+ else:
155
+ base = self.base
156
+
157
+ if np.array_equal(self.tool.A, np.eye(4)):
158
+ tool = None
159
+ else:
160
+ tool = self.tool
161
+
162
+ unicode = rtb_get_param("unicode")
163
+ border = "thin" if unicode else "ascii"
164
+ s = f"DHRobot: {self.name}"
165
+
166
+ if self.manufacturer is not None and len(self.manufacturer) > 0:
167
+ s += f" (by {self.manufacturer})"
168
+ s += f", {self.n} joints ({self.structure})"
169
+
170
+ deg = 180 / np.pi
171
+
172
+ if self._hasdynamics:
173
+ s += ", dynamics"
174
+ if any([link.mesh is not None for link in self.links]):
175
+ s += ", geometry"
176
+
177
+ if self.mdh:
178
+ dh = "modified"
179
+ else:
180
+ dh = "standard"
181
+ s += f", {dh} DH parameters\n"
182
+
183
+ def qstr(j, link):
184
+ j += 1
185
+ if link.isflip:
186
+ s = f"-q{j:d}"
187
+ else:
188
+ s = f" q{j:d}"
189
+
190
+ if L.offset != 0:
191
+ sign = "+" if L.offset > 0 else "-"
192
+ offset = abs(L.offset)
193
+ if link.isprismatic:
194
+ s += f" {sign} {offset:}"
195
+ else:
196
+ s += f" {sign} {offset * deg:.3g}\u00b0"
197
+ return s
198
+
199
+ def angle(theta, fmt=None):
200
+ if sym.issymbol(theta): # pragma nocover
201
+ return "<<red>>" + str(theta)
202
+ else:
203
+ if fmt is not None:
204
+ return fmt.format(theta * deg) + "\u00b0"
205
+ else:
206
+ return str(theta * deg) + "\u00b0"
207
+
208
+ def format_attr(attr) -> str:
209
+ if isinstance(attr, float):
210
+ return f"{attr:.4g}"
211
+ else:
212
+ return str(attr)
213
+
214
+ has_qlim = any([link.qlim is not None for link in self])
215
+ if has_qlim:
216
+ qlim_columns = [
217
+ Column("q⁻", headalign="^"),
218
+ Column("q⁺", headalign="^"),
219
+ ]
220
+ qlim = self.qlim
221
+
222
+ else:
223
+ qlim = np.array([]) # satisfy type checker
224
+ qlim_columns = []
225
+
226
+ if self.mdh:
227
+ # MDH format
228
+ table = ANSITable(
229
+ Column("aⱼ₋₁", headalign="^"),
230
+ Column("⍺ⱼ₋₁", headalign="^"),
231
+ Column("θⱼ", headalign="^"),
232
+ Column("dⱼ", headalign="^"),
233
+ *qlim_columns,
234
+ border=border,
235
+ )
236
+ for j, L in enumerate(self):
237
+ if has_qlim:
238
+ if L.isprismatic:
239
+ ql = [qlim[0, j], qlim[1, j]]
240
+ else:
241
+ ql = [angle(qlim[k, j], "{:.1f}") for k in [0, 1]]
242
+ else:
243
+ ql = []
244
+ if L.isprismatic:
245
+ table.row(L.a, angle(L.alpha), angle(L.theta), qstr(j, L), *ql)
246
+ else:
247
+ table.row(L.a, angle(L.alpha), qstr(j, L), L.d, *ql)
248
+ else:
249
+ # DH format
250
+ table = ANSITable(
251
+ Column("θⱼ", headalign="^", colalign="<"),
252
+ Column("dⱼ", headalign="^"),
253
+ Column("aⱼ", headalign="^"),
254
+ Column("⍺ⱼ", headalign="^"),
255
+ *qlim_columns,
256
+ border=border,
257
+ )
258
+
259
+ for j, L in enumerate(self):
260
+ if has_qlim:
261
+ if L.isprismatic:
262
+ ql = [qlim[0, j], qlim[1, j]]
263
+ else:
264
+ ql = [angle(qlim[k, j], "{:.1f}") for k in [0, 1]]
265
+ else:
266
+ ql = []
267
+ if L.isprismatic:
268
+ table.row(
269
+ angle(L.theta),
270
+ qstr(j, L),
271
+ format_attr(L.a),
272
+ angle(L.alpha),
273
+ *ql,
274
+ )
275
+ else:
276
+ table.row(
277
+ qstr(j, L),
278
+ format_attr(L.d),
279
+ format_attr(L.a),
280
+ angle(L.alpha),
281
+ *ql,
282
+ )
283
+
284
+ s += str(table)
285
+
286
+ # show tool and base
287
+ if tool is not None or base is not None:
288
+ table = ANSITable(
289
+ Column("", colalign=">"),
290
+ Column("", colalign="<"),
291
+ border=border,
292
+ header=False,
293
+ )
294
+ if base is not None:
295
+ table.row(
296
+ "base",
297
+ base.printline(orient="rpy/xyz", fmt="{:.2g}", file=None),
298
+ )
299
+ if tool is not None:
300
+ table.row(
301
+ "tool",
302
+ tool.strline(orient="rpy/xyz", fmt="{:.2g}"),
303
+ )
304
+ s += "\n" + str(table)
305
+
306
+ # show named configurations
307
+ s += self.configurations_str(border=border)
308
+
309
+ return s
310
+
311
+ def __add__(self, L):
312
+ nlinks = []
313
+
314
+ # TODO - Should I do a deep copy here a physically copy the DHLinks
315
+ # and not just the references?
316
+ # Copy DHLink references to new list
317
+ for i in range(self.n):
318
+ nlinks.append(self.links[i])
319
+
320
+ if isinstance(L, DHLink):
321
+ nlinks.append(L)
322
+ elif isinstance(L, DHRobot):
323
+ for j in range(L.n):
324
+ nlinks.append(L.links[j])
325
+ else:
326
+ raise TypeError("Can only combine DHRobots with other DHRobots or DHLinks")
327
+
328
+ return DHRobot(
329
+ nlinks,
330
+ name=self.name,
331
+ manufacturer=self.manufacturer,
332
+ base=self.base,
333
+ tool=self.tool,
334
+ gravity=self.gravity,
335
+ )
336
+
337
+ def __deepcopy__(self, memo):
338
+ links = []
339
+
340
+ for link in self.links:
341
+ links.append(copy.deepcopy(link))
342
+
343
+ name = copy.deepcopy(self.name)
344
+ manufacturer = copy.deepcopy(self.manufacturer)
345
+ comment = copy.deepcopy(self.comment)
346
+ base = copy.deepcopy(self.base)
347
+ tool = copy.deepcopy(self.tool)
348
+ gravity = copy.deepcopy(self.gravity)
349
+ keywords = copy.deepcopy(self.keywords)
350
+ symbolic = copy.deepcopy(self.symbolic)
351
+ configs = copy.deepcopy(self.configs)
352
+
353
+ try:
354
+ if self.meshdir:
355
+ meshdir = copy.deepcopy(self.meshdir)
356
+ else:
357
+ meshdir = None
358
+ except AttributeError:
359
+ meshdir = None
360
+
361
+ # cls = self.__class__
362
+ result = DHRobot(
363
+ links,
364
+ meshdir=meshdir,
365
+ name=name,
366
+ manufacturer=manufacturer,
367
+ comment=comment,
368
+ base=base,
369
+ tool=tool,
370
+ gravity=gravity,
371
+ keywords=keywords,
372
+ symbolic=symbolic,
373
+ configs=configs,
374
+ )
375
+
376
+ # if a configuration was an attribute of original robot, make it an
377
+ # attribute of the deep copy
378
+ for config in configs:
379
+ if hasattr(self, config):
380
+ setattr(result, config, configs[config])
381
+
382
+ try:
383
+ setattr(result, "ikine_a", getattr(self, "ikine_a"))
384
+ except AttributeError:
385
+ pass
386
+
387
+ memo[id(self)] = result
388
+ return result
389
+
390
+ # def copy(self):
391
+ # """
392
+ # Copy a robot
393
+
394
+ # :return: A deepish copy of the robot
395
+ # :rtype: Robot subclass instance
396
+ # """
397
+
398
+ # L = [link.copy() for link in self]
399
+
400
+ # new = DHRobot(
401
+ # L,
402
+ # name=self.name,
403
+ # manufacturer=self.manufacturer,
404
+ # base=self.base,
405
+ # tool=self.tool,
406
+ # gravity=self.gravity)
407
+
408
+ # new.q = self.q
409
+ # new.qd = self.qd
410
+ # new.qdd = self.qdd
411
+
412
+ # return new
413
+
414
+ # --------------------------------------------------------------------- #
415
+
416
+ def _set_link_fk(self, q):
417
+ """
418
+ robot._set_link_fk(q) evaluates fkine for each link within a
419
+ robot and stores that pose in a private variable within the link.
420
+
421
+ This method is not for general use.
422
+
423
+ :param q: The joint angles/configuration of the robot
424
+ :type q: float ndarray(n)
425
+
426
+ .. note::
427
+
428
+ - The robot's base transform, if present, are incorporated
429
+ into the result.
430
+ """
431
+
432
+ q = getvector(q, self.n)
433
+
434
+ # t = self.base
435
+
436
+ tall = self.fkine_all(q, old=True)
437
+
438
+ for i, link in enumerate(self.links):
439
+ # Update the link model transforms
440
+ for col in link.collision:
441
+ col.wT = tall[i]
442
+
443
+ for gi in link.geometry:
444
+ gi.wT = tall[i]
445
+
446
+ # --------------------------------------------------------------------- #
447
+
448
+ @property
449
+ def mdh(self):
450
+ """
451
+ Modified Denavit-Hartenberg status
452
+
453
+ :return: whether robot is defined using modified Denavit-Hartenberg
454
+ notation
455
+ :rtype: bool
456
+
457
+ Example:
458
+
459
+ .. runblock:: pycon
460
+
461
+ >>> import roboticstoolbox as rtb
462
+ >>> puma = rtb.models.DH.Puma560()
463
+ >>> puma.mdh
464
+ >>> panda = rtb.models.DH.Panda()
465
+ >>> panda.mdh
466
+
467
+ """
468
+ return self._mdh
469
+
470
+ @property
471
+ def d(self):
472
+ r"""
473
+ Link offset values
474
+
475
+ :return: List of link offset values :math:`d_j`.
476
+ :rtype: ndarray(n,)
477
+
478
+ The following are equivalent::
479
+
480
+ robot.links[j].d
481
+ robot.d[j]
482
+
483
+ Example:
484
+
485
+ .. runblock:: pycon
486
+
487
+ >>> import roboticstoolbox as rtb
488
+ >>> robot = rtb.models.DH.Puma560()
489
+ >>> robot.d
490
+ """
491
+ v = []
492
+ for i in range(self.n):
493
+ v.append(self.links[i].d)
494
+ return v
495
+
496
+ @property
497
+ def a(self):
498
+ r"""
499
+ Link length values
500
+
501
+ :return: List of link length values :math:`a_j`.
502
+ :rtype: ndarray(n,)
503
+
504
+ The following are equivalent::
505
+
506
+ robot.links[j].a
507
+ robot.a[j]
508
+
509
+ Example:
510
+
511
+ .. runblock:: pycon
512
+
513
+ >>> import roboticstoolbox as rtb
514
+ >>> robot = rtb.models.DH.Puma560()
515
+ >>> robot.a
516
+ """
517
+ v = []
518
+ for i in range(self.n):
519
+ v.append(self.links[i].a)
520
+ return v
521
+
522
+ @property
523
+ def theta(self):
524
+ r"""
525
+ Joint angle values
526
+
527
+ :return: List of joint angle values :math:`\theta_j`.
528
+ :rtype: ndarray(n,)
529
+
530
+ The following are equivalent::
531
+
532
+ robot.links[j].theta
533
+ robot.theta[j]
534
+
535
+ Example:
536
+
537
+ .. runblock:: pycon
538
+
539
+ >>> import roboticstoolbox as rtb
540
+ >>> robot = rtb.models.DH.Puma560()
541
+ >>> robot.theta
542
+ """
543
+ v = []
544
+ for i in range(self.n):
545
+ v.append(self.links[i].theta)
546
+ return v
547
+
548
+ @property
549
+ def alpha(self):
550
+ r"""
551
+ Link twist values
552
+
553
+ :return: List of link twist values :math:`\alpha_j`.
554
+ :rtype: ndarray(n,)
555
+
556
+ The following are equivalent::
557
+
558
+ robot.links[j].alpha
559
+ robot.alpha[j]
560
+
561
+ Example:
562
+
563
+ .. runblock:: pycon
564
+
565
+ >>> import roboticstoolbox as rtb
566
+ >>> robot = rtb.models.DH.Puma560()
567
+ >>> robot.alpha
568
+ """
569
+ v = []
570
+ for i in range(self.n):
571
+ v.append(self.links[i].alpha)
572
+ return v
573
+
574
+ @property
575
+ def r(self):
576
+ r"""
577
+ Link centre of mass values
578
+
579
+ :return: Array of link centre of mass values :math:`r_j`.
580
+ :rtype: ndarray(3,n)
581
+
582
+ Example:
583
+
584
+ .. runblock:: pycon
585
+
586
+ >>> import roboticstoolbox as rtb
587
+ >>> robot = rtb.models.DH.Puma560()
588
+ >>> robot.r
589
+ """
590
+ # TODO tidyup
591
+ v = np.copy(self.links[0].r)
592
+ for i in range(1, self.n):
593
+ v = np.c_[v, self.links[i].r]
594
+ return v
595
+
596
+ @property
597
+ def offset(self):
598
+ r"""
599
+ Joint offset values
600
+
601
+ :return: List of joint offset values :math:`\bar{q}_j`.
602
+ :rtype: ndarray(n,)
603
+
604
+ Example:
605
+
606
+ .. runblock:: pycon
607
+
608
+ >>> import roboticstoolbox as rtb
609
+ >>> robot = rtb.models.DH.Puma560()
610
+ >>> robot.offset
611
+ """
612
+ v = []
613
+ for i in range(self.n):
614
+ v.append(self.links[i].offset)
615
+ return v
616
+
617
+ @property
618
+ def reach(self):
619
+ r"""
620
+ Reach of the robot
621
+
622
+ :return: Maximum reach of the robot
623
+ :rtype: float
624
+
625
+ A conservative estimate of the reach of the robot. It is computed as
626
+ :math:`\sum_j |a_j| + |d_j|` where :math:`d_j` is taken as the maximum
627
+ joint coordinate (``qlim``) if the joint is primsmatic.
628
+
629
+ .. note::
630
+
631
+ - This is the *length sum* referred to in Craig's book
632
+ - Probably an overestimate of the actual reach
633
+ - Used by numerical inverse kinematics to scale translational
634
+ error.
635
+ - For a prismatic joint, uses ``qlim`` if it is set
636
+
637
+ .. warning:: Computed on the first access. If kinematic parameters
638
+ subsequently change this will not be reflected.
639
+ """
640
+ if self._reach is None:
641
+ d = 0
642
+ for link in self:
643
+ d += abs(link.a) + (link.d)
644
+ if link.isprismatic and link.qlim is not None:
645
+ d += link.qlim[1]
646
+ self._reach = d
647
+ return self._reach
648
+
649
+ @property
650
+ def nbranches(self):
651
+ """
652
+ Number of branches
653
+
654
+ :return: number of branches in the robot's kinematic tree
655
+ :rtype: int
656
+
657
+ Number of branches in this robot.
658
+
659
+ Example:
660
+
661
+ .. runblock:: pycon
662
+
663
+ >>> import roboticstoolbox as rtb
664
+ >>> robot = rtb.models.DH.Panda()
665
+ >>> robot.nbranches
666
+
667
+ :seealso: :func:`n`, :func:`nlinks`
668
+ """
669
+ return 1
670
+
671
+ def A(self, j, q=None):
672
+ """
673
+ Link forward kinematics
674
+
675
+ :param j: Joints to compute link transform for
676
+ :type j: int, 2-tuple
677
+ :param q: The joint configuration of the robot (Optional,
678
+ if not supplied will use the stored q values)
679
+ :type q: float ndarray(1,n)
680
+ :return T: The transform between link frames
681
+ :rtype T: SE3
682
+
683
+ - ``robot.A(j, q)`` transform between link frames {0} and {j}. ``q``
684
+ is a vector (n) of joint variables.
685
+ - ``robot.A([j1, j2], q)`` as above between link frames {j1} and {j2}.
686
+ - ``robot.A(j)`` as above except uses the stored q value of the
687
+ robot object.
688
+
689
+ .. note:: Base and tool transforms are not applied.
690
+
691
+ """
692
+
693
+ if isscalar(j):
694
+ j0 = 0
695
+ jn = int(j)
696
+ else:
697
+ j = getvector(j, 2)
698
+ j0 = int(j[0])
699
+ jn = int(j[1])
700
+
701
+ jn += 1
702
+
703
+ if jn > self.n:
704
+ raise ValueError("The joints value out of range")
705
+
706
+ q = getvector(q)
707
+
708
+ T = SE3()
709
+ for i in range(j0, jn):
710
+ T *= self.links[i].A(q[i])
711
+
712
+ return T
713
+
714
+ def islimit(self, q=None):
715
+ """
716
+ Joint limit test
717
+
718
+ :param q: The joint configuration of the robot (Optional,
719
+ if not supplied will use the stored q values)
720
+ :type q: ndarray(n
721
+ :return v: is a vector of boolean values, one per joint, False if
722
+ ``q[j]`` is within the joint limits, else True
723
+ :rtype v: bool list
724
+
725
+ - ``robot.islimit(q)`` is a list of boolean values indicating if the
726
+ joint configuration ``q`` is in violation of the joint limits.
727
+
728
+ - ``robot.jointlimit()`` as above except uses the stored q value of the
729
+ robot object.
730
+
731
+ Example:
732
+
733
+ .. runblock:: pycon
734
+
735
+ >>> import roboticstoolbox as rtb
736
+ >>> robot = rtb.models.DH.Puma560()
737
+ >>> robot.islimit([0, 0, -4, 4, 0, 0])
738
+
739
+ """
740
+ if q is None:
741
+ q = self.q
742
+
743
+ return [link.islimit(qk) for (link, qk) in zip(self, q)]
744
+
745
+ def isspherical(self):
746
+ """
747
+ Test for spherical wrist
748
+
749
+ :return: True if spherical wrist
750
+ :rtype: bool
751
+
752
+ Tests if the robot has a spherical wrist, that is, the last 3 axes are
753
+ revolute and their axes intersect at a point.
754
+
755
+ .. runblock:: pycon
756
+
757
+ >>> import roboticstoolbox as rtb
758
+ >>> robot = rtb.models.DH.Puma560()
759
+ >>> robot.isspherical()
760
+
761
+ """
762
+ if self.n < 3:
763
+ return False
764
+
765
+ L = self.links[self.n - 3 : self.n]
766
+
767
+ alpha = [-np.pi / 2, np.pi / 2]
768
+
769
+ return (
770
+ L[0].a == 0
771
+ and L[1].a == 0
772
+ and L[1].d == 0
773
+ and (
774
+ (L[0].alpha == alpha[0] and L[1].alpha == alpha[1])
775
+ or (L[0].alpha == alpha[1] and L[1].alpha == alpha[0])
776
+ )
777
+ and L[0].sigma == 0
778
+ and L[1].sigma == 0
779
+ and L[2].sigma == 0
780
+ )
781
+
782
+ def dhunique(self):
783
+ """
784
+ Print the unique DH parameters
785
+
786
+ Print a table showing all the non-zero DH parameters, and their
787
+ values. This is the minimum set of kinematic parameters required
788
+ to describe the robot.
789
+
790
+ Example:
791
+
792
+ .. runblock:: pycon
793
+
794
+ >>> import roboticstoolbox as rtb
795
+ >>> puma = rtb.models.DH.Puma560()
796
+ >>> puma.dhunique()
797
+ """
798
+
799
+ table = ANSITable(
800
+ Column("param"),
801
+ Column("value", headalign="^", colalign="<", fmt="{:.4g}"),
802
+ border="thin",
803
+ )
804
+ for j, link in enumerate(self):
805
+ if link.isprismatic:
806
+ if link.theta != 0:
807
+ table.row(f"θ{j}", link.theta)
808
+ elif link.isrevolute:
809
+ if link.d != 0:
810
+ table.row(f"d{j}", link.d)
811
+ if link.a != 0:
812
+ table.row(f"a{j}", link.a)
813
+ if link.alpha != 0:
814
+ table.row(f"⍺{j}", link.alpha)
815
+ table.print()
816
+
817
+ def twists(self, q=None):
818
+ """
819
+ Joint axes as twists
820
+
821
+ :param q: The joint configuration of the robot, defaults to zero
822
+ :return: a vector of joint axis twists
823
+ :rtype: Twist3 instance
824
+ :return: Pose of the tool
825
+ :rtype: SE3 instance
826
+
827
+ - ``tw, T0 = twists(q)`` calculates a vector of Twist objects (n) that
828
+ represent the axes of the joints for the robot with joint coordinates
829
+ ``q`` (n). Also returns T0 which is an SE3 object representing the
830
+ pose of the tool.
831
+
832
+ - ``tw, T0 = twists()`` as above but the joint coordinates are taken
833
+ to be zero.
834
+
835
+ Example:
836
+
837
+ .. runblock:: pycon
838
+
839
+ >>> import roboticstoolbox as rtb
840
+ >>> robot = rtb.models.DH.Puma560()
841
+ >>> tw, T0 = robot.twists()
842
+ >>> tw
843
+ >>> T0
844
+
845
+ """
846
+
847
+ if q is None:
848
+ q = np.zeros((self.n,))
849
+
850
+ T = self.fkine_all(q)[1:] # don't use first transform which is base
851
+ tw = Twist3.Alloc(self.n)
852
+ if self.mdh:
853
+ # MDH case
854
+ for j, link in enumerate(self):
855
+ if link.sigma == 0:
856
+ tw[j] = Twist3.UnitRevolute(T[j].a, T[j].t)
857
+ else:
858
+ tw[j] = Twist3.UnitPrismatic(T[j].a)
859
+ else:
860
+ # DH case
861
+ for j, link in enumerate(self):
862
+ if j == 0:
863
+ # first link case
864
+ if link.sigma == 0:
865
+ # revolute
866
+ tw[j] = Twist3.UnitRevolute([0, 0, 1], [0, 0, 0])
867
+ else:
868
+ tw[j] = Twist3.UnitPrismatic([0, 0, 1]) # prismatic
869
+ else:
870
+ # subsequent links
871
+ if link.sigma == 0:
872
+ tw[j] = Twist3.UnitRevolute(T[j - 1].a, T[j - 1].t) # revolute
873
+ else:
874
+ tw[j] = Twist3.UnitPrismatic(T[j - 1].a) # prismatic
875
+
876
+ return tw, T[-1]
877
+
878
+ def ets(self, *args, **kwargs) -> ETS:
879
+ """
880
+ Robot kinematics as an elemenary transform sequence
881
+
882
+ :return: elementary transform sequence
883
+ :rtype: ETS
884
+
885
+ Example:
886
+
887
+ .. runblock:: pycon
888
+
889
+ >>> import roboticstoolbox as rtb
890
+ >>> puma = rtb.models.DH.Puma560()
891
+ >>> puma.ets()
892
+ """
893
+
894
+ # optionally start with the base transform
895
+ if np.array_equal(self.base.A, np.eye(4)):
896
+ base = None
897
+ else:
898
+ base = self.base.A
899
+
900
+ if np.array_equal(self.tool.A, np.eye(4)):
901
+ tool = None
902
+ else:
903
+ tool = self.tool.A
904
+
905
+ if base is None:
906
+ ets = ETS()
907
+ else:
908
+ ets = ET.SE3(base)
909
+
910
+ # add the links
911
+ for link in self:
912
+ ets *= link.ets
913
+
914
+ # optionally add the base transform
915
+ if tool is not None:
916
+ ets *= ET.SE3(tool)
917
+
918
+ return ets
919
+
920
+ def fkine(self, q, **kwargs):
921
+ """
922
+ Forward kinematics
923
+
924
+ :param q: The joint configuration
925
+ :type q: ndarray(n) or ndarray(m,n)
926
+ :return: Forward kinematics as an SE(3) matrix
927
+ :rtype: SE3 instance
928
+
929
+ - ``robot.fkine(q)`` computes the forward kinematics for the robot at
930
+ joint configuration ``q``.
931
+
932
+ If q is a 2D array, the rows are interpreted as the generalized joint
933
+ coordinates for a sequence of points along a trajectory. ``q[k,j]`` is
934
+ the j'th joint coordinate for the k'th trajectory configuration, and
935
+ the returned ``SE3`` instance contains ``n`` values.
936
+
937
+ Example:
938
+
939
+ .. runblock:: pycon
940
+
941
+ >>> import roboticstoolbox as rtb
942
+ >>> puma = rtb.models.DH.Puma560()
943
+ >>> puma.fkine([0, 0, 0, 0, 0, 0])
944
+
945
+ .. note::
946
+
947
+ - The robot's base or tool transform, if present, are incorporated
948
+ into the result.
949
+ - Joint offsets, if defined, are added to ``q`` before the forward
950
+ kinematics are computed.
951
+ """
952
+
953
+ if np.array_equal(self.base.A, np.eye(4)):
954
+ base = None
955
+ else:
956
+ base = self.base
957
+
958
+ if np.array_equal(self.tool.A, np.eye(4)):
959
+ tool = None
960
+ else:
961
+ tool = self.tool
962
+
963
+ T = SE3.Empty()
964
+ for qr in getmatrix(q, (None, self.n)):
965
+ first = True
966
+ for q, L in zip(qr, self.links):
967
+ if first:
968
+ Tr = L.A(q)
969
+ first = False
970
+ else:
971
+ Tr *= L.A(q) # type: ignore
972
+
973
+ if base is not None:
974
+ Tr = base * Tr # type: ignore
975
+ if tool is not None:
976
+ Tr = Tr * tool # type: ignore
977
+ T.append(Tr) # type: ignore
978
+
979
+ return T
980
+
981
+ def fkine_path(self, q, old=None):
982
+ """
983
+ Compute the pose of every link frame
984
+
985
+ :param q: The joint configuration
986
+ :type q: darray(n)
987
+ :return: Pose of all links
988
+ :rtype: SE3 instance
989
+
990
+ ``T = robot.fkine_path(q)`` is an SE3 instance with ``robot.nlinks +
991
+ 1`` values:
992
+
993
+ - ``T[0]`` is the base transform
994
+ - ``T[i+1]`` is the pose of link whose ``number`` is ``i``
995
+
996
+ :references:
997
+ - Kinematic Derivatives using the Elementary Transform
998
+ Sequence, J. Haviland and P. Corke
999
+ """
1000
+ T = self.base
1001
+ q = getvector(q)
1002
+ Tj = T
1003
+
1004
+ for q, L in zip(q, self.links):
1005
+ Tj *= L.A(q)
1006
+ T.append(Tj)
1007
+
1008
+ if self._tool is not None:
1009
+ T[-1] *= self._tool
1010
+
1011
+ return T
1012
+
1013
+ def segments(self):
1014
+ segments = [None]
1015
+ segments.extend(self.links)
1016
+ return [segments]
1017
+
1018
+ def fkine_all(self, q=None, old=True):
1019
+ """
1020
+ Forward kinematics for all link frames
1021
+
1022
+ :param q: The joint configuration of the robot (Optional,
1023
+ if not supplied will use the stored q values).
1024
+ :type q: ndarray(n) or ndarray(m,n)
1025
+ :param old: "old" behaviour, defaults to True
1026
+ :type old: bool, optional
1027
+ :return: Forward kinematics as an SE(3) matrix
1028
+ :rtype: SE3 instance with ``n`` values
1029
+
1030
+ - ``fkine_all(q)`` evaluates fkine for each joint within a robot and
1031
+ returns a sequence of link frame poses.
1032
+
1033
+ - ``fkine_all()`` as above except uses the stored q value of the
1034
+ robot object.
1035
+
1036
+ Example:
1037
+
1038
+ .. runblock:: pycon
1039
+
1040
+ >>> import roboticstoolbox as rtb
1041
+ >>> puma = rtb.models.DH.Puma560()
1042
+ >>> T = puma.fkine_all([0, 0, 0, 0, 0, 0])
1043
+ >>> len(T)
1044
+
1045
+ .. note::
1046
+ - Old behaviour is to return a list of ``n`` frames {1} to {n}, but
1047
+ if ``old=False`` it returns ``n``+1 frames {0} to {n}, ie. it
1048
+ includes the base frame.
1049
+ - The robot's base or tool transform, if present, are incorporated
1050
+ into the result.
1051
+ - Joint offsets, if defined, are added to q before the forward
1052
+ kinematics are computed.
1053
+ """
1054
+
1055
+ if q is None:
1056
+ q = self.q
1057
+
1058
+ Tj = self.base.copy()
1059
+ Tall = Tj
1060
+
1061
+ for q, L in zip(q, self.links):
1062
+ Tj *= L.A(q)
1063
+ Tall.append(Tj)
1064
+ return Tall
1065
+
1066
+ def jacobe(self, q, half=None, **kwargs):
1067
+ r"""
1068
+ Manipulator Jacobian in end-effector frame
1069
+
1070
+ :param q: Joint coordinate vector
1071
+ :type q: ndarray(n)
1072
+ :param half: return half Jacobian: 'trans' or 'rot'
1073
+ :type half: str
1074
+ :return J: The manipulator Jacobian in the end-effector frame
1075
+ :rtype: ndarray(6,n)
1076
+
1077
+ - ``robot.jacobe(q)`` is the manipulator Jacobian matrix which maps
1078
+ joint velocity to end-effector spatial velocity.
1079
+
1080
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
1081
+ is related to joint velocity by :math:`{}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}`.
1082
+
1083
+ Example:
1084
+
1085
+ .. runblock:: pycon
1086
+
1087
+ >>> import roboticstoolbox as rtb
1088
+ >>> puma = rtb.models.DH.Puma560()
1089
+ >>> puma.jacobe([0, 0, 0, 0, 0, 0])
1090
+
1091
+ .. warning:: This is the **geometric Jacobian** as described in texts by
1092
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
1093
+ described in terms of translational and angular velocity, not a
1094
+ velocity twist as per the text by Lynch & Park.
1095
+ """ # noqa
1096
+
1097
+ q = getvector(q, self.n)
1098
+
1099
+ n = self.n
1100
+ L = self.links
1101
+ J = np.zeros((6, self.n), dtype=q.dtype) # type: ignore
1102
+
1103
+ U = self.tool.A
1104
+
1105
+ for j in range(n - 1, -1, -1):
1106
+ if self.mdh == 0:
1107
+ # standard DH convention
1108
+ U = L[j].A(q[j]).A @ U # type: ignore
1109
+
1110
+ if not L[j].sigma:
1111
+ # revolute axis
1112
+ d = np.array(
1113
+ [
1114
+ -U[0, 0] * U[1, 3] + U[1, 0] * U[0, 3],
1115
+ -U[0, 1] * U[1, 3] + U[1, 1] * U[0, 3],
1116
+ -U[0, 2] * U[1, 3] + U[1, 2] * U[0, 3],
1117
+ ]
1118
+ )
1119
+ delta = U[2, :3] # nz oz az
1120
+ else:
1121
+ # prismatic axis
1122
+ d = U[2, :3] # nz oz az
1123
+ delta = np.zeros((3,))
1124
+
1125
+ J[:, j] = np.r_[d, delta]
1126
+
1127
+ if self.mdh != 0:
1128
+ # modified DH convention
1129
+ U = L[j].A(q[j]).A @ U # type: ignore
1130
+
1131
+ # return top or bottom half if asked
1132
+ if half is not None:
1133
+ if half == "trans":
1134
+ return J[:3, :]
1135
+ elif half == "rot":
1136
+ return J[3:, :]
1137
+ else:
1138
+ raise ValueError("bad half specified")
1139
+
1140
+ return J
1141
+
1142
+ def jacob0(self, q=None, T=None, half=None, start=None, end=None):
1143
+ r"""
1144
+ Manipulator Jacobian in world frame
1145
+
1146
+ :param q: Joint coordinate vector
1147
+ :type q: ndarray(n)
1148
+ :param T: Forward kinematics if known, SE(3 matrix)
1149
+ :type T: SE3 instance
1150
+ :param half: return half Jacobian: 'trans' or 'rot'
1151
+ :type half: str
1152
+ :return J: The manipulator Jacobian in the world frame
1153
+ :rtype: ndarray(6,n)
1154
+
1155
+ - ``robot.jacob0(q)`` is the manipulator geometric Jacobian matrix which maps
1156
+ joint velocity to end-effector spatial velocity.
1157
+
1158
+ End-effector spatial velocity :math:`\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T`
1159
+ is related to joint velocity by :math:`{}^{0}\!\nu = \mathbf{J}_0(q) \dot{q}`.
1160
+
1161
+ Example:
1162
+
1163
+ .. runblock:: pycon
1164
+
1165
+ >>> import roboticstoolbox as rtb
1166
+ >>> puma = rtb.models.DH.Puma560()
1167
+ >>> puma.jacob0([0, 0, 0, 0, 0, 0])
1168
+
1169
+ .. warning:: This is the **geometric Jacobian** is as described in texts by
1170
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
1171
+ described in terms of translational and angular velocity, not a
1172
+ velocity twist as per the text by Lynch & Park.
1173
+
1174
+ .. note:: ``T`` can be passed in to save the cost of computing forward
1175
+ kinematics which is needed to transform velocity from end-effector
1176
+ frame to world frame.
1177
+
1178
+ """ # noqa
1179
+ q = getvector(q, self.n)
1180
+
1181
+ if T is None:
1182
+ T = self.fkine(q)
1183
+ T = T.A
1184
+
1185
+ # compute Jacobian in EE frame and transform to world frame
1186
+ J0 = tr2jac(T) @ self.jacobe(q)
1187
+
1188
+ # TODO optimize computation above if half matrix is returned
1189
+
1190
+ # return top or bottom half if asked
1191
+ if half is not None:
1192
+ if half == "trans":
1193
+ J0 = J0[:3, :]
1194
+ elif half == "rot":
1195
+ J0 = J0[3:, :]
1196
+ else:
1197
+ raise ValueError("bad half specified")
1198
+ return J0
1199
+
1200
+ def jacob0_analytical(self, q, representation=None, T=None):
1201
+ r"""
1202
+ Manipulator Jacobian in world frame
1203
+
1204
+ :param q: Joint coordinate vector
1205
+ :type q: ndarray(n)
1206
+ :param representation: return analytical Jacobian instead of geometric Jacobian
1207
+ :type representation: str
1208
+ :param T: Forward kinematics if known, SE(3 matrix)
1209
+ :type T: SE3 instance
1210
+ :return J: The manipulator analytical Jacobian in the world frame
1211
+ :rtype: ndarray(6,n)
1212
+
1213
+ Return the manipulator's analytical Jacobian matrix which maps
1214
+ joint velocity to end-effector spatial velocity.
1215
+
1216
+ End-effector spatial velocity :math:`\nu_a = (v_x, v_y, v_z, \dot{\Gamma}_1, \dot{\Gamma}_2, \dot{\Gamma}_3)^T`
1217
+ is related to joint velocity by :math:`{}^{0}\!\nu_a = \mathbf{J}_{a,0}(q) \dot{q}`.
1218
+ Where :math:`\dvec{\Gamma} = (\dot{\Gamma}_1, \dot{\Gamma}_2, \dot{\Gamma}_3)` is
1219
+ orientation rate expressed as one of:
1220
+
1221
+ ================== ==================================
1222
+ ``representation`` Rotational representation
1223
+ ================== ==================================
1224
+ ``'rpy/xyz'`` RPY angular rates in XYZ order
1225
+ ``'rpy/zyx'`` RPY angular rates in XYZ order
1226
+ ``'eul'`` Euler angular rates in ZYZ order
1227
+ ``'exp'`` exponential coordinate rates
1228
+ ================== ==================================
1229
+
1230
+ Example:
1231
+
1232
+ .. runblock:: pycon
1233
+
1234
+ >>> import roboticstoolbox as rtb
1235
+ >>> puma = rtb.models.DH.Puma560()
1236
+ >>> puma.jacob0_analytical([0, 0, 0, 0, 0, 0], "rpy/xyz")
1237
+
1238
+ .. warning:: The **geometric Jacobian** is as described in texts by
1239
+ Corke, Spong etal., Siciliano etal. The end-effector velocity is
1240
+ described in terms of translational and angular velocity, not a
1241
+ velocity twist as per the text by Lynch & Park.
1242
+
1243
+ .. note:: ``T`` can be passed in to save the cost of computing forward
1244
+ kinematics which is needed to transform velocity from end-effector
1245
+ frame to world frame.
1246
+
1247
+ """ # noqa
1248
+ q = getvector(q, self.n)
1249
+
1250
+ # compute forward kinematics if not provided
1251
+ if T is None:
1252
+ T = self.fkine(q)
1253
+
1254
+ # compute Jacobian in world frame
1255
+ J0 = self.jacob0(q, T)
1256
+
1257
+ if representation is None:
1258
+ return J0
1259
+
1260
+ # compute rotational transform if analytical Jacobian required
1261
+
1262
+ if representation == "rpy/xyz":
1263
+ gamma = tr2rpy(T.A, order="xyz")
1264
+ elif representation == "rpy/zyx":
1265
+ gamma = tr2rpy(T.A, order="zyx")
1266
+ elif representation == "eul":
1267
+ gamma = tr2eul(T.A)
1268
+ elif representation == "exp":
1269
+ # TODO: move to SMTB.base, Horner form with skew(v)
1270
+ gamma = trlog(t2r(T.A), twist=True)
1271
+ else:
1272
+ raise ValueError("bad analytical value specified")
1273
+
1274
+ A = rotvelxform(gamma, representation=representation, inverse=True, full=True)
1275
+ return A @ J0
1276
+
1277
+ def hessian0(self, q=None, J0=None, start=None, end=None):
1278
+ r"""
1279
+ Manipulator Hessian in base frame
1280
+
1281
+ :param q: joint coordinates
1282
+ :type q: array_like
1283
+ :param J0: Jacobian in {0} frame
1284
+ :type J0: ndarray(6,n)
1285
+ :return: Hessian matrix
1286
+ :rtype: ndarray(6,n,n)
1287
+
1288
+ This method calculcates the Hessisan in the base frame. One of ``J0`` or
1289
+ ``q`` is required. If ``J0`` is already calculated for the joint
1290
+ coordinates ``q`` it can be passed in to to save computation time.
1291
+
1292
+ If we take the time derivative of the differential kinematic
1293
+ relationship
1294
+
1295
+ .. math::
1296
+
1297
+ \nu &= \mat{J}(\vec{q}) \dvec{q} \\
1298
+ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}
1299
+
1300
+ where
1301
+
1302
+ .. math::
1303
+
1304
+ \dmat{J} = \mat{H} \dvec{q}
1305
+
1306
+ and :math:`\mat{H} \in \mathbb{R}^{6\times n \times n}` is the
1307
+ Hessian tensor.
1308
+
1309
+ The elements of the Hessian are
1310
+
1311
+ .. math::
1312
+
1313
+ \mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}
1314
+
1315
+ where :math:`u = \{t_x, t_y, t_z, r_x, r_y, r_z\}` are the elements
1316
+ of the spatial velocity vector.
1317
+
1318
+ Similarly, we can write
1319
+
1320
+ .. math::
1321
+
1322
+ \mat{J}_{i,j} = \frac{d u_i}{d q_j}
1323
+
1324
+ :references:
1325
+ - Kinematic Derivatives using the Elementary Transform
1326
+ Sequence, J. Haviland and P. Corke
1327
+
1328
+ :seealso: :func:`jacob0`, :func:`jacob_dot`
1329
+ """
1330
+
1331
+ return self.ets().hessian0(q, J0)
1332
+
1333
+ def _get_limit_links(self, end=None, start=None):
1334
+ # For compatibility with ERobot
1335
+
1336
+ return None, None, None
1337
+
1338
+ # -------------------------------------------------------------------------- #
1339
+
1340
+ def _init_rne(self):
1341
+ # Compress link data into a 1D array
1342
+ L = np.zeros(24 * self.n)
1343
+
1344
+ for i in range(self.n):
1345
+ j = i * 24
1346
+ L[j] = self.links[i].alpha
1347
+ L[j + 1] = self.links[i].a
1348
+ L[j + 2] = self.links[i].theta
1349
+ L[j + 3] = self.links[i].d
1350
+ L[j + 4] = self.links[i].sigma
1351
+ L[j + 5] = self.links[i].offset
1352
+ L[j + 6] = self.links[i].m
1353
+ L[j + 7 : j + 10] = self.links[i].r.flatten()
1354
+ L[j + 10 : j + 19] = self.links[i].I.flatten()
1355
+ L[j + 19] = self.links[i].Jm
1356
+ L[j + 20] = self.links[i].G
1357
+ L[j + 21] = self.links[i].B
1358
+ L[j + 22 : j + 24] = self.links[i].Tc.flatten()
1359
+
1360
+ # we negate gravity here, since the C code has the sign wrong
1361
+ self._rne_ob = init(self.n, self.mdh, L, -self.gravity)
1362
+
1363
+ def delete_rne(self):
1364
+ """
1365
+ Frees the memory holding the robot object in c if the robot object
1366
+ has been initialised in c.
1367
+ """
1368
+ if self._rne_ob is not None:
1369
+ delete(self._rne_ob)
1370
+ self._dynchanged = False
1371
+ self._rne_ob = None
1372
+
1373
+ @_check_rne
1374
+ def rne(self, q, qd=None, qdd=None, gravity=None, fext=None, base_wrench=False):
1375
+ r"""
1376
+ Inverse dynamics
1377
+
1378
+ :param q: Joint coordinates
1379
+ :type q: ndarray(n)
1380
+ :param qd: Joint velocity
1381
+ :type qd: ndarray(n)
1382
+ :param qdd: The joint accelerations of the robot
1383
+ :type qdd: ndarray(n)
1384
+ :param gravity: Gravitational acceleration to override robot's gravity
1385
+ value
1386
+ :type gravity: ndarray(6)
1387
+ :param fext: Specify wrench acting on the end-effector
1388
+ :math:`W=[F_x F_y F_z M_x M_y M_z]`
1389
+ :type fext: ndarray(6)
1390
+
1391
+ ``tau = rne(q, qd, qdd, grav, fext)`` is the joint torque required for
1392
+ the robot to achieve the specified joint position ``q`` (1xn), velocity
1393
+ ``qd`` (1xn) and acceleration ``qdd`` (1xn), where n is the number of
1394
+ robot joints. ``fext`` describes the wrench acting on the end-effector
1395
+
1396
+ Trajectory operation:
1397
+ If q, qd and qdd (mxn) are matrices with m cols representing a
1398
+ trajectory then tau (mxn) is a matrix with cols corresponding to each
1399
+ trajectory step.
1400
+
1401
+ .. note::
1402
+ - The torque computed contains a contribution due to armature
1403
+ inertia and joint friction.
1404
+ - If a model has no dynamic parameters set the result is zero.
1405
+
1406
+ :seealso: :func:`rne_python`
1407
+ """
1408
+
1409
+ if base_wrench:
1410
+ return self.rne_python(
1411
+ q, qd, qdd, gravity=gravity, fext=fext, base_wrench=base_wrench
1412
+ )
1413
+
1414
+ trajn = 1
1415
+
1416
+ try:
1417
+ q = getvector(q, self.n, "row")
1418
+ qd = getvector(qd, self.n, "row")
1419
+ qdd = getvector(qdd, self.n, "row")
1420
+ except ValueError:
1421
+ trajn = q.shape[0]
1422
+ verifymatrix(q, (trajn, self.n))
1423
+ verifymatrix(qd, (trajn, self.n))
1424
+ verifymatrix(qdd, (trajn, self.n))
1425
+
1426
+ if gravity is None:
1427
+ gravity = self.gravity
1428
+ else:
1429
+ gravity = getvector(gravity, 3)
1430
+
1431
+ # The c function doesn't handle base rotation, so we need to hack the
1432
+ # gravity vector instead
1433
+ gravity = self.base.R.T @ gravity
1434
+
1435
+ if fext is None:
1436
+ fext = np.zeros(6)
1437
+ else:
1438
+ fext = getvector(fext, 6)
1439
+
1440
+ tau = np.zeros((trajn, self.n))
1441
+
1442
+ for i in range(trajn):
1443
+ tau[i, :] = frne(
1444
+ # we negate gravity here, since the C code has the sign wrong
1445
+ self._rne_ob,
1446
+ q[i, :],
1447
+ qd[i, :],
1448
+ qdd[i, :],
1449
+ -gravity,
1450
+ fext,
1451
+ )
1452
+
1453
+ if trajn == 1:
1454
+ return tau[0, :]
1455
+ else:
1456
+ return tau
1457
+
1458
+ def rne_python(
1459
+ self,
1460
+ Q,
1461
+ QD=None,
1462
+ QDD=None,
1463
+ gravity=None,
1464
+ fext=None,
1465
+ debug=False,
1466
+ base_wrench=False,
1467
+ ):
1468
+ """
1469
+ Compute inverse dynamics via recursive Newton-Euler formulation
1470
+
1471
+ :param Q: Joint coordinates
1472
+ :param QD: Joint velocity
1473
+ :param QDD: Joint acceleration
1474
+ :param gravity: gravitational acceleration, defaults to attribute
1475
+ of self
1476
+ :type gravity: array_like(3), optional
1477
+ :param fext: end-effector wrench, defaults to None
1478
+ :type fext: array-like(6), optional
1479
+ :param debug: print debug information to console, defaults to False
1480
+ :type debug: bool, optional
1481
+ :param base_wrench: compute the base wrench, defaults to False
1482
+ :type base_wrench: bool, optional
1483
+ :raises ValueError: for misshaped inputs
1484
+ :return: Joint force/torques
1485
+ :rtype: NumPy array
1486
+
1487
+ Recursive Newton-Euler for standard Denavit-Hartenberg notation.
1488
+
1489
+ - ``rne_dh(q, qd, qdd)`` where the arguments have shape (n,) where n is
1490
+ the number of robot joints. The result has shape (n,).
1491
+ - ``rne_dh(q, qd, qdd)`` where the arguments have shape (m,n) where n
1492
+ is the number of robot joints and where m is the number of steps in
1493
+ the joint trajectory. The result has shape (m,n).
1494
+ - ``rne_dh(p)`` where the input is a 1D array ``p`` = [q, qd, qdd] with
1495
+ shape (3n,), and the result has shape (n,).
1496
+ - ``rne_dh(p)`` where the input is a 2D array ``p`` = [q, qd, qdd] with
1497
+ shape (m,3n) and the result has shape (m,n).
1498
+
1499
+ .. note::
1500
+ - This is a pure Python implementation and slower than the .rne()
1501
+ which is written in C.
1502
+ - This version supports symbolic model parameters
1503
+ - Verified against MATLAB code
1504
+
1505
+ :seealso: :func:`rne`
1506
+ """
1507
+
1508
+ if np.array_equal(self.base.A, np.eye(4)):
1509
+ base = None
1510
+ else:
1511
+ base = self.base.A
1512
+
1513
+ def removesmall(x):
1514
+ return x
1515
+
1516
+ n = self.n
1517
+
1518
+ if self.symbolic:
1519
+ dtype = "O"
1520
+ else:
1521
+ dtype = None
1522
+
1523
+ z0 = np.array([0, 0, 1], dtype=dtype)
1524
+
1525
+ if gravity is None:
1526
+ gravity = self.gravity # default gravity from the object
1527
+ else:
1528
+ gravity = getvector(gravity, 3)
1529
+
1530
+ if fext is None:
1531
+ fext = np.zeros((6,), dtype=dtype)
1532
+ else:
1533
+ fext = getvector(fext, 6)
1534
+
1535
+ if debug:
1536
+ print("grav", gravity)
1537
+ print("fext", fext)
1538
+
1539
+ # unpack the joint coordinates and derivatives
1540
+ if Q is not None and QD is None and QDD is None:
1541
+ # single argument case
1542
+ Q = getmatrix(Q, (None, self.n * 3))
1543
+ q = Q[:, 0:n]
1544
+ qd = Q[:, n : 2 * n]
1545
+ qdd = Q[:, 2 * n :]
1546
+
1547
+ else:
1548
+ # 3 argument case
1549
+ q = getmatrix(Q, (None, self.n))
1550
+ qd = getmatrix(QD, (None, self.n))
1551
+ qdd = getmatrix(QDD, (None, self.n))
1552
+
1553
+ nk = q.shape[0]
1554
+
1555
+ tau = np.zeros((nk, n), dtype=dtype)
1556
+ if base_wrench:
1557
+ wbase = np.zeros((nk, n), dtype=dtype)
1558
+
1559
+ for k in range(nk):
1560
+ # take the k'th row of data
1561
+ q_k = q[k, :]
1562
+ qd_k = qd[k, :]
1563
+ qdd_k = qdd[k, :]
1564
+
1565
+ if debug:
1566
+ print("q_k", q_k)
1567
+ print("qd_k", qd_k)
1568
+ print("qdd_k", qdd_k)
1569
+ print()
1570
+
1571
+ # joint vector quantities stored columwise in matrix
1572
+ # m suffix for matrix
1573
+ Fm = np.zeros((3, n), dtype=dtype)
1574
+ Nm = np.zeros((3, n), dtype=dtype)
1575
+ # if robot.issym
1576
+ # pstarm = sym([]);
1577
+ # else
1578
+ # pstarm = [];
1579
+ pstarm = np.zeros((3, n), dtype=dtype)
1580
+ Rm = []
1581
+
1582
+ # rotate base velocity and acceleration into L1 frame
1583
+ # base has zero angular velocity
1584
+ w = np.zeros((3,), dtype=dtype)
1585
+ # base has zero angular acceleration
1586
+ wd = np.zeros((3,), dtype=dtype)
1587
+ vd = -gravity # type: ignore
1588
+
1589
+ if base is not None:
1590
+ Rb = t2r(base).T
1591
+ w = Rb @ w
1592
+ wd = Rb @ wd
1593
+ vd = Rb @ gravity
1594
+
1595
+ # ---------------- initialize some variables ----------------- #
1596
+
1597
+ for j in range(n):
1598
+ link = self.links[j]
1599
+
1600
+ # compute the link rotation matrix
1601
+ if link.sigma == 0:
1602
+ # revolute axis
1603
+ Tj = link.A(q_k[j]).A
1604
+ d = link.d
1605
+ else:
1606
+ # prismatic
1607
+ Tj = link.A(link.theta).A
1608
+ d = q_k[j]
1609
+
1610
+ # compute pstar:
1611
+ # O_{j-1} to O_j in {j}, negative inverse of link xform
1612
+ alpha = link.alpha
1613
+ if self.mdh:
1614
+ pstar = np.r_[link.a, -d * sym.sin(alpha), d * sym.cos(alpha)]
1615
+ if j == 0:
1616
+ if base:
1617
+ Tj = base @ Tj
1618
+ pstar = base @ pstar
1619
+ else:
1620
+ pstar = np.r_[link.a, d * sym.sin(alpha), d * sym.cos(alpha)]
1621
+
1622
+ # stash them for later
1623
+ Rm.append(t2r(Tj))
1624
+ pstarm[:, j] = pstar
1625
+
1626
+ # ----------------- the forward recursion -------------------- #
1627
+
1628
+ for j, link in enumerate(self.links):
1629
+ Rt = Rm[j].T # transpose!!
1630
+ pstar = pstarm[:, j]
1631
+ r = link.r
1632
+
1633
+ # statement order is important here
1634
+
1635
+ if self.mdh:
1636
+ if link.isrevolute:
1637
+ # revolute axis
1638
+ w_ = Rt @ w + z0 * qd_k[j]
1639
+ wd_ = Rt @ wd + z0 * qdd_k[j] + _cross(Rt @ w, z0 * qd_k[j])
1640
+ vd_ = Rt @ _cross(wd, pstar) + _cross(w, _cross(w, pstar)) + vd
1641
+ else:
1642
+ # prismatic axis
1643
+ w_ = Rt @ w
1644
+ wd_ = Rt @ wd
1645
+ vd_ = (
1646
+ Rt @ (_cross(wd, pstar) + _cross(w, _cross(w, pstar)) + vd)
1647
+ + 2 * _cross(Rt @ w, z0 * qd_k[j])
1648
+ + z0 * qdd_k[j]
1649
+ )
1650
+ # trailing underscore means new value, update here
1651
+ w = w_
1652
+ wd = wd_
1653
+ vd = vd_
1654
+ else:
1655
+ if link.isrevolute:
1656
+ # revolute axis
1657
+ wd = Rt @ (wd + z0 * qdd_k[j] + _cross(w, z0 * qd_k[j]))
1658
+ w = Rt @ (w + z0 * qd_k[j])
1659
+ vd = _cross(wd, pstar) + _cross(w, _cross(w, pstar)) + Rt @ vd
1660
+ else:
1661
+ # prismatic axis
1662
+ w = Rt @ w
1663
+ wd = Rt @ wd
1664
+ vd = (
1665
+ Rt @ (z0 * qdd_k[j] + vd)
1666
+ + _cross(wd, pstar)
1667
+ + 2 * _cross(w, Rt @ z0 * qd_k[j])
1668
+ + _cross(w, _cross(w, pstar))
1669
+ )
1670
+
1671
+ vhat = _cross(wd, r) + _cross(w, _cross(w, r)) + vd
1672
+ Fm[:, j] = link.m * vhat
1673
+ Nm[:, j] = link.I @ wd + _cross(w, link.I @ w)
1674
+
1675
+ if debug:
1676
+ print("w: ", removesmall(w))
1677
+ print("wd: ", removesmall(wd))
1678
+ print("vd: ", removesmall(vd))
1679
+ print("vdbar: ", removesmall(vhat))
1680
+ print()
1681
+
1682
+ if debug:
1683
+ print("Fm\n", Fm)
1684
+ print("Nm\n", Nm)
1685
+
1686
+ # ----------------- the backward recursion -------------------- #
1687
+
1688
+ f = fext[:3] # force/moments on end of arm
1689
+ nn = fext[3:]
1690
+
1691
+ for j in range(n - 1, -1, -1):
1692
+ link = self.links[j]
1693
+ r = link.r
1694
+
1695
+ #
1696
+ # order of these statements is important, since both
1697
+ # nn and f are functions of previous f.
1698
+ #
1699
+ if self.mdh:
1700
+ if j == (n - 1):
1701
+ R = np.eye(3, dtype=dtype)
1702
+ pstar = np.zeros((3,), dtype=dtype)
1703
+ else:
1704
+ R = Rm[j + 1]
1705
+ pstar = pstarm[:, j + 1]
1706
+
1707
+ f_ = R @ f + Fm[:, j]
1708
+ nn_ = (
1709
+ R @ nn
1710
+ + _cross(pstar, R @ f)
1711
+ + _cross(pstar, Fm[:, j])
1712
+ + Nm[:, j]
1713
+ )
1714
+ f = f_
1715
+ nn = nn_
1716
+
1717
+ else:
1718
+ pstar = pstarm[:, j]
1719
+ if j == (n - 1):
1720
+ R = np.eye(3, dtype=dtype)
1721
+ else:
1722
+ R = Rm[j + 1]
1723
+
1724
+ nn = (
1725
+ R @ (nn + _cross(R.T @ pstar, f))
1726
+ + _cross(pstar + r, Fm[:, j])
1727
+ + Nm[:, j]
1728
+ )
1729
+ f = R @ f + Fm[:, j]
1730
+
1731
+ if debug:
1732
+ print("f: ", removesmall(f))
1733
+ print("n: ", removesmall(nn))
1734
+
1735
+ R = Rm[j]
1736
+ if self.mdh:
1737
+ if link.isrevolute:
1738
+ # revolute axis
1739
+ t = nn @ z0
1740
+ else:
1741
+ # prismatic
1742
+ t = f @ z0
1743
+ else:
1744
+ if link.isrevolute:
1745
+ # revolute axis
1746
+ t = nn @ (R.T @ z0)
1747
+ else:
1748
+ # prismatic
1749
+ t = f @ (R.T @ z0)
1750
+
1751
+ # add joint inertia and friction
1752
+ # no Coulomb friction if model is symbolic
1753
+ tau[k, j] = (
1754
+ t
1755
+ + link.G**2 * link.Jm * qdd_k[j]
1756
+ - link.friction(qd_k[j], coulomb=not self.symbolic)
1757
+ )
1758
+ if debug:
1759
+ print(
1760
+ f"j={j:}, G={link.G:}, Jm={link.Jm:},"
1761
+ f" friction={link.friction(qd_k[j], coulomb=False):}"
1762
+ ) # noqa
1763
+ print()
1764
+
1765
+ # compute the base wrench and save it
1766
+ if base_wrench:
1767
+ R = Rm[0]
1768
+ nn = R @ nn
1769
+ f = R @ f
1770
+ wbase[k, :] = np.r_[f, nn]
1771
+
1772
+ # if self.symbolic:
1773
+ # # simplify symbolic expressions
1774
+ # print(
1775
+ # 'start symbolic simplification, this might take a while...')
1776
+ # # from sympy import trigsimp
1777
+
1778
+ # # tau = trigsimp(tau)
1779
+ # # consider using multiprocessing to spread over cores
1780
+ # # https://stackoverflow.com/questions/33844085/using-multiprocessing-with-sympy # noqa
1781
+ # print('done')
1782
+ # if tau.shape[0] == 1:
1783
+ # return tau.reshape(self.n)
1784
+ # else:
1785
+ # return tau
1786
+
1787
+ if base_wrench:
1788
+ if tau.shape[0] == 1:
1789
+ return tau.flatten(), wbase.flatten()
1790
+ else:
1791
+ return tau, wbase
1792
+ else:
1793
+ if tau.shape[0] == 1:
1794
+ return tau.flatten()
1795
+ else:
1796
+ return tau
1797
+
1798
+ # -------------------------------------------------------------------------- #
1799
+
1800
+ def ikine_6s(self, T, config, ikfunc):
1801
+ # Undo base and tool transformations, but if they are not
1802
+ # set, skip the operation. Nicer for symbolics
1803
+ if np.array_equal(self.base.A, np.eye(4)):
1804
+ base = None
1805
+ else:
1806
+ base = self.base
1807
+
1808
+ if np.array_equal(self.tool.A, np.eye(4)):
1809
+ tool = None
1810
+ else:
1811
+ tool = self.tool
1812
+
1813
+ if base is not None:
1814
+ T = base.inv() * T
1815
+ if tool is not None:
1816
+ T = tool.inv() * T
1817
+
1818
+ # q = np.zeros((6,))
1819
+ solutions = []
1820
+
1821
+ for k, Tk in enumerate(T):
1822
+ # get model specific solution for first 3 joints
1823
+ theta = ikfunc(self, Tk, config)
1824
+
1825
+ if isinstance(theta, np.ndarray):
1826
+ # Solve for the wrist rotation
1827
+ # We need to account for some random translations between the
1828
+ # first and last 3 joints (d4) and also d6,a6,alpha6 in the
1829
+ # final frame.
1830
+
1831
+ # Transform of first 3 joints
1832
+ T13 = self.A([0, 2], theta)
1833
+
1834
+ # T = T13 * Tz(d4) * R * Tz(d6) Tx(a5)
1835
+ Td4 = SE3(0, 0, self.links[3].d) # Tz(d4)
1836
+
1837
+ # Tz(d6) Tx(a5) Rx(alpha6)
1838
+ Tt = SE3(self.links[5].a, 0, self.links[5].d) * SE3.Rx(
1839
+ self.links[5].alpha
1840
+ )
1841
+
1842
+ R = Td4.inv() * T13.inv() * Tk * Tt.inv()
1843
+
1844
+ # The spherical wrist implements Euler angles
1845
+ if "f" in config:
1846
+ eul = R.eul(flip=True)
1847
+ else:
1848
+ eul = R.eul()
1849
+ theta = np.r_[theta, eul]
1850
+ if self.links[3].alpha > 0:
1851
+ theta[4] = -theta[4]
1852
+
1853
+ # Remove the link offset angles
1854
+ theta = theta - self.offset
1855
+
1856
+ # solution = iksol(theta, True, "")
1857
+ solution = IKSolution(q=theta, success=True)
1858
+
1859
+ else:
1860
+ # ikfunc can return None or a str reason
1861
+ if theta is None:
1862
+ solution = IKSolution(q=None, success=False)
1863
+ else:
1864
+ solution = IKSolution(q=None, success=False, reason=theta)
1865
+
1866
+ solutions.append(solution)
1867
+
1868
+ if len(T) == 1:
1869
+ return solutions[0]
1870
+ else:
1871
+ return IKSolution(
1872
+ np.vstack([sol.q for sol in solutions]),
1873
+ np.array([sol.success for sol in solutions]),
1874
+ [sol.reason for sol in solutions],
1875
+ )
1876
+
1877
+ def config_validate(self, config, allowables):
1878
+ """
1879
+ Validate a configuration string
1880
+
1881
+ :param config: a configuration string
1882
+ :type config: str
1883
+ :param allowable: [description]
1884
+ :type allowable: tuple of str
1885
+ :raises ValueError: bad character in configuration string
1886
+ :return: configuration string
1887
+ :rtype: str
1888
+
1889
+ For analytic inverse kinematics the Toolbox uses a string whose
1890
+ letters indicate particular solutions, eg. for the Puma 560
1891
+
1892
+ ========= ===================
1893
+ Character Meaning
1894
+ ========= ===================
1895
+ 'l' lefty
1896
+ 'r' righty
1897
+ 'u' elbow up
1898
+ 'd' elbow down
1899
+ 'n' wrist not flipped
1900
+ 'f' wrist flipped
1901
+ ========= ===================
1902
+
1903
+ This method checks that the configuration string is valid and adds
1904
+ default values for missing characters. For example:
1905
+
1906
+ config = self.config_validate(config, ('lr', 'ud', 'nf'))
1907
+
1908
+ indicates the valid characters, and the first character in each
1909
+ string is the default, ie. if neither 'l' or 'r' is given then
1910
+ 'l' will be added to the string.
1911
+
1912
+ """
1913
+ for c in config:
1914
+ if not any([c in allowable for allowable in allowables]):
1915
+ raise ValueError(f"bad config specifier <{c}>")
1916
+ for allowable in allowables:
1917
+ if all([a not in config for a in allowable]):
1918
+ config += allowable[0]
1919
+ return config
1920
+
1921
+ # -------------------------------------------------------------------------- #
1922
+
1923
+ def ik_lm_chan(
1924
+ self,
1925
+ Tep: Union[np.ndarray, SE3],
1926
+ q0: Union[np.ndarray, None] = None,
1927
+ ilimit: int = 30,
1928
+ slimit: int = 100,
1929
+ tol: float = 1e-6,
1930
+ reject_jl: bool = True,
1931
+ we: Union[np.ndarray, None] = None,
1932
+ λ: float = 1.0,
1933
+ ) -> Tuple[np.ndarray, int, int, int, float]:
1934
+ """
1935
+ Numerical inverse kinematics by Levenberg-Marquadt optimization (Chan's Method)
1936
+
1937
+ :param Tep: The desired end-effector pose or pose trajectory
1938
+ :param q0: initial joint configuration (default to random valid joint
1939
+ configuration contrained by the joint limits of the robot)
1940
+ :param ilimit: maximum number of iterations per search
1941
+ :param slimit: maximum number of search attempts
1942
+ :param tol: final error tolerance
1943
+ :param reject_jl: constrain the solution to being within the joint limits of
1944
+ the robot (reject solution with invalid joint configurations and perfrom
1945
+ another search up to the slimit)
1946
+ :param we: a mask vector which weights the end-effector error priority.
1947
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
1948
+ respectively
1949
+ :param λ: value of lambda for the damping matrix Wn
1950
+
1951
+ :return: inverse kinematic solution
1952
+ :rtype: tuple (q, success, iterations, searches, residual)
1953
+
1954
+ ``sol = ets.ik_lm_chan(Tep)`` are the joint coordinates (n) corresponding
1955
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
1956
+ This method can be used for robots with any number of degrees of freedom.
1957
+ The return value ``sol`` is a tuple with elements:
1958
+
1959
+ ============ ========== ===============================================
1960
+ Element Type Description
1961
+ ============ ========== ===============================================
1962
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
1963
+ ``success`` int whether a solution was found
1964
+ ``iterations`` int total number of iterations
1965
+ ``searches`` int total number of searches
1966
+ ``residual`` float final value of cost function
1967
+ ============ ========== ===============================================
1968
+
1969
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
1970
+ solution will be in error. The amount of error is indicated by
1971
+ the ``residual``.
1972
+
1973
+ **Joint Limits**:
1974
+
1975
+ ``sol = robot.ikine_LM(T, slimit=100)`` which is the deafualt for this method.
1976
+ The solver will initialise a solution attempt with a random valid q0 and
1977
+ perform a maximum of ilimit steps within this attempt. If a solution is not
1978
+ found, this process is repeated up to slimit times.
1979
+
1980
+ **Global search**:
1981
+
1982
+ ``sol = robot.ikine_LM(T, reject_jl=True)`` is the deafualt for this method.
1983
+ By setting reject_jl to True, the solver will discard any solution which
1984
+ violates the defined joint limits of the robot. The solver will then
1985
+ re-initialise with a new random q0 and repeat the process up to slimit times.
1986
+ Note that finding a solution with valid joint coordinates takes longer than
1987
+ without.
1988
+
1989
+ **Underactuated robots:**
1990
+
1991
+ For the case where the manipulator has fewer than 6 DOF the
1992
+ solution space has more dimensions than can be spanned by the
1993
+ manipulator joint coordinates.
1994
+
1995
+ In this case we specify the ``we`` option where the ``we`` vector
1996
+ (6) specifies the Cartesian DOF (in the wrist coordinate frame) that
1997
+ will be ignored in reaching a solution. The we vector has six
1998
+ elements that correspond to translation in X, Y and Z, and rotation
1999
+ about X, Y and Z respectively. The value can be 0 (for ignore)
2000
+ or above to assign a priority relative to other Cartesian DoF. The number
2001
+ of non-zero elements must equal the number of manipulator DOF.
2002
+
2003
+ For example when using a 3 DOF manipulator tool orientation might
2004
+ be unimportant, in which case use the option ``we=[1, 1, 1, 0, 0, 0]``.
2005
+
2006
+
2007
+
2008
+ .. note::
2009
+
2010
+ - See `Toolbox kinematics wiki page
2011
+ <https://github.com/petercorke/robotics-toolbox-python/wiki/Kinematics>`_
2012
+ - Implements a Levenberg-Marquadt variable-damping solver.
2013
+ - The tolerance is computed on the norm of the error between
2014
+ current and desired tool pose. This norm is computed from
2015
+ distances and angles without any kind of weighting.
2016
+ - The inverse kinematic solution is generally not unique, and
2017
+ depends on the initial guess ``q0``.
2018
+
2019
+ :references:
2020
+ TODO
2021
+
2022
+ :seealso:
2023
+ TODO
2024
+ """
2025
+
2026
+ return self.ets().ik_lm_chan(Tep, q0, ilimit, slimit, tol, reject_jl, we, λ)
2027
+
2028
+ def ik_lm_wampler(
2029
+ self,
2030
+ Tep: Union[np.ndarray, SE3],
2031
+ q0: Union[np.ndarray, None] = None,
2032
+ ilimit: int = 30,
2033
+ slimit: int = 100,
2034
+ tol: float = 1e-6,
2035
+ reject_jl: bool = True,
2036
+ we: Union[np.ndarray, None] = None,
2037
+ λ: float = 1.0,
2038
+ ) -> Tuple[np.ndarray, int, int, int, float]:
2039
+ """
2040
+ Numerical inverse kinematics by Levenberg-Marquadt optimization (Wamplers's Method)
2041
+
2042
+ :param Tep: The desired end-effector pose or pose trajectory
2043
+ :param q0: initial joint configuration (default to random valid joint
2044
+ configuration contrained by the joint limits of the robot)
2045
+ :param ilimit: maximum number of iterations per search
2046
+ :param slimit: maximum number of search attempts
2047
+ :param tol: final error tolerance
2048
+ :param reject_jl: constrain the solution to being within the joint limits of
2049
+ the robot (reject solution with invalid joint configurations and perfrom
2050
+ another search up to the slimit)
2051
+ :param we: a mask vector which weights the end-effector error priority.
2052
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2053
+ respectively
2054
+ :param λ: value of lambda for the damping matrix Wn
2055
+
2056
+ :return: inverse kinematic solution
2057
+ :rtype: tuple (q, success, iterations, searches, residual)
2058
+
2059
+ ``sol = ets.ik_lm_chan(Tep)`` are the joint coordinates (n) corresponding
2060
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2061
+ This method can be used for robots with any number of degrees of freedom.
2062
+ The return value ``sol`` is a tuple with elements:
2063
+
2064
+ ============ ========== ===============================================
2065
+ Element Type Description
2066
+ ============ ========== ===============================================
2067
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2068
+ ``success`` int whether a solution was found
2069
+ ``iterations`` int total number of iterations
2070
+ ``searches`` int total number of searches
2071
+ ``residual`` float final value of cost function
2072
+ ============ ========== ===============================================
2073
+
2074
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2075
+ solution will be in error. The amount of error is indicated by
2076
+ the ``residual``.
2077
+
2078
+ **Joint Limits**:
2079
+
2080
+ ``sol = robot.ikine_LM(T, slimit=100)`` which is the deafualt for this method.
2081
+ The solver will initialise a solution attempt with a random valid q0 and
2082
+ perform a maximum of ilimit steps within this attempt. If a solution is not
2083
+ found, this process is repeated up to slimit times.
2084
+
2085
+ **Global search**:
2086
+
2087
+ ``sol = robot.ikine_LM(T, reject_jl=True)`` is the deafualt for this method.
2088
+ By setting reject_jl to True, the solver will discard any solution which
2089
+ violates the defined joint limits of the robot. The solver will then
2090
+ re-initialise with a new random q0 and repeat the process up to slimit times.
2091
+ Note that finding a solution with valid joint coordinates takes longer than
2092
+ without.
2093
+
2094
+ **Underactuated robots:**
2095
+
2096
+ For the case where the manipulator has fewer than 6 DOF the
2097
+ solution space has more dimensions than can be spanned by the
2098
+ manipulator joint coordinates.
2099
+
2100
+ In this case we specify the ``we`` option where the ``we`` vector
2101
+ (6) specifies the Cartesian DOF (in the wrist coordinate frame) that
2102
+ will be ignored in reaching a solution. The we vector has six
2103
+ elements that correspond to translation in X, Y and Z, and rotation
2104
+ about X, Y and Z respectively. The value can be 0 (for ignore)
2105
+ or above to assign a priority relative to other Cartesian DoF. The number
2106
+ of non-zero elements must equal the number of manipulator DOF.
2107
+
2108
+ For example when using a 3 DOF manipulator tool orientation might
2109
+ be unimportant, in which case use the option ``we=[1, 1, 1, 0, 0, 0]``.
2110
+
2111
+
2112
+
2113
+ .. note::
2114
+
2115
+ - See `Toolbox kinematics wiki page
2116
+ <https://github.com/petercorke/robotics-toolbox-python/wiki/Kinematics>`_
2117
+ - Implements a Levenberg-Marquadt variable-damping solver.
2118
+ - The tolerance is computed on the norm of the error between
2119
+ current and desired tool pose. This norm is computed from
2120
+ distances and angles without any kind of weighting.
2121
+ - The inverse kinematic solution is generally not unique, and
2122
+ depends on the initial guess ``q0``.
2123
+
2124
+ :references:
2125
+ TODO
2126
+
2127
+ :seealso:
2128
+ TODO
2129
+ """
2130
+
2131
+ return self.ets().ik_lm_wampler(Tep, q0, ilimit, slimit, tol, reject_jl, we, λ)
2132
+
2133
+ def ik_lm_sugihara(
2134
+ self,
2135
+ Tep: Union[np.ndarray, SE3],
2136
+ q0: Union[np.ndarray, None] = None,
2137
+ ilimit: int = 30,
2138
+ slimit: int = 100,
2139
+ tol: float = 1e-6,
2140
+ reject_jl: bool = True,
2141
+ we: Union[np.ndarray, None] = None,
2142
+ λ: float = 1.0,
2143
+ ) -> Tuple[np.ndarray, int, int, int, float]:
2144
+ """
2145
+ Numerical inverse kinematics by Levenberg-Marquadt optimization (Sugihara's Method)
2146
+
2147
+ :param Tep: The desired end-effector pose or pose trajectory
2148
+ :param q0: initial joint configuration (default to random valid joint
2149
+ configuration contrained by the joint limits of the robot)
2150
+ :param ilimit: maximum number of iterations per search
2151
+ :param slimit: maximum number of search attempts
2152
+ :param tol: final error tolerance
2153
+ :param reject_jl: constrain the solution to being within the joint limits of
2154
+ the robot (reject solution with invalid joint configurations and perfrom
2155
+ another search up to the slimit)
2156
+ :param we: a mask vector which weights the end-effector error priority.
2157
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2158
+ respectively
2159
+ :param λ: value of lambda for the damping matrix Wn
2160
+
2161
+ :return: inverse kinematic solution
2162
+ :rtype: tuple (q, success, iterations, searches, residual)
2163
+
2164
+ ``sol = ets.ik_lm_chan(Tep)`` are the joint coordinates (n) corresponding
2165
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2166
+ This method can be used for robots with any number of degrees of freedom.
2167
+ The return value ``sol`` is a tuple with elements:
2168
+
2169
+ ============ ========== ===============================================
2170
+ Element Type Description
2171
+ ============ ========== ===============================================
2172
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2173
+ ``success`` int whether a solution was found
2174
+ ``iterations`` int total number of iterations
2175
+ ``searches`` int total number of searches
2176
+ ``residual`` float final value of cost function
2177
+ ============ ========== ===============================================
2178
+
2179
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2180
+ solution will be in error. The amount of error is indicated by
2181
+ the ``residual``.
2182
+
2183
+ **Joint Limits**:
2184
+
2185
+ ``sol = robot.ikine_LM(T, slimit=100)`` which is the deafualt for this method.
2186
+ The solver will initialise a solution attempt with a random valid q0 and
2187
+ perform a maximum of ilimit steps within this attempt. If a solution is not
2188
+ found, this process is repeated up to slimit times.
2189
+
2190
+ **Global search**:
2191
+
2192
+ ``sol = robot.ikine_LM(T, reject_jl=True)`` is the deafualt for this method.
2193
+ By setting reject_jl to True, the solver will discard any solution which
2194
+ violates the defined joint limits of the robot. The solver will then
2195
+ re-initialise with a new random q0 and repeat the process up to slimit times.
2196
+ Note that finding a solution with valid joint coordinates takes longer than
2197
+ without.
2198
+
2199
+ **Underactuated robots:**
2200
+
2201
+ For the case where the manipulator has fewer than 6 DOF the
2202
+ solution space has more dimensions than can be spanned by the
2203
+ manipulator joint coordinates.
2204
+
2205
+ In this case we specify the ``we`` option where the ``we`` vector
2206
+ (6) specifies the Cartesian DOF (in the wrist coordinate frame) that
2207
+ will be ignored in reaching a solution. The we vector has six
2208
+ elements that correspond to translation in X, Y and Z, and rotation
2209
+ about X, Y and Z respectively. The value can be 0 (for ignore)
2210
+ or above to assign a priority relative to other Cartesian DoF. The number
2211
+ of non-zero elements must equal the number of manipulator DOF.
2212
+
2213
+ For example when using a 3 DOF manipulator tool orientation might
2214
+ be unimportant, in which case use the option ``we=[1, 1, 1, 0, 0, 0]``.
2215
+
2216
+
2217
+
2218
+ .. note::
2219
+
2220
+ - See `Toolbox kinematics wiki page
2221
+ <https://github.com/petercorke/robotics-toolbox-python/wiki/Kinematics>`_
2222
+ - Implements a Levenberg-Marquadt variable-damping solver.
2223
+ - The tolerance is computed on the norm of the error between
2224
+ current and desired tool pose. This norm is computed from
2225
+ distances and angles without any kind of weighting.
2226
+ - The inverse kinematic solution is generally not unique, and
2227
+ depends on the initial guess ``q0``.
2228
+
2229
+ :references:
2230
+ TODO
2231
+
2232
+ :seealso:
2233
+ TODO
2234
+ """
2235
+
2236
+ return self.ets().ik_lm_sugihara(Tep, q0, ilimit, slimit, tol, reject_jl, we, λ)
2237
+
2238
+ def ik_nr(
2239
+ self,
2240
+ Tep: Union[np.ndarray, SE3],
2241
+ q0: Union[np.ndarray, None] = None,
2242
+ ilimit: int = 30,
2243
+ slimit: int = 100,
2244
+ tol: float = 1e-6,
2245
+ reject_jl: bool = True,
2246
+ we: Union[np.ndarray, None] = None,
2247
+ use_pinv: int = True,
2248
+ pinv_damping: float = 0.0,
2249
+ ) -> Tuple[np.ndarray, int, int, int, float]:
2250
+ """
2251
+ Numerical inverse kinematics by Levenberg-Marquadt optimization (Newton-Raphson Method)
2252
+
2253
+ :param Tep: The desired end-effector pose or pose trajectory
2254
+ :param q0: initial joint configuration (default to random valid joint
2255
+ configuration contrained by the joint limits of the robot)
2256
+ :param ilimit: maximum number of iterations per search
2257
+ :param slimit: maximum number of search attempts
2258
+ :param tol: final error tolerance
2259
+ :param reject_jl: constrain the solution to being within the joint limits of
2260
+ the robot (reject solution with invalid joint configurations and perfrom
2261
+ another search up to the slimit)
2262
+ :param we: a mask vector which weights the end-effector error priority.
2263
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2264
+ respectively
2265
+ :param λ: value of lambda for the damping matrix Wn
2266
+
2267
+ :return: inverse kinematic solution
2268
+ :rtype: tuple (q, success, iterations, searches, residual)
2269
+
2270
+ ``sol = ets.ik_lm_chan(Tep)`` are the joint coordinates (n) corresponding
2271
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2272
+ This method can be used for robots with any number of degrees of freedom.
2273
+ The return value ``sol`` is a tuple with elements:
2274
+
2275
+ ============ ========== ===============================================
2276
+ Element Type Description
2277
+ ============ ========== ===============================================
2278
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2279
+ ``success`` int whether a solution was found
2280
+ ``iterations`` int total number of iterations
2281
+ ``searches`` int total number of searches
2282
+ ``residual`` float final value of cost function
2283
+ ============ ========== ===============================================
2284
+
2285
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2286
+ solution will be in error. The amount of error is indicated by
2287
+ the ``residual``.
2288
+
2289
+ **Joint Limits**:
2290
+
2291
+ ``sol = robot.ikine_LM(T, slimit=100)`` which is the deafualt for this method.
2292
+ The solver will initialise a solution attempt with a random valid q0 and
2293
+ perform a maximum of ilimit steps within this attempt. If a solution is not
2294
+ found, this process is repeated up to slimit times.
2295
+
2296
+ **Global search**:
2297
+
2298
+ ``sol = robot.ikine_LM(T, reject_jl=True)`` is the deafualt for this method.
2299
+ By setting reject_jl to True, the solver will discard any solution which
2300
+ violates the defined joint limits of the robot. The solver will then
2301
+ re-initialise with a new random q0 and repeat the process up to slimit times.
2302
+ Note that finding a solution with valid joint coordinates takes longer than
2303
+ without.
2304
+
2305
+ **Underactuated robots:**
2306
+
2307
+ For the case where the manipulator has fewer than 6 DOF the
2308
+ solution space has more dimensions than can be spanned by the
2309
+ manipulator joint coordinates.
2310
+
2311
+ In this case we specify the ``we`` option where the ``we`` vector
2312
+ (6) specifies the Cartesian DOF (in the wrist coordinate frame) that
2313
+ will be ignored in reaching a solution. The we vector has six
2314
+ elements that correspond to translation in X, Y and Z, and rotation
2315
+ about X, Y and Z respectively. The value can be 0 (for ignore)
2316
+ or above to assign a priority relative to other Cartesian DoF. The number
2317
+ of non-zero elements must equal the number of manipulator DOF.
2318
+
2319
+ For example when using a 3 DOF manipulator tool orientation might
2320
+ be unimportant, in which case use the option ``we=[1, 1, 1, 0, 0, 0]``.
2321
+
2322
+
2323
+
2324
+ .. note::
2325
+
2326
+ - See `Toolbox kinematics wiki page
2327
+ <https://github.com/petercorke/robotics-toolbox-python/wiki/Kinematics>`_
2328
+ - Implements a Levenberg-Marquadt variable-damping solver.
2329
+ - The tolerance is computed on the norm of the error between
2330
+ current and desired tool pose. This norm is computed from
2331
+ distances and angles without any kind of weighting.
2332
+ - The inverse kinematic solution is generally not unique, and
2333
+ depends on the initial guess ``q0``.
2334
+
2335
+ :references:
2336
+ TODO
2337
+
2338
+ :seealso:
2339
+ TODO
2340
+ """
2341
+
2342
+ return self.ets().ik_nr(
2343
+ Tep, q0, ilimit, slimit, tol, reject_jl, we, use_pinv, pinv_damping
2344
+ )
2345
+
2346
+ def ik_gn(
2347
+ self,
2348
+ Tep: Union[np.ndarray, SE3],
2349
+ q0: Union[np.ndarray, None] = None,
2350
+ ilimit: int = 30,
2351
+ slimit: int = 100,
2352
+ tol: float = 1e-6,
2353
+ reject_jl: bool = True,
2354
+ we: Union[np.ndarray, None] = None,
2355
+ use_pinv: int = True,
2356
+ pinv_damping: float = 0.0,
2357
+ ) -> Tuple[np.ndarray, int, int, int, float]:
2358
+ """
2359
+ Numerical inverse kinematics by Levenberg-Marquadt optimization (Gauss-Newton Method)
2360
+
2361
+ :param Tep: The desired end-effector pose or pose trajectory
2362
+ :param q0: initial joint configuration (default to random valid joint
2363
+ configuration contrained by the joint limits of the robot)
2364
+ :param ilimit: maximum number of iterations per search
2365
+ :param slimit: maximum number of search attempts
2366
+ :param tol: final error tolerance
2367
+ :param reject_jl: constrain the solution to being within the joint limits of
2368
+ the robot (reject solution with invalid joint configurations and perfrom
2369
+ another search up to the slimit)
2370
+ :param we: a mask vector which weights the end-effector error priority.
2371
+ Corresponds to translation in X, Y and Z and rotation about X, Y and Z
2372
+ respectively
2373
+ :param λ: value of lambda for the damping matrix Wn
2374
+
2375
+ :return: inverse kinematic solution
2376
+ :rtype: tuple (q, success, iterations, searches, residual)
2377
+
2378
+ ``sol = ets.ik_lm_chan(Tep)`` are the joint coordinates (n) corresponding
2379
+ to the robot end-effector pose ``Tep`` which is an ``SE3`` or ``ndarray`` object.
2380
+ This method can be used for robots with any number of degrees of freedom.
2381
+ The return value ``sol`` is a tuple with elements:
2382
+
2383
+ ============ ========== ===============================================
2384
+ Element Type Description
2385
+ ============ ========== ===============================================
2386
+ ``q`` ndarray(n) joint coordinates in units of radians or metres
2387
+ ``success`` int whether a solution was found
2388
+ ``iterations`` int total number of iterations
2389
+ ``searches`` int total number of searches
2390
+ ``residual`` float final value of cost function
2391
+ ============ ========== ===============================================
2392
+
2393
+ If ``success == 0`` the ``q`` values will be valid numbers, but the
2394
+ solution will be in error. The amount of error is indicated by
2395
+ the ``residual``.
2396
+
2397
+ **Joint Limits**:
2398
+
2399
+ ``sol = robot.ikine_LM(T, slimit=100)`` which is the deafualt for this method.
2400
+ The solver will initialise a solution attempt with a random valid q0 and
2401
+ perform a maximum of ilimit steps within this attempt. If a solution is not
2402
+ found, this process is repeated up to slimit times.
2403
+
2404
+ **Global search**:
2405
+
2406
+ ``sol = robot.ikine_LM(T, reject_jl=True)`` is the deafualt for this method.
2407
+ By setting reject_jl to True, the solver will discard any solution which
2408
+ violates the defined joint limits of the robot. The solver will then
2409
+ re-initialise with a new random q0 and repeat the process up to slimit times.
2410
+ Note that finding a solution with valid joint coordinates takes longer than
2411
+ without.
2412
+
2413
+ **Underactuated robots:**
2414
+
2415
+ For the case where the manipulator has fewer than 6 DOF the
2416
+ solution space has more dimensions than can be spanned by the
2417
+ manipulator joint coordinates.
2418
+
2419
+ In this case we specify the ``we`` option where the ``we`` vector
2420
+ (6) specifies the Cartesian DOF (in the wrist coordinate frame) that
2421
+ will be ignored in reaching a solution. The we vector has six
2422
+ elements that correspond to translation in X, Y and Z, and rotation
2423
+ about X, Y and Z respectively. The value can be 0 (for ignore)
2424
+ or above to assign a priority relative to other Cartesian DoF. The number
2425
+ of non-zero elements must equal the number of manipulator DOF.
2426
+
2427
+ For example when using a 3 DOF manipulator tool orientation might
2428
+ be unimportant, in which case use the option ``we=[1, 1, 1, 0, 0, 0]``.
2429
+
2430
+
2431
+
2432
+ .. note::
2433
+
2434
+ - See `Toolbox kinematics wiki page
2435
+ <https://github.com/petercorke/robotics-toolbox-python/wiki/Kinematics>`_
2436
+ - Implements a Levenberg-Marquadt variable-damping solver.
2437
+ - The tolerance is computed on the norm of the error between
2438
+ current and desired tool pose. This norm is computed from
2439
+ distances and angles without any kind of weighting.
2440
+ - The inverse kinematic solution is generally not unique, and
2441
+ depends on the initial guess ``q0``.
2442
+
2443
+ :references:
2444
+ TODO
2445
+
2446
+ :seealso:
2447
+ TODO
2448
+ """
2449
+
2450
+ return self.ets().ik_gn(
2451
+ Tep, q0, ilimit, slimit, tol, reject_jl, we, use_pinv, pinv_damping
2452
+ )
2453
+
2454
+ def ikine_LM(
2455
+ self,
2456
+ Tep: Union[np.ndarray, SE3],
2457
+ q0: Union[ArrayLike, None] = None,
2458
+ ilimit: int = 30,
2459
+ slimit: int = 100,
2460
+ tol: float = 1e-6,
2461
+ joint_limits: bool = False,
2462
+ mask: Union[ArrayLike, None] = None,
2463
+ seed: Union[int, None] = None,
2464
+ ):
2465
+ return self.ets().ikine_LM(
2466
+ Tep=Tep,
2467
+ q0=q0,
2468
+ ilimit=ilimit,
2469
+ slimit=slimit,
2470
+ tol=tol,
2471
+ joint_limits=joint_limits,
2472
+ mask=mask,
2473
+ seed=seed,
2474
+ )
2475
+
2476
+
2477
+ class SerialLink(DHRobot):
2478
+ def __init__(self, *args, **kwargs):
2479
+ warnings.warn(
2480
+ "SerialLink is deprecated, use DHRobot instead", DeprecationWarning
2481
+ )
2482
+ super().__init__(*args, **kwargs)
2483
+
2484
+
2485
+ def _cross(a, b):
2486
+ return np.r_[
2487
+ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]
2488
+ ]
2489
+
2490
+
2491
+ if __name__ == "__main__": # pragma nocover
2492
+ import roboticstoolbox as rtb
2493
+
2494
+ # import spatialmath.base.symbolic as sym
2495
+
2496
+ # planar = rtb.models.DH.Planar2()
2497
+ # J = puma.jacob0(puma.qn)
2498
+ # print(J)
2499
+ # print(puma.manipulability(puma.qn))
2500
+ # print(puma.manipulability(puma.qn, 'asada'))
2501
+ # tw, T0 = puma.twists(puma.qz)
2502
+ # print(planar)
2503
+
2504
+ puma = rtb.models.DH.Puma560()
2505
+ print(puma)
2506
+ # print(puma.jacob0(puma.qn, analytical="eul"))
2507
+ # puma.base = None
2508
+ # print('base', puma.base)
2509
+ # print('tool', puma.tool)
2510
+
2511
+ # print(puma.ets())
2512
+
2513
+ # puma[2].flip = True
2514
+ # puma[3].offset = 1
2515
+ # puma[4].flip = True
2516
+ # puma[4].offset = -1
2517
+ # print(puma)
2518
+ # print(puma.ets())
2519
+
2520
+ # print(puma.dyntable())