roboticstoolbox-python 1.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (610) hide show
  1. roboticstoolbox/__init__.py +107 -0
  2. roboticstoolbox/backends/Connector.py +113 -0
  3. roboticstoolbox/backends/Dynamixel/README.md +9 -0
  4. roboticstoolbox/backends/Dynamixel/dynamixel.json +581 -0
  5. roboticstoolbox/backends/Dynamixel/dynamixel_io.py +450 -0
  6. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/LICENSE +201 -0
  7. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/README.md +28 -0
  8. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/ReleaseNote.md +181 -0
  9. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/__init__.py +27 -0
  10. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_read.py +163 -0
  11. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_write.py +109 -0
  12. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_read.py +166 -0
  13. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_write.py +99 -0
  14. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/packet_handler.py +33 -0
  15. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/port_handler.py +155 -0
  16. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol1_packet_handler.py +548 -0
  17. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol2_packet_handler.py +1080 -0
  18. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/robotis_def.py +75 -0
  19. roboticstoolbox/backends/Dynamixel/dyndata.py +121 -0
  20. roboticstoolbox/backends/PyPlot/EllipsePlot.py +256 -0
  21. roboticstoolbox/backends/PyPlot/PyPlot.py +778 -0
  22. roboticstoolbox/backends/PyPlot/PyPlot2.py +537 -0
  23. roboticstoolbox/backends/PyPlot/README.md +67 -0
  24. roboticstoolbox/backends/PyPlot/RobotPlot.py +247 -0
  25. roboticstoolbox/backends/PyPlot/RobotPlot2.py +123 -0
  26. roboticstoolbox/backends/PyPlot/__init__.py +4 -0
  27. roboticstoolbox/backends/ROS/ROS.py +129 -0
  28. roboticstoolbox/backends/ROS/__init__.py +3 -0
  29. roboticstoolbox/backends/__init__.py +39 -0
  30. roboticstoolbox/backends/swift/__init__.py +165 -0
  31. roboticstoolbox/bin/__init__.py +0 -0
  32. roboticstoolbox/bin/_bintools.py +61 -0
  33. roboticstoolbox/bin/rtbtool.py +404 -0
  34. roboticstoolbox/blocks/Icons/250x250/armplot.png +0 -0
  35. roboticstoolbox/blocks/Icons/250x250/bicycle.png +0 -0
  36. roboticstoolbox/blocks/Icons/250x250/camera.png +0 -0
  37. roboticstoolbox/blocks/Icons/250x250/circlepath.png +0 -0
  38. roboticstoolbox/blocks/Icons/250x250/coriolis.png +0 -0
  39. roboticstoolbox/blocks/Icons/250x250/ctraj.png +0 -0
  40. roboticstoolbox/blocks/Icons/250x250/delta2tr.png +0 -0
  41. roboticstoolbox/blocks/Icons/250x250/diffsteer.png +0 -0
  42. roboticstoolbox/blocks/Icons/250x250/fdyn.png +0 -0
  43. roboticstoolbox/blocks/Icons/250x250/fdynx.png +0 -0
  44. roboticstoolbox/blocks/Icons/250x250/fkine.png +0 -0
  45. roboticstoolbox/blocks/Icons/250x250/gravload.png +0 -0
  46. roboticstoolbox/blocks/Icons/250x250/idyn.png +0 -0
  47. roboticstoolbox/blocks/Icons/250x250/idynx.png +0 -0
  48. roboticstoolbox/blocks/Icons/250x250/ikine.png +0 -0
  49. roboticstoolbox/blocks/Icons/250x250/inertia.png +0 -0
  50. roboticstoolbox/blocks/Icons/250x250/jacobian.png +0 -0
  51. roboticstoolbox/blocks/Icons/250x250/jtraj.png +0 -0
  52. roboticstoolbox/blocks/Icons/250x250/lspb.png +0 -0
  53. roboticstoolbox/blocks/Icons/250x250/multirotor.png +0 -0
  54. roboticstoolbox/blocks/Icons/250x250/multirotormixer.png +0 -0
  55. roboticstoolbox/blocks/Icons/250x250/multirotorplot.png +0 -0
  56. roboticstoolbox/blocks/Icons/250x250/point2tr.png +0 -0
  57. roboticstoolbox/blocks/Icons/250x250/tr2delta.png +0 -0
  58. roboticstoolbox/blocks/Icons/250x250/tr2t.png +0 -0
  59. roboticstoolbox/blocks/Icons/250x250/unicycle.png +0 -0
  60. roboticstoolbox/blocks/Icons/250x250/vehicleplot.png +0 -0
  61. roboticstoolbox/blocks/Icons/50x50/armplot.png +0 -0
  62. roboticstoolbox/blocks/Icons/50x50/bicycle.png +0 -0
  63. roboticstoolbox/blocks/Icons/50x50/camera.png +0 -0
  64. roboticstoolbox/blocks/Icons/50x50/circlepath.png +0 -0
  65. roboticstoolbox/blocks/Icons/50x50/coriolis.png +0 -0
  66. roboticstoolbox/blocks/Icons/50x50/delta2tr.png +0 -0
  67. roboticstoolbox/blocks/Icons/50x50/diffsteer.png +0 -0
  68. roboticstoolbox/blocks/Icons/50x50/fdyn.png +0 -0
  69. roboticstoolbox/blocks/Icons/50x50/fdynx.png +0 -0
  70. roboticstoolbox/blocks/Icons/50x50/fkine.png +0 -0
  71. roboticstoolbox/blocks/Icons/50x50/gravload.png +0 -0
  72. roboticstoolbox/blocks/Icons/50x50/idyn.png +0 -0
  73. roboticstoolbox/blocks/Icons/50x50/idynx.png +0 -0
  74. roboticstoolbox/blocks/Icons/50x50/ikine.png +0 -0
  75. roboticstoolbox/blocks/Icons/50x50/inertia.png +0 -0
  76. roboticstoolbox/blocks/Icons/50x50/jacobian.png +0 -0
  77. roboticstoolbox/blocks/Icons/50x50/jtraj.png +0 -0
  78. roboticstoolbox/blocks/Icons/50x50/lspb.png +0 -0
  79. roboticstoolbox/blocks/Icons/50x50/multirotor.png +0 -0
  80. roboticstoolbox/blocks/Icons/50x50/multirotormixer.png +0 -0
  81. roboticstoolbox/blocks/Icons/50x50/multirotorplot.png +0 -0
  82. roboticstoolbox/blocks/Icons/50x50/point2tr.png +0 -0
  83. roboticstoolbox/blocks/Icons/50x50/tr2delta.png +0 -0
  84. roboticstoolbox/blocks/Icons/50x50/tr2t.png +0 -0
  85. roboticstoolbox/blocks/Icons/50x50/unicycle.png +0 -0
  86. roboticstoolbox/blocks/Icons/50x50/vehicleplot.png +0 -0
  87. roboticstoolbox/blocks/Icons/armplot.png +0 -0
  88. roboticstoolbox/blocks/Icons/bicycle.png +0 -0
  89. roboticstoolbox/blocks/Icons/camera.png +0 -0
  90. roboticstoolbox/blocks/Icons/circlepath.png +0 -0
  91. roboticstoolbox/blocks/Icons/coriolis.png +0 -0
  92. roboticstoolbox/blocks/Icons/ctraj.png +0 -0
  93. roboticstoolbox/blocks/Icons/delta2tr.png +0 -0
  94. roboticstoolbox/blocks/Icons/diffsteer.png +0 -0
  95. roboticstoolbox/blocks/Icons/fdyn.png +0 -0
  96. roboticstoolbox/blocks/Icons/fdynx.png +0 -0
  97. roboticstoolbox/blocks/Icons/fkine.png +0 -0
  98. roboticstoolbox/blocks/Icons/gravload.png +0 -0
  99. roboticstoolbox/blocks/Icons/idyn.png +0 -0
  100. roboticstoolbox/blocks/Icons/idynx.png +0 -0
  101. roboticstoolbox/blocks/Icons/ikine.png +0 -0
  102. roboticstoolbox/blocks/Icons/inertia.png +0 -0
  103. roboticstoolbox/blocks/Icons/jacobian.png +0 -0
  104. roboticstoolbox/blocks/Icons/jtraj.png +0 -0
  105. roboticstoolbox/blocks/Icons/lspb.png +0 -0
  106. roboticstoolbox/blocks/Icons/multirotor.png +0 -0
  107. roboticstoolbox/blocks/Icons/multirotormixer.png +0 -0
  108. roboticstoolbox/blocks/Icons/multirotorplot.png +0 -0
  109. roboticstoolbox/blocks/Icons/point2tr.png +0 -0
  110. roboticstoolbox/blocks/Icons/tr2delta.png +0 -0
  111. roboticstoolbox/blocks/Icons/tr2t.png +0 -0
  112. roboticstoolbox/blocks/Icons/unicycle.png +0 -0
  113. roboticstoolbox/blocks/Icons/vehicleplot.png +0 -0
  114. roboticstoolbox/blocks/README.md +43 -0
  115. roboticstoolbox/blocks/__init__.py +6 -0
  116. roboticstoolbox/blocks/arm.py +1591 -0
  117. roboticstoolbox/blocks/mobile.py +522 -0
  118. roboticstoolbox/blocks/quad_model.py +132 -0
  119. roboticstoolbox/blocks/spatial.py +245 -0
  120. roboticstoolbox/blocks/uav.py +949 -0
  121. roboticstoolbox/demo/__init__.py +0 -0
  122. roboticstoolbox/demo/eigdemo.py +112 -0
  123. roboticstoolbox/demo/tripleangledemo.py +239 -0
  124. roboticstoolbox/demo/twistdemo.py +175 -0
  125. roboticstoolbox/ets/ET.py +439 -0
  126. roboticstoolbox/ets/ET2.py +179 -0
  127. roboticstoolbox/ets/ETS.py +2013 -0
  128. roboticstoolbox/ets/ETS2.py +449 -0
  129. roboticstoolbox/ets/_ET.py +668 -0
  130. roboticstoolbox/ets/_ETS.py +781 -0
  131. roboticstoolbox/ets/__init__.py +11 -0
  132. roboticstoolbox/ets/cpp-extensions/Eigen/Cholesky +45 -0
  133. roboticstoolbox/ets/cpp-extensions/Eigen/CholmodSupport +48 -0
  134. roboticstoolbox/ets/cpp-extensions/Eigen/Core +384 -0
  135. roboticstoolbox/ets/cpp-extensions/Eigen/Dense +7 -0
  136. roboticstoolbox/ets/cpp-extensions/Eigen/Eigen +2 -0
  137. roboticstoolbox/ets/cpp-extensions/Eigen/Eigenvalues +60 -0
  138. roboticstoolbox/ets/cpp-extensions/Eigen/Geometry +59 -0
  139. roboticstoolbox/ets/cpp-extensions/Eigen/Householder +29 -0
  140. roboticstoolbox/ets/cpp-extensions/Eigen/IterativeLinearSolvers +48 -0
  141. roboticstoolbox/ets/cpp-extensions/Eigen/Jacobi +32 -0
  142. roboticstoolbox/ets/cpp-extensions/Eigen/KLUSupport +41 -0
  143. roboticstoolbox/ets/cpp-extensions/Eigen/LU +47 -0
  144. roboticstoolbox/ets/cpp-extensions/Eigen/MetisSupport +35 -0
  145. roboticstoolbox/ets/cpp-extensions/Eigen/OrderingMethods +70 -0
  146. roboticstoolbox/ets/cpp-extensions/Eigen/PaStiXSupport +49 -0
  147. roboticstoolbox/ets/cpp-extensions/Eigen/PardisoSupport +35 -0
  148. roboticstoolbox/ets/cpp-extensions/Eigen/QR +50 -0
  149. roboticstoolbox/ets/cpp-extensions/Eigen/QtAlignedMalloc +39 -0
  150. roboticstoolbox/ets/cpp-extensions/Eigen/SPQRSupport +34 -0
  151. roboticstoolbox/ets/cpp-extensions/Eigen/SVD +50 -0
  152. roboticstoolbox/ets/cpp-extensions/Eigen/Sparse +34 -0
  153. roboticstoolbox/ets/cpp-extensions/Eigen/SparseCholesky +37 -0
  154. roboticstoolbox/ets/cpp-extensions/Eigen/SparseCore +69 -0
  155. roboticstoolbox/ets/cpp-extensions/Eigen/SparseLU +50 -0
  156. roboticstoolbox/ets/cpp-extensions/Eigen/SparseQR +36 -0
  157. roboticstoolbox/ets/cpp-extensions/Eigen/StdDeque +27 -0
  158. roboticstoolbox/ets/cpp-extensions/Eigen/StdList +26 -0
  159. roboticstoolbox/ets/cpp-extensions/Eigen/StdVector +27 -0
  160. roboticstoolbox/ets/cpp-extensions/Eigen/SuperLUSupport +64 -0
  161. roboticstoolbox/ets/cpp-extensions/Eigen/UmfPackSupport +40 -0
  162. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LDLT.h +688 -0
  163. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LLT.h +558 -0
  164. roboticstoolbox/ets/cpp-extensions/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  165. roboticstoolbox/ets/cpp-extensions/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  166. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArithmeticSequence.h +413 -0
  167. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Array.h +417 -0
  168. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArrayBase.h +226 -0
  169. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ArrayWrapper.h +209 -0
  170. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Assign.h +90 -0
  171. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/AssignEvaluator.h +1010 -0
  172. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Assign_MKL.h +178 -0
  173. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/BandMatrix.h +353 -0
  174. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Block.h +448 -0
  175. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/BooleanRedux.h +162 -0
  176. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CommaInitializer.h +164 -0
  177. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ConditionEstimator.h +175 -0
  178. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CoreEvaluators.h +1741 -0
  179. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CoreIterators.h +132 -0
  180. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  181. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  182. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  183. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  184. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/CwiseUnaryView.h +132 -0
  185. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseBase.h +701 -0
  186. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  187. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DenseStorage.h +652 -0
  188. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Diagonal.h +258 -0
  189. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DiagonalMatrix.h +391 -0
  190. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/DiagonalProduct.h +28 -0
  191. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Dot.h +318 -0
  192. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/EigenBase.h +160 -0
  193. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  194. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Fuzzy.h +155 -0
  195. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GeneralProduct.h +465 -0
  196. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GenericPacketMath.h +1040 -0
  197. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/GlobalFunctions.h +194 -0
  198. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/IO.h +258 -0
  199. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/IndexedView.h +237 -0
  200. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Inverse.h +117 -0
  201. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Map.h +171 -0
  202. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MapBase.h +310 -0
  203. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MathFunctions.h +2057 -0
  204. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  205. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Matrix.h +565 -0
  206. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/MatrixBase.h +547 -0
  207. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NestByValue.h +85 -0
  208. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NoAlias.h +109 -0
  209. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/NumTraits.h +335 -0
  210. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  211. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PermutationMatrix.h +605 -0
  212. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/PlainObjectBase.h +1128 -0
  213. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Product.h +191 -0
  214. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ProductEvaluators.h +1179 -0
  215. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Random.h +218 -0
  216. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Redux.h +515 -0
  217. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Ref.h +381 -0
  218. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Replicate.h +142 -0
  219. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Reshaped.h +454 -0
  220. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/ReturnByValue.h +119 -0
  221. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Reverse.h +217 -0
  222. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Select.h +164 -0
  223. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SelfAdjointView.h +365 -0
  224. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  225. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Solve.h +188 -0
  226. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SolveTriangular.h +235 -0
  227. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/SolverBase.h +168 -0
  228. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/StableNorm.h +251 -0
  229. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/StlIterators.h +463 -0
  230. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Stride.h +116 -0
  231. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Swap.h +68 -0
  232. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Transpose.h +464 -0
  233. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Transpositions.h +386 -0
  234. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/TriangularMatrix.h +1001 -0
  235. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/VectorBlock.h +96 -0
  236. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/VectorwiseOp.h +784 -0
  237. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/Visitor.h +381 -0
  238. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  239. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  240. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  241. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  242. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  243. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  244. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  245. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  246. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  247. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  248. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  249. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  250. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  251. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  252. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  253. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  254. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  255. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  256. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  257. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/Half.h +942 -0
  258. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/Settings.h +49 -0
  259. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  260. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  261. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  262. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  263. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  264. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  265. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  266. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  267. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  268. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  269. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  270. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  271. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  272. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  273. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  274. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  275. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  276. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  277. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  278. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  279. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  280. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  281. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  282. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  283. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  284. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  285. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  286. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  287. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  288. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  289. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  290. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/StlFunctors.h +166 -0
  291. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  292. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  293. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  294. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  295. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  296. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  297. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  298. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  299. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  300. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/Parallelizer.h +180 -0
  301. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  302. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  303. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  304. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  305. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  306. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  307. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  308. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  309. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  310. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  311. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  312. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  313. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  314. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/BlasUtil.h +583 -0
  315. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  316. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Constants.h +563 -0
  317. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  318. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  319. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  320. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/IntegralConstant.h +272 -0
  321. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/MKL_support.h +137 -0
  322. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Macros.h +1464 -0
  323. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Memory.h +1163 -0
  324. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/Meta.h +812 -0
  325. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/NonMPL2.h +3 -0
  326. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  327. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  328. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/StaticAssert.h +221 -0
  329. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  330. roboticstoolbox/ets/cpp-extensions/Eigen/src/Core/util/XprHelper.h +856 -0
  331. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  332. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  333. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  334. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  335. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  336. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  337. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  338. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  339. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  340. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  341. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  342. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  343. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  344. roboticstoolbox/ets/cpp-extensions/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  345. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/AlignedBox.h +486 -0
  346. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/AngleAxis.h +247 -0
  347. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/EulerAngles.h +114 -0
  348. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Homogeneous.h +501 -0
  349. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Hyperplane.h +282 -0
  350. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/OrthoMethods.h +235 -0
  351. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  352. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Quaternion.h +870 -0
  353. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Rotation2D.h +199 -0
  354. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/RotationBase.h +206 -0
  355. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Scaling.h +188 -0
  356. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Transform.h +1563 -0
  357. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Translation.h +202 -0
  358. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/Umeyama.h +166 -0
  359. roboticstoolbox/ets/cpp-extensions/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  360. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/BlockHouseholder.h +110 -0
  361. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/Householder.h +176 -0
  362. roboticstoolbox/ets/cpp-extensions/Eigen/src/Householder/HouseholderSequence.h +545 -0
  363. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  364. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  365. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  366. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  367. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  368. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  369. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  370. roboticstoolbox/ets/cpp-extensions/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  371. roboticstoolbox/ets/cpp-extensions/Eigen/src/Jacobi/Jacobi.h +483 -0
  372. roboticstoolbox/ets/cpp-extensions/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  373. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/Determinant.h +117 -0
  374. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/FullPivLU.h +877 -0
  375. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/InverseImpl.h +432 -0
  376. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/PartialPivLU.h +624 -0
  377. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  378. roboticstoolbox/ets/cpp-extensions/Eigen/src/LU/arch/InverseSize4.h +351 -0
  379. roboticstoolbox/ets/cpp-extensions/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  380. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Amd.h +435 -0
  381. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  382. roboticstoolbox/ets/cpp-extensions/Eigen/src/OrderingMethods/Ordering.h +153 -0
  383. roboticstoolbox/ets/cpp-extensions/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  384. roboticstoolbox/ets/cpp-extensions/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  385. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  386. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  387. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  388. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  389. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/HouseholderQR.h +434 -0
  390. roboticstoolbox/ets/cpp-extensions/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  391. roboticstoolbox/ets/cpp-extensions/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  392. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/BDCSVD.h +1366 -0
  393. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/JacobiSVD.h +812 -0
  394. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  395. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/SVDBase.h +376 -0
  396. roboticstoolbox/ets/cpp-extensions/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  397. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  398. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  399. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/AmbiVector.h +378 -0
  400. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  401. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  402. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  403. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseAssign.h +270 -0
  404. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseBlock.h +571 -0
  405. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  406. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  407. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  408. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  409. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  410. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  411. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseDot.h +98 -0
  412. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  413. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMap.h +305 -0
  414. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  415. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  416. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  417. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseProduct.h +181 -0
  418. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseRedux.h +49 -0
  419. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseRef.h +397 -0
  420. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  421. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  422. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  423. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  424. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  425. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseUtil.h +186 -0
  426. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseVector.h +478 -0
  427. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/SparseView.h +254 -0
  428. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  429. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU.h +923 -0
  430. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  431. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  432. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  433. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  434. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  435. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  436. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  437. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  438. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  439. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  440. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  441. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  442. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  443. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  444. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  445. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  446. roboticstoolbox/ets/cpp-extensions/Eigen/src/SparseQR/SparseQR.h +758 -0
  447. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdDeque.h +116 -0
  448. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdList.h +106 -0
  449. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/StdVector.h +131 -0
  450. roboticstoolbox/ets/cpp-extensions/Eigen/src/StlSupport/details.h +84 -0
  451. roboticstoolbox/ets/cpp-extensions/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  452. roboticstoolbox/ets/cpp-extensions/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  453. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/Image.h +82 -0
  454. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/Kernel.h +79 -0
  455. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/RealSvd2x2.h +55 -0
  456. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/blas.h +440 -0
  457. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapack.h +152 -0
  458. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapacke.h +16292 -0
  459. roboticstoolbox/ets/cpp-extensions/Eigen/src/misc/lapacke_mangling.h +17 -0
  460. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  461. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  462. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/BlockMethods.h +1442 -0
  463. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  464. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  465. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  466. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  467. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  468. roboticstoolbox/ets/cpp-extensions/Eigen/src/plugins/ReshapedMethods.h +149 -0
  469. roboticstoolbox/ets/cpp-extensions/README.md +73 -0
  470. roboticstoolbox/ets/cpp-extensions/fknm_nb.cpp +534 -0
  471. roboticstoolbox/ets/cpp-extensions/ik.cpp +301 -0
  472. roboticstoolbox/ets/cpp-extensions/ik.h +59 -0
  473. roboticstoolbox/ets/cpp-extensions/linalg.cpp +316 -0
  474. roboticstoolbox/ets/cpp-extensions/linalg.h +64 -0
  475. roboticstoolbox/ets/cpp-extensions/methods.cpp +372 -0
  476. roboticstoolbox/ets/cpp-extensions/methods.h +32 -0
  477. roboticstoolbox/ets/cpp-extensions/structs.cpp +24 -0
  478. roboticstoolbox/ets/cpp-extensions/structs.h +62 -0
  479. roboticstoolbox/ets/fknm.py +366 -0
  480. roboticstoolbox/mobile/Animations.py +485 -0
  481. roboticstoolbox/mobile/Bug2.py +455 -0
  482. roboticstoolbox/mobile/CurvaturePolyPlanner.py +179 -0
  483. roboticstoolbox/mobile/DistanceTransformPlanner.py +395 -0
  484. roboticstoolbox/mobile/DstarPlanner.py +591 -0
  485. roboticstoolbox/mobile/DubinsPlanner.py +474 -0
  486. roboticstoolbox/mobile/EKF.py +1617 -0
  487. roboticstoolbox/mobile/LatticePlanner.py +419 -0
  488. roboticstoolbox/mobile/OccGrid.py +613 -0
  489. roboticstoolbox/mobile/PRMPlanner.py +348 -0
  490. roboticstoolbox/mobile/ParticleFilter.py +706 -0
  491. roboticstoolbox/mobile/PlannerBase.py +1009 -0
  492. roboticstoolbox/mobile/PoseGraph.py +544 -0
  493. roboticstoolbox/mobile/QuinticPolyPlanner.py +349 -0
  494. roboticstoolbox/mobile/RRTPlanner.py +359 -0
  495. roboticstoolbox/mobile/ReedsSheppPlanner.py +545 -0
  496. roboticstoolbox/mobile/Vehicle.py +1909 -0
  497. roboticstoolbox/mobile/__init__.py +194 -0
  498. roboticstoolbox/mobile/drivers.py +397 -0
  499. roboticstoolbox/mobile/landmarkmap.py +181 -0
  500. roboticstoolbox/mobile/sensors.py +789 -0
  501. roboticstoolbox/models/DH/AL5D.py +121 -0
  502. roboticstoolbox/models/DH/Ball.py +87 -0
  503. roboticstoolbox/models/DH/Baxter.py +91 -0
  504. roboticstoolbox/models/DH/Cobra600.py +63 -0
  505. roboticstoolbox/models/DH/Coil.py +80 -0
  506. roboticstoolbox/models/DH/Hyper.py +81 -0
  507. roboticstoolbox/models/DH/Hyper3d.py +83 -0
  508. roboticstoolbox/models/DH/IRB140.py +159 -0
  509. roboticstoolbox/models/DH/Jaco.py +102 -0
  510. roboticstoolbox/models/DH/KR5.py +112 -0
  511. roboticstoolbox/models/DH/LWR4.py +80 -0
  512. roboticstoolbox/models/DH/Mico.py +102 -0
  513. roboticstoolbox/models/DH/Orion5.py +91 -0
  514. roboticstoolbox/models/DH/P8.py +80 -0
  515. roboticstoolbox/models/DH/Panda.py +213 -0
  516. roboticstoolbox/models/DH/Planar2.py +69 -0
  517. roboticstoolbox/models/DH/Planar3.py +51 -0
  518. roboticstoolbox/models/DH/Puma560.py +326 -0
  519. roboticstoolbox/models/DH/README.md +216 -0
  520. roboticstoolbox/models/DH/Sawyer.py +85 -0
  521. roboticstoolbox/models/DH/Stanford.py +147 -0
  522. roboticstoolbox/models/DH/TwoLink.py +153 -0
  523. roboticstoolbox/models/DH/UR10.py +124 -0
  524. roboticstoolbox/models/DH/UR3.py +98 -0
  525. roboticstoolbox/models/DH/UR5.py +98 -0
  526. roboticstoolbox/models/DH/Uprighttl.py +24 -0
  527. roboticstoolbox/models/DH/__init__.py +52 -0
  528. roboticstoolbox/models/ETS/Frankie.py +90 -0
  529. roboticstoolbox/models/ETS/GenericSeven.py +54 -0
  530. roboticstoolbox/models/ETS/Omni.py +74 -0
  531. roboticstoolbox/models/ETS/Panda.py +69 -0
  532. roboticstoolbox/models/ETS/Planar2.py +49 -0
  533. roboticstoolbox/models/ETS/Planar_Y.py +65 -0
  534. roboticstoolbox/models/ETS/Puma560.py +70 -0
  535. roboticstoolbox/models/ETS/XYPanda.py +84 -0
  536. roboticstoolbox/models/ETS/__init__.py +20 -0
  537. roboticstoolbox/models/README.md +9 -0
  538. roboticstoolbox/models/URDF/AL5D.py +45 -0
  539. roboticstoolbox/models/URDF/Fetch.py +96 -0
  540. roboticstoolbox/models/URDF/Frankie.py +67 -0
  541. roboticstoolbox/models/URDF/FrankieOmni.py +94 -0
  542. roboticstoolbox/models/URDF/Jaco.py +49 -0
  543. roboticstoolbox/models/URDF/KinovaGen3.py +63 -0
  544. roboticstoolbox/models/URDF/LBR.py +57 -0
  545. roboticstoolbox/models/URDF/PR2.py +66 -0
  546. roboticstoolbox/models/URDF/Panda.py +60 -0
  547. roboticstoolbox/models/URDF/Puma560.py +90 -0
  548. roboticstoolbox/models/URDF/UR10.py +43 -0
  549. roboticstoolbox/models/URDF/UR3.py +43 -0
  550. roboticstoolbox/models/URDF/UR5.py +64 -0
  551. roboticstoolbox/models/URDF/URDFRobot.py +402 -0
  552. roboticstoolbox/models/URDF/Valkyrie.py +110 -0
  553. roboticstoolbox/models/URDF/YuMi.py +107 -0
  554. roboticstoolbox/models/URDF/__init__.py +51 -0
  555. roboticstoolbox/models/URDF/px100.py +48 -0
  556. roboticstoolbox/models/URDF/px150.py +48 -0
  557. roboticstoolbox/models/URDF/rx150.py +48 -0
  558. roboticstoolbox/models/URDF/rx200.py +48 -0
  559. roboticstoolbox/models/URDF/vx300.py +48 -0
  560. roboticstoolbox/models/URDF/vx300s.py +48 -0
  561. roboticstoolbox/models/URDF/wx200.py +48 -0
  562. roboticstoolbox/models/URDF/wx250.py +48 -0
  563. roboticstoolbox/models/URDF/wx250s.py +48 -0
  564. roboticstoolbox/models/__init__.py +7 -0
  565. roboticstoolbox/models/catalog.py +226 -0
  566. roboticstoolbox/robot/BaseRobot.py +2589 -0
  567. roboticstoolbox/robot/DHFactor.py +522 -0
  568. roboticstoolbox/robot/DHLink.py +949 -0
  569. roboticstoolbox/robot/DHRobot.py +2591 -0
  570. roboticstoolbox/robot/Dynamics.py +1537 -0
  571. roboticstoolbox/robot/ELink.py +23 -0
  572. roboticstoolbox/robot/ERobot.py +25 -0
  573. roboticstoolbox/robot/Gripper.py +242 -0
  574. roboticstoolbox/robot/IK.py +1378 -0
  575. roboticstoolbox/robot/Link.py +1557 -0
  576. roboticstoolbox/robot/PoERobot.py +352 -0
  577. roboticstoolbox/robot/Robot.py +2157 -0
  578. roboticstoolbox/robot/RobotKinematics.py +1505 -0
  579. roboticstoolbox/robot/RobotPlottingMPL.py +355 -0
  580. roboticstoolbox/robot/RobotProto.py +156 -0
  581. roboticstoolbox/robot/__init__.py +57 -0
  582. roboticstoolbox/robot/cpp-extensions/README.md +29 -0
  583. roboticstoolbox/robot/cpp-extensions/frne.h +96 -0
  584. roboticstoolbox/robot/cpp-extensions/frne_nb.cpp +237 -0
  585. roboticstoolbox/robot/cpp-extensions/ne.c +495 -0
  586. roboticstoolbox/robot/cpp-extensions/vmath.c +163 -0
  587. roboticstoolbox/robot/cpp-extensions/vmath.h +32 -0
  588. roboticstoolbox/robot/frne.py +51 -0
  589. roboticstoolbox/tools/DHFactor.py +375 -0
  590. roboticstoolbox/tools/Ticker.py +53 -0
  591. roboticstoolbox/tools/__init__.py +54 -0
  592. roboticstoolbox/tools/data.py +187 -0
  593. roboticstoolbox/tools/jsingu.py +51 -0
  594. roboticstoolbox/tools/null.py +48 -0
  595. roboticstoolbox/tools/numerical.py +96 -0
  596. roboticstoolbox/tools/p_servo.py +108 -0
  597. roboticstoolbox/tools/params.py +11 -0
  598. roboticstoolbox/tools/plot.py +109 -0
  599. roboticstoolbox/tools/trajectory.py +1152 -0
  600. roboticstoolbox/tools/types.py +13 -0
  601. roboticstoolbox/tools/urdf/__init__.py +45 -0
  602. roboticstoolbox/tools/urdf/tests/data/ur5.urdf +341 -0
  603. roboticstoolbox/tools/urdf/tests/test_urdf.py +116 -0
  604. roboticstoolbox/tools/urdf/urdf.py +1930 -0
  605. roboticstoolbox/tools/urdf/utils.py +50 -0
  606. roboticstoolbox_python-1.4.0.dist-info/METADATA +664 -0
  607. roboticstoolbox_python-1.4.0.dist-info/RECORD +610 -0
  608. roboticstoolbox_python-1.4.0.dist-info/WHEEL +5 -0
  609. roboticstoolbox_python-1.4.0.dist-info/entry_points.txt +6 -0
  610. roboticstoolbox_python-1.4.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1537 @@
1
+ """
2
+ Rigid-body dynamics functionality of the Toolbox.
3
+
4
+ ``DynamicsMixin`` holds *derived* dynamics quantities -- ``accel``,
5
+ ``gravload``, ``coriolis``, ``inertia``, ``itorque``, ``pay``, etc. --
6
+ implemented generically, in terms of a small set of primitives (``rne``,
7
+ ``jacob0``, ...) declared abstractly by ``RobotProto``. This mixin never
8
+ touches representation-specific internals (DH parameters, ETS chains, the
9
+ compiled extension) directly.
10
+
11
+ ``rne()`` itself is deliberately *not* defined here -- it's a primitive,
12
+ implemented differently per concrete class: ``Robot``'s generic Featherstone
13
+ spatial-vector recursion (ETS-based, used by ``ERobot``/URDF robots, which
14
+ have no DH/MDH concept at all) vs. ``DHRobot``'s two DH-specific
15
+ implementations (``rne_python()``, hand-derived; ``rne()``, the compiled
16
+ ``ne.c`` extension). Keeping those out of this file preserves the
17
+ representation-agnostic boundary above.
18
+
19
+ ``Robot.rne()`` cannot represent ETS chains with joint-first-in-segment
20
+ structure (which any standard-DH derived chain has) -- ``ne.c``/``rne_python()``
21
+ don't share this limitation (``ne.c`` handles both DH conventions;
22
+ ``rne_python()`` is explicitly documented as standard-DH-only). Rather than
23
+ silently miscomputing this case, ``Robot.rne()`` now guards and rejects it
24
+ (see rne.md for the full investigation). This matters more than a typical
25
+ "one convention only" limitation because ``Robot.rne()`` is the *only* dynamics
26
+ implementation available to ``ERobot``/URDF/general robots -- there's no
27
+ alternative to fall back on the way ``DHRobot`` has two.
28
+ """
29
+
30
+ from collections import namedtuple
31
+ from typing import Any, Callable
32
+ import numpy as np
33
+ from spatialmath.base import getvector, verifymatrix, isscalar, getmatrix, t2r, rot2jac
34
+ from scipy import integrate, interpolate
35
+ from spatialmath.base import symbolic as sym
36
+ from roboticstoolbox.tools.params import rtb_get_param
37
+ from roboticstoolbox.robot.RobotProto import RobotProto
38
+
39
+ from roboticstoolbox.tools.types import ArrayLike, NDArray
40
+ from typing_extensions import Self
41
+ import roboticstoolbox as rtb
42
+
43
+ from ansitable import ANSITable, Column
44
+ import warnings
45
+
46
+
47
+ class DynamicsMixin:
48
+ # --------------------------------------------------------------------- #
49
+ def dynamics(self: RobotProto):
50
+ """
51
+ Pretty print the dynamic parameters (Robot superclass)
52
+
53
+ The dynamic parameters (inertial and friction) are printed in a table,
54
+ with one row per link.
55
+
56
+ Examples
57
+ --------
58
+
59
+ .. runblock:: pycon
60
+
61
+ >>> import roboticstoolbox as rtb
62
+ >>> robot = rtb.models.DH.Puma560()
63
+ >>> robot.dynamics()
64
+
65
+ """
66
+ unicode = rtb_get_param("unicode")
67
+ table = ANSITable(
68
+ Column("j", colalign=">", headalign="^"),
69
+ Column("m", colalign="<", headalign="^"),
70
+ Column("r", colalign="<", headalign="^"),
71
+ Column("I", colalign="<", headalign="^"),
72
+ Column("Jm", colalign="<", headalign="^"),
73
+ Column("B", colalign="<", headalign="^"),
74
+ Column("Tc", colalign="<", headalign="^"),
75
+ Column("G", colalign="<", headalign="^"),
76
+ border="thin" if unicode else "ascii",
77
+ )
78
+
79
+ for j, link in enumerate(self.links):
80
+ table.row(link.name, *link._dyn2list())
81
+ table.print()
82
+
83
+ def dynamics_list(self: RobotProto):
84
+ """
85
+ Print dynamic parameters (Robot superclass)
86
+
87
+ Display the kinematic and dynamic parameters to the console in
88
+ reable format
89
+
90
+ """
91
+ for j, link in enumerate(self.links):
92
+ print("\nLink {:d}::".format(j), link)
93
+ print(link.dyn(indent=2))
94
+
95
+ # --------------------------------------------------------------------- #
96
+
97
+ def friction(self: RobotProto, qd: NDArray) -> NDArray:
98
+ r"""
99
+ Manipulator joint friction (Robot superclass)
100
+
101
+ :param qd: The joint velocities of the robot
102
+ :type qd: ndarray(n,)
103
+ :returns: The joint friction forces/torques for the robot
104
+ :rtype: ndarray(n,)
105
+
106
+ ``robot.friction(qd)`` is a vector of joint friction
107
+ forces/torques for the robot moving with joint velocities ``qd``.
108
+
109
+ The friction model includes:
110
+
111
+ - Viscous friction which is a linear function of velocity.
112
+ - Coulomb friction which is proportional to sign(qd).
113
+
114
+ .. math::
115
+
116
+ \tau_j = G^2 B \dot{q}_j + |G_j| \left\{ \begin{array}{ll}
117
+ \tau_{C,j}^+ & \mbox{if $\dot{q}_j > 0$} \\
118
+ \tau_{C,j}^- & \mbox{if $\dot{q}_j < 0$} \end{array} \right.
119
+
120
+ .. rubric:: Notes
121
+
122
+ - The friction value should be added to the motor output torque to
123
+ determine the nett torque. It has a negative value when qd > 0.
124
+ - The returned friction value is referred to the output of the
125
+ gearbox.
126
+ - The friction parameters in the Link object are referred to the
127
+ motor.
128
+ - Motor viscous friction is scaled up by :math:`G^2`.
129
+ - Motor Coulomb friction is scaled up by :math:`G`.
130
+ - The appropriate Coulomb friction value to use in the
131
+ non-symmetric case depends on the sign of the joint velocity,
132
+ not the motor velocity.
133
+ - Coulomb friction is zero for zero joint velocity, stiction is
134
+ not modeled.
135
+ - The absolute value of the gear ratio is used. Negative gear
136
+ ratios are tricky: the Puma560 robot has negative gear ratio for
137
+ joints 1 and 3.
138
+
139
+ See Also
140
+ --------
141
+ :func:`Robot.nofriction`
142
+ :func:`Link.friction`
143
+
144
+ """
145
+
146
+ qd = np.array(getvector(qd, self.n))
147
+ tau = np.zeros(self.n)
148
+
149
+ for i in range(self.n):
150
+ tau[i] = self.links[i].friction(qd[i])
151
+
152
+ return tau
153
+
154
+ # --------------------------------------------------------------------- #
155
+
156
+ def nofriction(self: RobotProto, coulomb: bool = True, viscous: bool = False):
157
+ """
158
+ Remove manipulator joint friction
159
+
160
+ :param coulomb: set the Coulomb friction to 0
161
+ :param viscous: set the viscous friction to 0
162
+ :returns: A copy of the robot with dynamic parameters perturbed
163
+
164
+ ``nofriction()`` copies the robot and returns
165
+ a robot with the same link parameters except the Coulomb and/or viscous
166
+ friction parameter are set to zero.
167
+
168
+ See Also
169
+ --------
170
+ :func:`Robot.friction`
171
+ :func:`Link.nofriction`
172
+
173
+ """
174
+
175
+ # shallow copy the robot object
176
+ if isinstance(self, rtb.DHRobot):
177
+ self.delete_rne() # remove the inherited C pointers
178
+
179
+ nf = self.copy()
180
+ nf.name = "NF/" + self.name
181
+
182
+ # add the modified links (copies)
183
+ nf._links = [link.nofriction(coulomb, viscous) for link in self.links]
184
+
185
+ return nf
186
+
187
+ def fdyn(
188
+ self: RobotProto,
189
+ T: float,
190
+ q0: ArrayLike,
191
+ Q: Callable[[Any, float, NDArray, NDArray], NDArray] | None = None,
192
+ Q_args: dict = {},
193
+ qd0: ArrayLike | None = None,
194
+ solver: str = "RK45",
195
+ solver_args: dict = {},
196
+ dt: float | None = None,
197
+ progress: bool = False,
198
+ ):
199
+ """
200
+ Integrate forward dynamics
201
+
202
+ :param T: integration time
203
+ :param q0: initial joint coordinates
204
+ :type q0: ndarray(n,)
205
+ :param Q: a function that computes generalized joint force as a function of
206
+ time and/or state
207
+ :param Q_args: positional arguments passed to ``torque``
208
+ :param qd0: initial joint velocities, assumed zero if not given
209
+ :type qd0: ndarray(n,)
210
+ :param solver: name of SciPy integrator to use, default ``'RK45'``
211
+ :param solver_args: optional arguments passed to the SciPy integrator
212
+ :param dt: if given, interpolate the results to this timestep
213
+ :param progress: show progress bar, default False
214
+ :returns: robot trajectory
215
+ :rtype: namedtuple with fields ``t``, ``q``, ``qd``
216
+
217
+ ``tg = R.fdyn(T, q)`` integrates the dynamics of the robot with zero
218
+ input torques over the time interval 0 to ``T`` and returns the
219
+ trajectory as a namedtuple with elements:
220
+
221
+ - ``t`` the time vector (M,)
222
+ - ``q`` the joint coordinates (M,n)
223
+ - ``qd`` the joint velocities (M,n)
224
+
225
+ ``tg = R.fdyn(T, q, torqfun)`` as above but the torque applied to the
226
+ joints is given by the provided function::
227
+
228
+ tau = function(robot, t, q, qd, **args)
229
+
230
+ where the inputs are:
231
+
232
+ - the robot object
233
+ - current time
234
+ - current joint coordinates (n,)
235
+ - current joint velocity (n,)
236
+ - args, optional keyword arguments can be specified, these are
237
+ passed in from the ``targs`` keyword argument.
238
+
239
+ The function must return a Numpy array (n,) of joint forces/torques.
240
+
241
+ Examples
242
+ --------
243
+
244
+ To apply zero joint torque to the robot without Coulomb
245
+ friction:
246
+
247
+ >>> def myfunc(robot, t, q, qd):
248
+ >>> return np.zeros((robot.n,))
249
+
250
+ >>> tg = robot.nofriction().fdyn(5, q0, myfunc)
251
+
252
+ >>> plt.figure()
253
+ >>> plt.plot(tg.t, tg.q)
254
+ >>> plt.show()
255
+
256
+ We could also use a lambda function::
257
+
258
+ >>> tg = robot.nofriction().fdyn(
259
+ >>> 5, q0, lambda r, t, q, qd: np.zeros((r.n,)))
260
+
261
+ The robot is controlled by a PD controller. We first define a
262
+ function to compute the control which has additional parameters for
263
+ the setpoint and control gains (qstar, P, D)::
264
+
265
+ >>> def myfunc(robot, t, q, qd, qstar, P, D):
266
+ >>> return (qstar - q) * P + qd * D # P, D are (6,)
267
+
268
+ >>> tg = robot.fdyn(10, q0, myfunc, torque_args=(qstar, P, D))
269
+
270
+ Many integrators have variable step length which is problematic if we
271
+ want to animate the result. If ``dt`` is specified then the solver
272
+ results are interpolated in time steps of ``dt``.
273
+
274
+ .. rubric:: Notes
275
+
276
+ - This function performs poorly with non-linear joint friction,
277
+ such as Coulomb friction. The R.nofriction() method can be used
278
+ to set this friction to zero.
279
+ - If the function is not specified then zero force/torque is
280
+ applied to the manipulator joints.
281
+ - Interpolation is performed using
282
+ `SciPy integrate.ode <https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html>`_
283
+ - The SciPy RK45 integrator is used by default
284
+ - Interpolation is performed using
285
+ `SciPy interp1d <https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html>`_
286
+
287
+ See Also
288
+ --------
289
+ :func:`DHRobot.accel`
290
+ :func:`DHRobot.nofriction`,
291
+ :func:`DHRobot.rne`.
292
+
293
+ """
294
+
295
+ n = self.n
296
+
297
+ if not isscalar(T):
298
+ raise ValueError("T must be a scalar")
299
+ q0 = getvector(q0, n)
300
+ if qd0 is None:
301
+ qd0 = np.zeros((n,))
302
+ else:
303
+ qd0 = getvector(qd0, n)
304
+ if Q is not None:
305
+ if not callable(Q):
306
+ raise ValueError("generalized joint torque function must be callable")
307
+
308
+ # concatenate q and qd into the initial state vector
309
+ x0 = np.r_[q0, qd0]
310
+
311
+ # get user specified integrator
312
+ scipy_integrator = integrate.__dict__[solver]
313
+
314
+ integrator = scipy_integrator(
315
+ lambda t, y: self._fdyn(t, y, Q, Q_args),
316
+ t0=0.0,
317
+ y0=x0,
318
+ t_bound=T,
319
+ **solver_args,
320
+ )
321
+
322
+ # initialize list of time and states
323
+ tlist = [0]
324
+ xlist = [np.r_[q0, qd0]]
325
+
326
+ if progress:
327
+ _printProgressBar(0, prefix="Progress:", suffix="complete", length=60)
328
+
329
+ while integrator.status == "running":
330
+ # step the integrator, calls _fdyn multiple times
331
+ integrator.step()
332
+
333
+ if integrator.status == "failed":
334
+ raise RuntimeError("integration completed with failed status ")
335
+
336
+ # stash the results
337
+ tlist.append(integrator.t)
338
+ xlist.append(integrator.y)
339
+
340
+ # update the progress bar
341
+ if progress:
342
+ _printProgressBar(
343
+ integrator.t / T, prefix="Progress:", suffix="complete", length=60
344
+ )
345
+
346
+ # cleanup the progress bar
347
+ if progress:
348
+ print("\r" + " " * 90 + "\r")
349
+
350
+ tarray = np.array(tlist)
351
+ xarray = np.array(xlist)
352
+
353
+ if dt is not None:
354
+ # interpolate data to equal time steps of dt
355
+ interp = interpolate.interp1d(tarray, xarray, axis=0)
356
+
357
+ tnew = np.arange(0, T, dt)
358
+ xnew = interp(tnew)
359
+ return namedtuple("fdyn", "t q qd")(tnew, xnew[:, :n], xnew[:, n:])
360
+ else:
361
+ return namedtuple("fdyn", "t q qd")(tarray, xarray[:, :n], xarray[:, n:])
362
+
363
+ def _fdyn(
364
+ self: RobotProto,
365
+ t: float,
366
+ x: NDArray,
367
+ Qfunc: Callable[[Any, float, NDArray, NDArray], NDArray],
368
+ Qargs: dict,
369
+ ):
370
+ """
371
+ Private function called by fdyn
372
+
373
+ Called by ``fdyn`` to evaluate the robot velocity and acceleration for
374
+ forward dynamics.
375
+
376
+ :param t: current time
377
+ :param x: current state [q, qd]
378
+ :type x: ndarray(2n,)
379
+ :param Qfunc: a function that computes torque as a function of time
380
+ and/or state
381
+ :param Qargs: arguments passed to ``Qfunc``
382
+ :type Qargs: dict
383
+ :returns: derivative of current state [qd, qdd]
384
+ :rtype: ndarray(2n,)
385
+
386
+ """
387
+ n = self.n
388
+
389
+ q = x[0:n]
390
+ qd = x[n:]
391
+
392
+ # evaluate the torque function if one is given
393
+ if Qfunc is None:
394
+ tau = np.zeros((n,))
395
+ else:
396
+ tau = Qfunc(self, t, q, qd, **Qargs)
397
+ if len(tau) != n or not all(np.isreal(tau)):
398
+ raise RuntimeError(
399
+ "torque function must return vector with N real elements"
400
+ )
401
+
402
+ qdd = self.accel(q, qd, tau)
403
+
404
+ return np.r_[qd, qdd]
405
+
406
+ def accel(self: RobotProto, q, qd, torque, gravity=None):
407
+ r"""
408
+ Compute acceleration due to applied torque
409
+
410
+ :param q: Joint coordinates
411
+ :type q: ndarray(n,) or ndarray(m,n)
412
+ :param qd: Joint velocity
413
+ :type qd: ndarray(n,) or ndarray(m,n)
414
+ :param torque: Joint torques of the robot
415
+ :type torque: ndarray(n,) or ndarray(m,n)
416
+ :param gravity: gravitational acceleration in the world frame,
417
+ downwards gravitational force is equivalent to robot base
418
+ acceleration upwards (positive); if not supplied, uses the
419
+ ``gravity`` attribute of self
420
+ :returns: Joint accelerations
421
+ :rtype: ndarray(n,)
422
+
423
+ ``qdd = accel(q, qd, torque)`` calculates a vector (n) of joint
424
+ accelerations that result from applying the actuator force/torque (n)
425
+ to the manipulator in state `q` (n) and `qd` (n), and ``n`` is
426
+ the number of robot joints.
427
+
428
+ .. math::
429
+
430
+ \ddot{q} = \mathbf{M}^{-1} \left(\tau - \mathbf{C}(q)\dot{q} - \mathbf{g}(q)\right)
431
+
432
+ **Trajectory operation**
433
+
434
+ If `q`, `qd`, torque are matrices (m,n) then ``qdd`` is a matrix (m,n)
435
+ where each row is the acceleration corresponding to the equivalent rows
436
+ of q, qd, torque.
437
+
438
+ Examples
439
+ --------
440
+
441
+ .. runblock:: pycon
442
+
443
+ >>> import roboticstoolbox as rtb
444
+ >>> puma = rtb.models.DH.Puma560()
445
+ >>> puma.accel(puma.qz, 0.5 * np.ones(6), np.zeros(6))
446
+
447
+ .. rubric:: Notes
448
+
449
+ - Useful for simulation of manipulator dynamics, in
450
+ conjunction with a numerical integration function.
451
+ - Uses the method 1 of Walker and Orin to compute the forward
452
+ dynamics.
453
+ - Featherstone's method is more efficient for robots with large
454
+ numbers of joints.
455
+ - Joint friction is considered.
456
+
457
+ .. rubric:: References
458
+
459
+ - Efficient dynamic computer simulation of robotic mechanisms,
460
+ M. W. Walker and D. E. Orin,
461
+ ASME Journal of Dynamic Systems, Measurement and Control, vol.
462
+ 104, no. 3, pp. 205-211, 1982.
463
+
464
+ """
465
+
466
+ q = getmatrix(q, (None, self.n))
467
+ qd = getmatrix(qd, (None, self.n))
468
+ torque = getmatrix(torque, (None, self.n))
469
+
470
+ qdd = np.zeros((q.shape[0], self.n))
471
+
472
+ for k, (qk, qdk, tauk) in enumerate(zip(q, qd, torque)):
473
+ # Compute current manipulator inertia torques resulting from unit
474
+ # acceleration of each joint with no gravity.
475
+ qI = (np.c_[qk] @ np.ones((1, self.n))).T
476
+ qdI = np.zeros((self.n, self.n))
477
+ qddI = np.eye(self.n)
478
+
479
+ M = self.rne(qI, qdI, qddI, gravity=[0, 0, 0])
480
+
481
+ # Compute gravity and coriolis torque torques resulting from zero
482
+ # acceleration at given velocity & with gravity acting.
483
+ tau = self.rne(qk, qdk, np.zeros((1, self.n)), gravity=gravity)
484
+
485
+ # solve is faster than inv() which is faster than pinv()
486
+ qdd[k, :] = np.linalg.solve(M, tauk - tau)
487
+
488
+ if q.shape[0] == 1:
489
+ return qdd[0, :]
490
+ else:
491
+ return qdd
492
+
493
+ def pay(
494
+ self: RobotProto,
495
+ W: ArrayLike,
496
+ q: NDArray | None = None,
497
+ J: NDArray | None = None,
498
+ frame: int = 1,
499
+ ):
500
+ """
501
+ Generalised joint force/torque due to a payload wrench
502
+
503
+ :param W: A wrench vector applied at the end effector,
504
+ W = [Fx Fy Fz Mx My Mz]
505
+ :type W: ndarray(6,)
506
+ :param q: Joint coordinates
507
+ :type q: ndarray(n,)
508
+ :param J: The manipulator Jacobian (Optional, if not supplied will
509
+ use the q value).
510
+ :type J: ndarray(6,n)
511
+ :param frame: The frame in which to torques are expressed in when J
512
+ is not supplied. 0 means base frame of the robot, 1 means end-
513
+ effector frame
514
+ :returns: Joint forces/torques due to W
515
+ :rtype: ndarray(n,)
516
+
517
+ tau = pay(W, J) Returns the generalised joint force/torques due to a
518
+ payload wrench W applied to the end-effector. Where the manipulator
519
+ Jacobian is J (6xn), and n is the number of robot joints.
520
+
521
+ tau = pay(W, q, frame) as above but the Jacobian is calculated at pose
522
+ q in the frame given by frame which is 0 for base frame, 1 for
523
+ end-effector frame.
524
+
525
+ Uses the formula tau = J'W, where W is a wrench vector applied at the
526
+ end effector, W = [Fx Fy Fz Mx My Mz]'.
527
+
528
+ Trajectory operation:
529
+ In the case q is nxm or J is 6xnxm then tau is nxm where each row
530
+ is the generalised force/torque at the pose given by corresponding
531
+ row of q.
532
+
533
+ .. rubric:: Notes
534
+
535
+ - Wrench vector and Jacobian must be from the same reference
536
+ frame.
537
+ - Tool transforms are taken into consideration when frame=1.
538
+ - Must have a constant wrench - no trajectory support for this
539
+ yet.
540
+
541
+ """
542
+
543
+ try:
544
+ W = np.array(getvector(W, 6))
545
+ trajn = 0
546
+ except ValueError:
547
+ if isinstance(W, NDArray):
548
+ trajn = W.shape[0]
549
+ verifymatrix(W, (trajn, 6))
550
+ else:
551
+ raise ValueError("W is invalid")
552
+
553
+ if trajn:
554
+ # A trajectory
555
+ if J is not None:
556
+ # Jacobian supplied
557
+ verifymatrix(J, (trajn, 6, self.n))
558
+ elif q is not None:
559
+ # Use q instead
560
+ verifymatrix(q, (trajn, self.n))
561
+ J = np.zeros((trajn, 6, self.n))
562
+ for i in range(trajn):
563
+ if frame:
564
+ J[i, :, :] = self.jacobe(q[i, :])
565
+ else:
566
+ J[i, :, :] = self.jacob0(q[i, :])
567
+ else:
568
+ raise ValueError("q of J is needed for trajectory")
569
+ else:
570
+ # Single configuration
571
+ if J is not None:
572
+ # Jacobian supplied
573
+ verifymatrix(J, (6, self.n))
574
+ else:
575
+ # Use q instead
576
+ if q is None:
577
+ q = np.copy(self.q)
578
+ else:
579
+ q = getvector(q, self.n)
580
+
581
+ if frame:
582
+ J = self.jacobe(q)
583
+ else:
584
+ J = self.jacob0(q)
585
+
586
+ if trajn == 0:
587
+ tau = -J.T @ W
588
+ else:
589
+ tau = np.zeros((trajn, self.n))
590
+
591
+ for i in range(trajn):
592
+ tau[i, :] = -J[i, :, :].T @ W[i, :]
593
+
594
+ return tau
595
+
596
+ def payload(self: RobotProto, m: float, p=np.zeros(3)):
597
+ """
598
+ Add a payload to the end-effector
599
+
600
+ :param m: mass (kg)
601
+ :param p: position in end-effector frame
602
+ :type p: ndarray(3,)
603
+
604
+ payload(m, p) adds payload mass adds a payload with point mass m at
605
+ position p in the end-effector coordinate frame.
606
+
607
+ payload(m) adds payload mass adds a payload with point mass m at
608
+ in the end-effector coordinate frame.
609
+
610
+ payload(0) removes added payload.
611
+
612
+ """
613
+
614
+ p = getvector(p, 3, out="col")
615
+ lastlink = self.links[self.n - 1]
616
+
617
+ lastlink.m = m
618
+ lastlink.r = p
619
+
620
+ def jointdynamics(self: RobotProto, q, qd=None):
621
+ """
622
+ Transfer function of joint actuator
623
+
624
+ :param q: Joint coordinates
625
+ :type q: ndarray(n,)
626
+ :param qd: Joint velocity
627
+ :type qd: ndarray(n,)
628
+ :returns: transfer function denominators
629
+ :rtype: list of 2-tuples
630
+
631
+ ``tf = jointdynamics(qd, q)`` calculates a vector of n
632
+ continuous-time transfer functions that represent the transfer
633
+ function 1/(Js+B) for each joint based on the dynamic parameters
634
+ of the robot and the configuration q (n). n is the number of robot
635
+ joints. The result is a list of tuples (J, B) for each joint.
636
+
637
+ ``tf = jointdynamics(q, qd)`` as above but include the linearized
638
+ effects of Coulomb friction when operating at joint velocity QD
639
+ (1xN).
640
+
641
+ """
642
+
643
+ tf = []
644
+ for j, link in enumerate(self.links):
645
+ # compute inertia for this joint
646
+ zero = np.zeros((self.n))
647
+ qdd = np.zeros((self.n))
648
+ qdd[j] = 1
649
+ M = self.rne(q, zero, qdd, gravity=[0, 0, 0])
650
+ J = link.Jm + M[j] / abs(link.G) ** 2
651
+
652
+ # compute friction
653
+ B = link.B
654
+ if qd is not None:
655
+ # add linearized Coulomb friction at the operating point
656
+ if qd > 0:
657
+ B += link.Tc[0] / qd[j]
658
+ elif qd < 0:
659
+ B += link.Tc[1] / qd[j]
660
+ tf.append(((1,), (J, B)))
661
+
662
+ return tf
663
+
664
+ def cinertia(self: RobotProto, q):
665
+ """
666
+ Deprecated, use ``inertia_x``
667
+
668
+ """
669
+ warnings.warn("cinertia is deprecated, use inertia_x", DeprecationWarning)
670
+
671
+ def inertia(self: RobotProto, q: NDArray) -> NDArray:
672
+ """
673
+ Manipulator inertia matrix
674
+
675
+ :param q: Joint coordinates
676
+ :type q: ndarray(n,) or ndarray(m,n)
677
+ :returns: The inertia matrix
678
+ :rtype: ndarray(n,n)
679
+
680
+ ``inertia(q)`` is the symmetric joint inertia matrix (n,n) which
681
+ relates joint torque to joint acceleration for the robot at joint
682
+ configuration q.
683
+
684
+ **Trajectory operation**
685
+
686
+ If ``q`` is a matrix (m,n), each row is interpretted as a joint state
687
+ vector, and the result is a 3d-matrix (nxnxk) where each plane
688
+ corresponds to the inertia for the corresponding row of q.
689
+
690
+ Examples
691
+ --------
692
+
693
+ .. runblock:: pycon
694
+
695
+ >>> import roboticstoolbox as rtb
696
+ >>> puma = rtb.models.DH.Puma560()
697
+ >>> puma.inertia(puma.qz)
698
+
699
+ .. rubric:: Notes
700
+
701
+ - The diagonal elements ``M[j,j]`` are the inertia seen by joint
702
+ actuator ``j``.
703
+ - The off-diagonal elements ``M[j,k]`` are coupling inertias that
704
+ relate acceleration on joint ``j`` to force/torque on
705
+ joint ``k``.
706
+ - The diagonal terms include the motor inertia reflected through
707
+ the gear ratio.
708
+
709
+ See Also
710
+ --------
711
+ :func:`cinertia`
712
+
713
+ """
714
+ q = getmatrix(q, (None, self.n))
715
+
716
+ In = np.zeros((q.shape[0], self.n, self.n))
717
+
718
+ for k, qk in enumerate(q):
719
+ In[k, :, :] = self.rne(
720
+ (np.c_[qk] @ np.ones((1, self.n))).T,
721
+ np.zeros((self.n, self.n)),
722
+ np.eye(self.n),
723
+ gravity=[0, 0, 0],
724
+ )
725
+
726
+ if q.shape[0] == 1:
727
+ return In[0, :, :]
728
+ else:
729
+ return In
730
+
731
+ def coriolis(self: RobotProto, q, qd):
732
+ r"""
733
+ Coriolis and centripetal term
734
+
735
+ :param q: Joint coordinates
736
+ :type q: ndarray(n,) or ndarray(m,n)
737
+ :param qd: Joint velocity
738
+ :type qd: ndarray(n,) or ndarray(m,n)
739
+ :returns: Coriolis/centripetal velocity matrix
740
+ :rtype: ndarray(n,n)
741
+
742
+ ``coriolis(q, qd)`` calculates the Coriolis/centripetal matrix (n,n)
743
+ for the robot in configuration ``q`` and velocity ``qd``, where ``n``
744
+ is the number of joints.
745
+
746
+ The product :math:`\mathbf{C} \dot{q}` is the vector of joint
747
+ force/torque due to velocity coupling. The diagonal elements are due to
748
+ centripetal effects and the off-diagonal elements are due to Coriolis
749
+ effects. This matrix is also known as the velocity coupling matrix,
750
+ since it describes the disturbance forces on any joint due to
751
+ velocity of all other joints.
752
+
753
+ **Trajectory operation**
754
+
755
+ If ``q`` and `qd` are matrices (m,n), each row is interpretted as a
756
+ joint configuration, and the result (n,n,m) is a 3d-matrix where
757
+ each plane corresponds to a row of ``q`` and ``qd``.
758
+
759
+ Examples
760
+ --------
761
+
762
+ .. runblock:: pycon
763
+
764
+ >>> import roboticstoolbox as rtb
765
+ >>> puma = rtb.models.DH.Puma560()
766
+ >>> puma.coriolis(puma.qz, 0.5 * np.ones((6,)))
767
+
768
+ .. rubric:: Notes
769
+
770
+ - Joint viscous friction is also a joint force proportional to
771
+ velocity but it is eliminated in the computation of this value.
772
+ - Computationally slow, involves :math:`n^2/2` invocations of RNE.
773
+
774
+ """
775
+
776
+ q = getmatrix(q, (None, self.n))
777
+ qd = getmatrix(qd, (None, self.n))
778
+ if q.shape[0] != qd.shape[0]:
779
+ raise ValueError("q and qd must have the same number of rows")
780
+
781
+ # ensure that friction doesn't enter the mix, it's also a velocity
782
+ # dependent force/torque
783
+ r1 = self.nofriction(True, True)
784
+
785
+ C = np.zeros((q.shape[0], self.n, self.n))
786
+ Csq = np.zeros((q.shape[0], self.n, self.n))
787
+
788
+ # Find the torques that depend on a single finite joint speed,
789
+ # these are due to the squared (centripetal) terms
790
+ # set QD = [1 0 0 ...] then resulting torque is due to qd_1^2
791
+ for k, qk in enumerate(q):
792
+ for i in range(self.n):
793
+ QD = np.zeros(self.n)
794
+ QD[i] = 1
795
+ tau = r1.rne(qk, QD, np.zeros(self.n), gravity=[0, 0, 0])
796
+ Csq[k, :, i] = Csq[k, :, i] + tau
797
+
798
+ # Find the torques that depend on a pair of finite joint speeds,
799
+ # these are due to the product (Coriolis) terms
800
+ # set QD = [1 1 0 ...] then resulting torque is due to
801
+ # qd_1 qd_2 + qd_1^2 + qd_2^2
802
+ for k, (qk, qdk) in enumerate(zip(q, qd)):
803
+ for i in range(self.n):
804
+ for j in range(i + 1, self.n):
805
+ # Find a product term qd_i * qd_j
806
+ QD = np.zeros(self.n)
807
+ QD[i] = 1
808
+ QD[j] = 1
809
+ tau = r1.rne(qk, QD, np.zeros(self.n), gravity=[0, 0, 0])
810
+
811
+ C[k, :, j] = (
812
+ C[k, :, j] + (tau - Csq[k, :, j] - Csq[k, :, i]) * qdk[i] / 2
813
+ )
814
+
815
+ C[k, :, i] = (
816
+ C[k, :, i] + (tau - Csq[k, :, j] - Csq[k, :, i]) * qdk[j] / 2
817
+ )
818
+
819
+ C[k, :, :] = C[k, :, :] + Csq[k, :, :] @ np.diag(qdk)
820
+
821
+ if q.shape[0] == 1:
822
+ return C[0, :, :]
823
+ else:
824
+ return C
825
+
826
+ def gravload(
827
+ self: RobotProto,
828
+ q: ArrayLike | None = None,
829
+ gravity: ArrayLike | None = None,
830
+ ):
831
+ """
832
+ Compute gravity load
833
+
834
+ :param q: Joint coordinates
835
+ :type q: ndarray(n,) or ndarray(m,n)
836
+ :param gravity: gravitational acceleration in the world frame,
837
+ downwards gravitational force is equivalent to robot base
838
+ acceleration upwards (positive); if not supplied, uses the
839
+ stored gravity values
840
+ :type gravity: ndarray(3,)
841
+ :returns: The generalised joint force/torques due to gravity
842
+ :rtype: ndarray(n,)
843
+
844
+ ``robot.gravload(q)`` calculates the joint gravity loading (n) for
845
+ the robot in the joint configuration ``q`` and using the default
846
+ gravitational acceleration specified in the DHRobot object.
847
+
848
+ ``robot.gravload(q, gravity=g)`` as above except the gravitational
849
+ acceleration is explicitly specified as ``g``.
850
+
851
+ **Trajectory operation**
852
+
853
+ If q is a matrix (nxm) each column is interpreted as a joint
854
+ configuration vector, and the result is a matrix (nxm) each column
855
+ being the corresponding joint torques.
856
+
857
+ Examples
858
+ --------
859
+
860
+ .. runblock:: pycon
861
+
862
+ >>> import roboticstoolbox as rtb
863
+ >>> puma = rtb.models.DH.Puma560()
864
+ >>> puma.gravload(puma.qz)
865
+
866
+ """
867
+
868
+ q = getmatrix(q, (None, self.n))
869
+
870
+ if gravity is None:
871
+ gravity = self.gravity
872
+ else:
873
+ gravity = getvector(gravity, 3)
874
+
875
+ taug = np.zeros((q.shape[0], self.n))
876
+ z = np.zeros(self.n)
877
+
878
+ for k, qk in enumerate(q):
879
+ taug[k, :] = self.rne(qk, z, z, gravity=gravity)
880
+
881
+ if q.shape[0] == 1:
882
+ return taug[0, :]
883
+ else:
884
+ return taug
885
+
886
+ def inertia_x(
887
+ self: RobotProto, q=None, pinv=False, representation="rpy/xyz", Ji=None
888
+ ):
889
+ r"""
890
+ Operational space inertia matrix
891
+
892
+ :param q: Joint coordinates
893
+ :type q: ndarray(n,) or ndarray(m,n)
894
+ :param pinv: use pseudo inverse rather than inverse (Default value = False)
895
+ :param representation: the type of analytical Jacobian to use, default is
896
+ ``'rpy/xyz'``
897
+ :param Ji: The inverse analytical Jacobian (base-frame)
898
+ :type Ji: ndarray(6,n)
899
+ :returns: The operational space inertia matrix
900
+ :rtype: ndarray(6,6)
901
+
902
+ ``robot.inertia_x(q)`` is the operational space (Cartesian) inertia
903
+ matrix which relates Cartesian force/torque to Cartesian
904
+ acceleration at the joint configuration q.
905
+
906
+ .. math::
907
+
908
+ \mathbf{M}_x = \mathbf{J}(q)^{-T} \mathbf{M}(q) \mathbf{J}(q)^{-1}
909
+
910
+ The transformation to operational space requires an analytical, rather
911
+ than geometric, Jacobian. ``analytical`` can be one of:
912
+
913
+ ============= ========================================
914
+ Value Rotational representation
915
+ ============= ========================================
916
+ ``'rpy/xyz'`` RPY angular rates in XYZ order (default)
917
+ ``'rpy/zyx'`` RPY angular rates in XYZ order
918
+ ``'eul'`` Euler angular rates in ZYZ order
919
+ ``'exp'`` exponential coordinate rates
920
+ ============= ========================================
921
+
922
+ **Trajectory operation**
923
+
924
+ If ``q`` is a matrix (m,n), each row is interpretted as a joint state
925
+ vector, and the result is a 3d-matrix (m,n,n) where each plane
926
+ corresponds to the Cartesian inertia for the corresponding
927
+ row of ``q``.
928
+
929
+ Examples
930
+ --------
931
+
932
+ .. runblock:: pycon
933
+
934
+ >>> import roboticstoolbox as rtb
935
+ >>> puma = rtb.models.DH.Puma560()
936
+ >>> puma.inertia_x(puma.qn)
937
+
938
+ .. rubric:: Notes
939
+
940
+ - If the robot is not 6 DOF the ``pinv`` option is set True.
941
+ - ``pinv()`` is around 5x slower than ``inv()``
942
+
943
+ .. warning:: Assumes that the operational space has 6 DOF.
944
+
945
+ See Also
946
+ --------
947
+ :func:`inertia`
948
+
949
+ """
950
+
951
+ q = getmatrix(q, (None, self.n))
952
+ if q.shape[1] != 6:
953
+ pinv = True
954
+
955
+ if q.shape[0] == 1:
956
+ # single q case
957
+ if Ji is None:
958
+ Ja = self.jacob0_analytical(q[0, :], representation)
959
+ if pinv:
960
+ Ji = np.linalg.pinv(Ja)
961
+ else:
962
+ Ji = np.linalg.inv(Ja)
963
+ M = self.inertia(q[0, :])
964
+ return Ji.T @ M @ Ji
965
+
966
+ else:
967
+ # trajectory case
968
+ Mt = np.zeros((q.shape[0], 6, 6))
969
+
970
+ for k, qk in enumerate(q):
971
+ Ja = self.jacob0_analytical(qk, representation)
972
+ if pinv:
973
+ Ji = np.linalg.pinv(Ja)
974
+ else:
975
+ Ji = np.linalg.inv(Ja)
976
+ M = self.inertia(qk)
977
+ Mt[k, :, :] = Ji.T @ M @ Ji
978
+
979
+ return Mt
980
+
981
+ def coriolis_x(
982
+ self: RobotProto,
983
+ q,
984
+ qd,
985
+ pinv=False,
986
+ representation="rpy/xyz",
987
+ J=None,
988
+ Ji=None,
989
+ Jd=None,
990
+ C=None,
991
+ Mx=None,
992
+ ):
993
+ r"""
994
+ Operational space Coriolis and centripetal term
995
+
996
+ :param q: Joint coordinates
997
+ :type q: ndarray(n,) or ndarray(m,n)
998
+ :param qd: Joint velocity
999
+ :type qd: ndarray(n,) or ndarray(m,n)
1000
+ :param pinv: use pseudo inverse rather than inverse (Default value = False)
1001
+ :param representation: the type of analytical Jacobian to use, default is
1002
+ ``'rpy/xyz'``
1003
+ :param J: pre-computed analytical Jacobian (optional)
1004
+ :type J: ndarray(6,n)
1005
+ :param Ji: pre-computed inverse analytical Jacobian (optional)
1006
+ :type Ji: ndarray(n,6)
1007
+ :param Jd: pre-computed time-derivative of analytical Jacobian (optional)
1008
+ :type Jd: ndarray(6,n)
1009
+ :param C: pre-computed joint-space Coriolis matrix (optional)
1010
+ :type C: ndarray(n,n)
1011
+ :param Mx: pre-computed operational-space inertia matrix (optional)
1012
+ :type Mx: ndarray(6,6)
1013
+ :returns: Operational space velocity matrix
1014
+ :rtype: ndarray(6,6)
1015
+
1016
+ ``coriolis_x(q, qd)`` is the Coriolis/centripetal matrix (m,m)
1017
+ in operational space for the robot in configuration ``q`` and velocity
1018
+ ``qd``, where ``n`` is the number of joints.
1019
+
1020
+ .. math::
1021
+
1022
+ \mathbf{C}_x = \mathbf{J}(q)^{-T} \left(
1023
+ \mathbf{C}(q) - \mathbf{M}_x(q) \mathbf{J})(q)
1024
+ \right) \mathbf{J}(q)^{-1}
1025
+
1026
+ The product :math:`\mathbf{C} \dot{x}` is the operational space wrench
1027
+ due to joint velocity coupling. This matrix is also known as the
1028
+ velocity coupling matrix, since it describes the disturbance forces on
1029
+ any joint due to velocity of all other joints.
1030
+
1031
+ The transformation to operational space requires an analytical, rather
1032
+ than geometric, Jacobian. ``analytical`` can be one of:
1033
+
1034
+ ============= ========================================
1035
+ Value Rotational representation
1036
+ ============= ========================================
1037
+ ``'rpy/xyz'`` RPY angular rates in XYZ order (default)
1038
+ ``'rpy/zyx'`` RPY angular rates in XYZ order
1039
+ ``'eul'`` Euler angular rates in ZYZ order
1040
+ ``'exp'`` exponential coordinate rates
1041
+ ============= ========================================
1042
+
1043
+ **Trajectory operation**
1044
+
1045
+ If ``q`` and `qd` are matrices (m,n), each row is interpretted as a
1046
+ joint configuration, and the result (n,n,m) is a 3d-matrix where
1047
+ each plane corresponds to a row of ``q`` and ``qd``.
1048
+
1049
+ Examples
1050
+ --------
1051
+
1052
+ .. runblock:: pycon
1053
+
1054
+ >>> import roboticstoolbox as rtb
1055
+ >>> puma = rtb.models.DH.Puma560()
1056
+ >>> puma.coriolis_x(puma.qn, 0.5 * np.ones((6,)))
1057
+
1058
+ .. rubric:: Notes
1059
+
1060
+ - Joint viscous friction is also a joint force proportional to
1061
+ velocity but it is eliminated in the computation of this value.
1062
+ - Computationally slow, involves :math:`n^2/2` invocations of RNE.
1063
+ - If the robot is not 6 DOF the ``pinv`` option is set True.
1064
+ - ``pinv()`` is around 5x slower than ``inv()``
1065
+
1066
+ .. warning:: Assumes that the operational space has 6 DOF.
1067
+
1068
+ See Also
1069
+ --------
1070
+ :func:`coriolis`
1071
+ :func:`inertia_x`
1072
+ :func:`hessian0`
1073
+
1074
+ """
1075
+
1076
+ q = getmatrix(q, (None, self.n))
1077
+ qd = getmatrix(qd, (None, self.n))
1078
+ n = q.shape[1]
1079
+ if n != 6:
1080
+ pinv = True
1081
+
1082
+ if q.shape[0] == 1:
1083
+ # single q case
1084
+ if Ji is None:
1085
+ Ja = self.jacob0_analytical(q[0, :], representation)
1086
+ if pinv:
1087
+ Ji = np.linalg.pinv(Ja)
1088
+ else:
1089
+ Ji = np.linalg.inv(Ja)
1090
+ if C is None:
1091
+ C = self.coriolis(q[0, :], qd[0, :])
1092
+ if Mx is None:
1093
+ Mx = self.inertia_x(q[0, :], Ji=Ji)
1094
+ if Jd is None:
1095
+ Jd = self.jacob0_dot(q[0, :], qd[0, :], J0=Ja)
1096
+ return Ji.T @ (C - Mx @ Jd) @ Ji
1097
+ else:
1098
+ # trajectory case
1099
+ Ct = np.zeros((q.shape[0], 6, 6))
1100
+
1101
+ for k, (qk, qdk) in enumerate(zip(q, qd)):
1102
+ if Ji is None:
1103
+ Ja = self.jacob0_analytical(q[0, :], representation)
1104
+ if pinv:
1105
+ Ji = np.linalg.pinv(Ja)
1106
+ else:
1107
+ Ji = np.linalg.inv(Ja)
1108
+
1109
+ C = self.coriolis(qk, qdk)
1110
+ Mx = self.inertia_x(qk, Ji=Ji)
1111
+ Jd = self.jacob0_dot(qk, qdk, J0=J)
1112
+
1113
+ Ct[k, :, :] = Ji.T @ (C - Mx @ Jd) @ Ji
1114
+
1115
+ return Ct
1116
+
1117
+ def gravload_x(
1118
+ self: RobotProto,
1119
+ q=None,
1120
+ gravity=None,
1121
+ pinv=False,
1122
+ representation="rpy/xyz",
1123
+ Ji=None,
1124
+ ):
1125
+ r"""
1126
+ Operational space gravity load
1127
+
1128
+ :param q: Joint coordinates
1129
+ :type q: ndarray(n,) or ndarray(m,n)
1130
+ :param gravity: gravitational acceleration in the world frame,
1131
+ downwards gravitational force is equivalent to robot base
1132
+ acceleration upwards (positive); if not supplied, uses the
1133
+ ``gravity`` attribute of self
1134
+ :type gravity: ndarray(3,)
1135
+ :param pinv: use pseudo inverse rather than inverse (Default value = False)
1136
+ :param representation: the type of analytical Jacobian to use, default is
1137
+ ``'rpy/xyz'``
1138
+ :param Ji: pre-computed inverse analytical Jacobian (optional)
1139
+ :type Ji: ndarray(n,6)
1140
+ :returns: The operational space gravity wrench
1141
+ :rtype: ndarray(6,)
1142
+
1143
+ ``robot.gravload_x(q)`` calculates the gravity wrench for
1144
+ the robot in the joint configuration ``q`` and using the default
1145
+ gravitational acceleration specified in the robot object.
1146
+
1147
+ ``robot.gravload_x(q, gravity=g)`` as above except the gravitational
1148
+ acceleration is explicitly specified as ``g``.
1149
+
1150
+ .. math::
1151
+
1152
+ \mathbf{G}_x = \mathbf{J}(q)^{-T} \mathbf{G}(q)
1153
+
1154
+ The transformation to operational space requires an analytical, rather
1155
+ than geometric, Jacobian. ``analytical`` can be one of:
1156
+
1157
+ ============= ========================================
1158
+ Value Rotational representation
1159
+ ============= ========================================
1160
+ ``'rpy/xyz'`` RPY angular rates in XYZ order (default)
1161
+ ``'rpy/zyx'`` RPY angular rates in XYZ order
1162
+ ``'eul'`` Euler angular rates in ZYZ order
1163
+ ``'exp'`` exponential coordinate rates
1164
+ ============= ========================================
1165
+
1166
+ **Trajectory operation**
1167
+
1168
+ If q is a matrix (nxm) each column is interpreted as a joint
1169
+ configuration vector, and the result is a matrix (nxm) each column
1170
+ being the corresponding joint torques.
1171
+
1172
+ Examples
1173
+ --------
1174
+
1175
+ .. runblock:: pycon
1176
+
1177
+ >>> import roboticstoolbox as rtb
1178
+ >>> puma = rtb.models.DH.Puma560()
1179
+ >>> puma.gravload_x(puma.qn)
1180
+
1181
+ .. rubric:: Notes
1182
+
1183
+ - If the robot is not 6 DOF the ``pinv`` option is set True.
1184
+ - ``pinv()`` is around 5x slower than ``inv()``
1185
+
1186
+ .. warning:: Assumes that the operational space has 6 DOF.
1187
+
1188
+ See Also
1189
+ --------
1190
+ :func:`gravload`
1191
+
1192
+ """
1193
+
1194
+ q = getmatrix(q, (None, self.n))
1195
+ if q.shape[1] != 6:
1196
+ pinv = True
1197
+
1198
+ # if gravity is None:
1199
+ # gravity = self.gravity
1200
+ # else:
1201
+ # gravity = getvector(gravity, 3)
1202
+
1203
+ if q.shape[0] == 1:
1204
+ # single q case
1205
+ if Ji is None:
1206
+ Ja = self.jacob0_analytical(q[0, :], representation=representation)
1207
+ if pinv:
1208
+ Ji = np.linalg.pinv(Ja)
1209
+ else:
1210
+ Ji = np.linalg.inv(Ja)
1211
+ G = self.gravload(q[0, :])
1212
+ return Ji.T @ G
1213
+
1214
+ else:
1215
+ # trajectory case
1216
+ taug = np.zeros((q.shape[0], self.n))
1217
+ # z = np.zeros(self.n)
1218
+
1219
+ for k, qk in enumerate(q):
1220
+ Ja = self.jacob0_analytical(qk, representation=representation)
1221
+ G = self.gravload(qk)
1222
+ if pinv:
1223
+ Ji = np.linalg.pinv(Ja)
1224
+ else:
1225
+ Ji = np.linalg.inv(Ja)
1226
+
1227
+ taug[k, :] = Ji.T @ G
1228
+
1229
+ return taug
1230
+
1231
+ def accel_x(
1232
+ self: RobotProto,
1233
+ q,
1234
+ xd,
1235
+ wrench,
1236
+ gravity=None,
1237
+ pinv=False,
1238
+ representation="rpy/xyz",
1239
+ ):
1240
+ r"""
1241
+ Operational space acceleration due to applied wrench
1242
+
1243
+ :param q: Joint coordinates
1244
+ :type q: ndarray(n,) or ndarray(m,n)
1245
+ :param xd: Operational space velocity of the end-effector
1246
+ :type xd: ndarray(6,)
1247
+ :param wrench: Wrench applied to the end-effector
1248
+ :type wrench: ndarray(6,)
1249
+ :param gravity: gravitational acceleration in the world frame,
1250
+ downwards gravitational force is equivalent to robot base
1251
+ acceleration upwards (positive); if not supplied, uses the
1252
+ ``gravity`` attribute of self
1253
+ :param pinv: use pseudo inverse rather than inverse
1254
+ :param representation: the type of analytical Jacobian to use, default is
1255
+ ``'rpy/xyz'``
1256
+ :returns: Operational space accelerations of the end-effector
1257
+ :rtype: ndarray(6,)
1258
+
1259
+ ``xdd = accel_x(q, qd, wrench)`` is the operational space acceleration
1260
+ due to ``wrench`` applied to the end-effector of a robot in joint
1261
+ configuration ``q`` and joint velocity ``qd``.
1262
+
1263
+ .. math::
1264
+
1265
+ \ddot{x} = \mathbf{J}(q) \mathbf{M}(q)^{-1} \left(
1266
+ \mathbf{J}(q)^T w - \mathbf{C}(q)\dot{q} - \mathbf{g}(q)
1267
+ \right)
1268
+
1269
+ **Trajectory operation**
1270
+
1271
+ If `q`, `qd`, torque are matrices (m,n) then ``qdd`` is a matrix (m,n)
1272
+ where each row is the acceleration corresponding to the equivalent rows
1273
+ of q, qd, wrench.
1274
+
1275
+ .. rubric:: Notes
1276
+
1277
+ - Useful for simulation of manipulator dynamics, in
1278
+ conjunction with a numerical integration function.
1279
+ - Uses the method 1 of Walker and Orin to compute the forward
1280
+ dynamics.
1281
+ - Featherstone's method is more efficient for robots with large
1282
+ numbers of joints.
1283
+ - Joint friction is considered.
1284
+
1285
+ See Also
1286
+ --------
1287
+ :func:`accel`
1288
+
1289
+ """
1290
+
1291
+ q = getmatrix(q, (None, self.n))
1292
+ xd = getmatrix(xd, (None, 6))
1293
+ w = getmatrix(wrench, (None, 6))
1294
+ if q.shape[1] != 6:
1295
+ pinv = True
1296
+
1297
+ xdd = np.zeros((q.shape[0], self.n))
1298
+
1299
+ for k, (qk, xdk, wk) in enumerate(zip(q, xd, w)):
1300
+ Ja = self.jacob0_analytical(qk, representation=representation)
1301
+ if pinv:
1302
+ Ji = np.linalg.pinv(Ja)
1303
+ else:
1304
+ Ji = np.linalg.inv(Ja)
1305
+
1306
+ # Compute current manipulator inertia tensor
1307
+ # shortcut from torques resulting from unit
1308
+ # acceleration of each joint with zero gravity and zero velocity
1309
+ qI = (np.c_[qk] @ np.ones((1, self.n))).T
1310
+ qdI = np.zeros((self.n, self.n))
1311
+ qddI = np.eye(self.n)
1312
+ M = self.rne(qI, qdI, qddI, gravity=[0, 0, 0])
1313
+
1314
+ # Compute gravity and coriolis torque torques resulting from zero
1315
+ # acceleration at given velocity & with gravity acting.
1316
+ tau_rne = self.rne(qk, Ji @ xdk, np.zeros((1, self.n)), gravity=gravity)
1317
+
1318
+ # solve is faster than inv() which is faster than pinv()
1319
+ # tau_rne = C(q,qd) + G(q)
1320
+ # qdd = M^-1 (tau - C(q,qd) - G(q))
1321
+ qdd = np.linalg.solve(M, Ja.T @ wk - tau_rne)
1322
+
1323
+ # xd = Ja qd
1324
+ # xdd = Jad qd + Ja qdd
1325
+ #
1326
+ # Ja = T J
1327
+ # Jad = Td J + T Jd
1328
+ # assume Td = 0, not sure how valid that is
1329
+
1330
+ # need Jacobian dot
1331
+ qdk = Ji @ xdk
1332
+ Jd = self.jacob0_dot(qk, qdk, J0=Ja)
1333
+
1334
+ xdd[k, :] = T @ (Jd @ qdk + J @ qdd)
1335
+
1336
+ if q.shape[0] == 1:
1337
+ return xdd[0, :]
1338
+ else:
1339
+ return xdd
1340
+
1341
+ def itorque(self: RobotProto, q, qdd):
1342
+ r"""
1343
+ Inertia torque
1344
+
1345
+ :param q: Joint coordinates
1346
+ :type q: ndarray(n,) or ndarray(m,n)
1347
+ :param qdd: Joint acceleration
1348
+ :type qdd: ndarray(n,) or ndarray(m,n)
1349
+ :returns: The inertia torque vector
1350
+ :rtype: ndarray(n,)
1351
+
1352
+ ``itorque(q, qdd)`` is the inertia force/torque vector (n) at
1353
+ the specified joint configuration q (n) and acceleration qdd (n), and
1354
+ ``n`` is the number of robot joints. It is :math:`\mathbf{I}(q) \ddot{q}`.
1355
+
1356
+ **Trajectory operation**
1357
+
1358
+ If ``q`` and ``qdd`` are matrices (m,n), each row is interpretted as a
1359
+ joint configuration, and the result is a matrix (m,n) where each row is
1360
+ the corresponding joint torques.
1361
+
1362
+ Examples
1363
+ --------
1364
+
1365
+ .. runblock:: pycon
1366
+
1367
+ >>> import roboticstoolbox as rtb
1368
+ >>> puma = rtb.models.DH.Puma560()
1369
+ >>> puma.itorque(puma.qz, 0.5 * np.ones((6,)))
1370
+
1371
+ .. rubric:: Notes
1372
+
1373
+ - If the robot model contains non-zero motor inertia then this
1374
+ will be included in the result.
1375
+
1376
+ See Also
1377
+ --------
1378
+ :func:`inertia`
1379
+
1380
+ """
1381
+
1382
+ q = getmatrix(q, (None, self.n))
1383
+ qdd = getmatrix(qdd, (None, self.n))
1384
+ if q.shape[0] != qdd.shape[0]:
1385
+ raise ValueError("q and qdd must have the same number of rows")
1386
+
1387
+ taui = np.zeros((q.shape[0], self.n))
1388
+
1389
+ for k, (qk, qddk) in enumerate(zip(q, qdd)):
1390
+ taui[k, :] = self.rne(qk, np.zeros(self.n), qddk, gravity=[0, 0, 0])
1391
+
1392
+ if q.shape[0] == 1:
1393
+ return taui[0, :]
1394
+ else:
1395
+ return taui
1396
+
1397
+ def paycap(
1398
+ self: RobotProto,
1399
+ w: NDArray,
1400
+ tauR: NDArray,
1401
+ frame: int = 1,
1402
+ q: ArrayLike | None = None,
1403
+ ):
1404
+ """
1405
+ Static payload capacity of a robot
1406
+
1407
+ :param w: The payload wrench
1408
+ :type w: ndarray(6,)
1409
+ :param tauR: Joint torque matrix minimum and maximums
1410
+ :type tauR: ndarray(n,2)
1411
+ :param frame: The frame in which to torques are expressed in when J
1412
+ is not supplied. 'base' means base frame of the robot, 'ee' means
1413
+ end-effector frame
1414
+ :param q: Joint coordinates
1415
+ :type q: ndarray(n,)
1416
+ :returns: The maximum permissible payload wrench
1417
+ :rtype: ndarray(6,)
1418
+
1419
+ ``wmax, joint = paycap(q, w, f, tauR)`` returns the maximum permissible
1420
+ payload wrench ``wmax`` (6) applied at the end-effector, and the index
1421
+ of the joint (zero indexed) which hits its force/torque limit at that
1422
+ wrench. ``q`` (n) is the manipulator pose, ``w`` the payload wrench
1423
+ (6), ``f`` the wrench reference frame and tauR (nx2) is a matrix of
1424
+ joint forces/torques (first col is maximum, second col minimum).
1425
+
1426
+ **Trajectory operation:**
1427
+
1428
+ In the case q is nxm then wmax is Mx6 and J is Mx1 where the rows are
1429
+ the results at the pose given by corresponding row of q.
1430
+
1431
+ .. rubric:: Notes
1432
+
1433
+ - Wrench vector and Jacobian must be from the same reference frame
1434
+ - Tool transforms are taken into consideration for frame=1.
1435
+
1436
+ """
1437
+
1438
+ # TODO rewrite
1439
+ trajn = 1
1440
+
1441
+ if q is None:
1442
+ q = self.q
1443
+ else:
1444
+ q = np.array(q)
1445
+
1446
+ try:
1447
+ q = np.array(getvector(q, self.n, "row"))
1448
+ w = np.array(getvector(w, 6, "row"))
1449
+ except ValueError:
1450
+ trajn = q.shape[1]
1451
+ verifymatrix(q, (trajn, self.n))
1452
+ verifymatrix(w, (trajn, 6))
1453
+
1454
+ verifymatrix(tauR, (self.n, 2))
1455
+
1456
+ wmax = np.zeros((trajn, 6))
1457
+ joint = np.zeros(trajn, dtype=int)
1458
+
1459
+ for i in range(trajn):
1460
+ tauB = self.gravload(q[i, :])
1461
+
1462
+ # tauP = self.rne(
1463
+ # np.zeros(self.n), np.zeros(self.n),
1464
+ # q, grav=[0, 0, 0], fext=w/np.linalg.norm(w))
1465
+
1466
+ tauP = self.pay(w[i, :] / np.linalg.norm(w[i, :]), q=q[i, :], frame=frame)
1467
+
1468
+ M = tauP > 0
1469
+ m = tauP <= 0
1470
+
1471
+ TAUm = np.ones(self.n)
1472
+ TAUM = np.ones(self.n)
1473
+
1474
+ for c in range(self.n):
1475
+ TAUM[c] = tauR[c, 0]
1476
+ TAUm[c] = tauR[c, 1]
1477
+
1478
+ WM = np.zeros(self.n)
1479
+ WM[M] = (TAUM[M] - tauB[M]) / tauP[M]
1480
+ WM[m] = (TAUm[m] - tauB[m]) / tauP[m]
1481
+
1482
+ WM[WM == -np.inf] = np.inf
1483
+
1484
+ wmax[i, :] = WM
1485
+ joint[i] = np.argmin(WM)
1486
+
1487
+ if trajn == 1:
1488
+ return wmax[0, :], joint[0]
1489
+ else:
1490
+ return wmax, joint
1491
+
1492
+ def perturb(self: RobotProto, p=0.1):
1493
+ """
1494
+ Perturb robot parameters
1495
+
1496
+ :param p: The percent (+/-) to be perturbed. Default 10%
1497
+ :returns: A copy of the robot with dynamic parameters perturbed
1498
+
1499
+ rp = perturb(p) is a new robot object in which the dynamic parameters
1500
+ (link mass and inertia) have been perturbed. The perturbation is
1501
+ multiplicative so that values are multiplied by random numbers in the
1502
+ interval (1-p) to (1+p). The name string of the perturbed robot is
1503
+ prefixed by 'P/'.
1504
+
1505
+ Useful for investigating the robustness of various model-based control
1506
+ schemes. For example to vary parameters in the range +/- 10 percent
1507
+ is: r2 = puma.perturb(0.1)
1508
+
1509
+ """
1510
+
1511
+ r2 = self.copy()
1512
+ r2.name = "P/" + self.name
1513
+
1514
+ for i in range(self.n):
1515
+ s = (2 * np.random.random() - 1) * p + 1
1516
+ r2.links[i].m = r2.links[i].m * s
1517
+
1518
+ s = (2 * np.random.random() - 1) * p + 1
1519
+ r2.links[i].I = r2.links[i].I * s
1520
+
1521
+ return r2
1522
+
1523
+
1524
+ def _printProgressBar(
1525
+ fraction, prefix="", suffix="", decimals=1, length=50, fill="█", printEnd="\r"
1526
+ ):
1527
+
1528
+ percent = ("{0:." + str(decimals) + "f}").format(fraction * 100)
1529
+ filledLength = int(length * fraction)
1530
+ bar = fill * filledLength + "-" * (length - filledLength)
1531
+ print(f"\r{prefix} |{bar}| {percent}% {suffix}", end=printEnd)
1532
+
1533
+
1534
+ if __name__ == "__main__": # pragma nocover
1535
+ import roboticstoolbox as rtb
1536
+
1537
+ puma = rtb.models.DH.Puma560()