roboticstoolbox-python 1.3.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. roboticstoolbox/__init__.py +104 -0
  2. roboticstoolbox/backends/Connector.py +107 -0
  3. roboticstoolbox/backends/Dynamixel/README.md +9 -0
  4. roboticstoolbox/backends/Dynamixel/dynamixel.json +581 -0
  5. roboticstoolbox/backends/Dynamixel/dynamixel_io.py +450 -0
  6. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/LICENSE +201 -0
  7. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/README.md +28 -0
  8. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/ReleaseNote.md +181 -0
  9. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/__init__.py +27 -0
  10. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_read.py +163 -0
  11. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_bulk_write.py +109 -0
  12. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_read.py +166 -0
  13. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/group_sync_write.py +99 -0
  14. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/packet_handler.py +33 -0
  15. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/port_handler.py +155 -0
  16. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol1_packet_handler.py +548 -0
  17. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/protocol2_packet_handler.py +1080 -0
  18. roboticstoolbox/backends/Dynamixel/dynamixel_sdk/robotis_def.py +75 -0
  19. roboticstoolbox/backends/Dynamixel/dyndata.py +121 -0
  20. roboticstoolbox/backends/PyPlot/EllipsePlot.py +253 -0
  21. roboticstoolbox/backends/PyPlot/PyPlot.py +769 -0
  22. roboticstoolbox/backends/PyPlot/PyPlot2.py +526 -0
  23. roboticstoolbox/backends/PyPlot/README.md +67 -0
  24. roboticstoolbox/backends/PyPlot/RobotPlot.py +247 -0
  25. roboticstoolbox/backends/PyPlot/RobotPlot2.py +123 -0
  26. roboticstoolbox/backends/PyPlot/__init__.py +4 -0
  27. roboticstoolbox/backends/ROS/ROS.py +129 -0
  28. roboticstoolbox/backends/ROS/__init__.py +3 -0
  29. roboticstoolbox/backends/__init__.py +39 -0
  30. roboticstoolbox/backends/swift/__init__.py +26 -0
  31. roboticstoolbox/bin/__init__.py +0 -0
  32. roboticstoolbox/bin/rtbtool.py +307 -0
  33. roboticstoolbox/blocks/Icons/250x250/armplot.png +0 -0
  34. roboticstoolbox/blocks/Icons/250x250/bicycle.png +0 -0
  35. roboticstoolbox/blocks/Icons/250x250/camera.png +0 -0
  36. roboticstoolbox/blocks/Icons/250x250/circlepath.png +0 -0
  37. roboticstoolbox/blocks/Icons/250x250/coriolis.png +0 -0
  38. roboticstoolbox/blocks/Icons/250x250/ctraj.png +0 -0
  39. roboticstoolbox/blocks/Icons/250x250/delta2tr.png +0 -0
  40. roboticstoolbox/blocks/Icons/250x250/diffsteer.png +0 -0
  41. roboticstoolbox/blocks/Icons/250x250/fdyn.png +0 -0
  42. roboticstoolbox/blocks/Icons/250x250/fdynx.png +0 -0
  43. roboticstoolbox/blocks/Icons/250x250/fkine.png +0 -0
  44. roboticstoolbox/blocks/Icons/250x250/gravload.png +0 -0
  45. roboticstoolbox/blocks/Icons/250x250/idyn.png +0 -0
  46. roboticstoolbox/blocks/Icons/250x250/idynx.png +0 -0
  47. roboticstoolbox/blocks/Icons/250x250/ikine.png +0 -0
  48. roboticstoolbox/blocks/Icons/250x250/inertia.png +0 -0
  49. roboticstoolbox/blocks/Icons/250x250/jacobian.png +0 -0
  50. roboticstoolbox/blocks/Icons/250x250/jtraj.png +0 -0
  51. roboticstoolbox/blocks/Icons/250x250/lspb.png +0 -0
  52. roboticstoolbox/blocks/Icons/250x250/multirotor.png +0 -0
  53. roboticstoolbox/blocks/Icons/250x250/multirotormixer.png +0 -0
  54. roboticstoolbox/blocks/Icons/250x250/multirotorplot.png +0 -0
  55. roboticstoolbox/blocks/Icons/250x250/point2tr.png +0 -0
  56. roboticstoolbox/blocks/Icons/250x250/tr2delta.png +0 -0
  57. roboticstoolbox/blocks/Icons/250x250/tr2t.png +0 -0
  58. roboticstoolbox/blocks/Icons/250x250/unicycle.png +0 -0
  59. roboticstoolbox/blocks/Icons/250x250/vehicleplot.png +0 -0
  60. roboticstoolbox/blocks/Icons/50x50/armplot.png +0 -0
  61. roboticstoolbox/blocks/Icons/50x50/bicycle.png +0 -0
  62. roboticstoolbox/blocks/Icons/50x50/camera.png +0 -0
  63. roboticstoolbox/blocks/Icons/50x50/circlepath.png +0 -0
  64. roboticstoolbox/blocks/Icons/50x50/coriolis.png +0 -0
  65. roboticstoolbox/blocks/Icons/50x50/delta2tr.png +0 -0
  66. roboticstoolbox/blocks/Icons/50x50/diffsteer.png +0 -0
  67. roboticstoolbox/blocks/Icons/50x50/fdyn.png +0 -0
  68. roboticstoolbox/blocks/Icons/50x50/fdynx.png +0 -0
  69. roboticstoolbox/blocks/Icons/50x50/fkine.png +0 -0
  70. roboticstoolbox/blocks/Icons/50x50/gravload.png +0 -0
  71. roboticstoolbox/blocks/Icons/50x50/idyn.png +0 -0
  72. roboticstoolbox/blocks/Icons/50x50/idynx.png +0 -0
  73. roboticstoolbox/blocks/Icons/50x50/ikine.png +0 -0
  74. roboticstoolbox/blocks/Icons/50x50/inertia.png +0 -0
  75. roboticstoolbox/blocks/Icons/50x50/jacobian.png +0 -0
  76. roboticstoolbox/blocks/Icons/50x50/jtraj.png +0 -0
  77. roboticstoolbox/blocks/Icons/50x50/lspb.png +0 -0
  78. roboticstoolbox/blocks/Icons/50x50/multirotor.png +0 -0
  79. roboticstoolbox/blocks/Icons/50x50/multirotormixer.png +0 -0
  80. roboticstoolbox/blocks/Icons/50x50/multirotorplot.png +0 -0
  81. roboticstoolbox/blocks/Icons/50x50/point2tr.png +0 -0
  82. roboticstoolbox/blocks/Icons/50x50/tr2delta.png +0 -0
  83. roboticstoolbox/blocks/Icons/50x50/tr2t.png +0 -0
  84. roboticstoolbox/blocks/Icons/50x50/unicycle.png +0 -0
  85. roboticstoolbox/blocks/Icons/50x50/vehicleplot.png +0 -0
  86. roboticstoolbox/blocks/Icons/armplot.png +0 -0
  87. roboticstoolbox/blocks/Icons/bicycle.png +0 -0
  88. roboticstoolbox/blocks/Icons/camera.png +0 -0
  89. roboticstoolbox/blocks/Icons/circlepath.png +0 -0
  90. roboticstoolbox/blocks/Icons/coriolis.png +0 -0
  91. roboticstoolbox/blocks/Icons/ctraj.png +0 -0
  92. roboticstoolbox/blocks/Icons/delta2tr.png +0 -0
  93. roboticstoolbox/blocks/Icons/diffsteer.png +0 -0
  94. roboticstoolbox/blocks/Icons/fdyn.png +0 -0
  95. roboticstoolbox/blocks/Icons/fdynx.png +0 -0
  96. roboticstoolbox/blocks/Icons/fkine.png +0 -0
  97. roboticstoolbox/blocks/Icons/gravload.png +0 -0
  98. roboticstoolbox/blocks/Icons/idyn.png +0 -0
  99. roboticstoolbox/blocks/Icons/idynx.png +0 -0
  100. roboticstoolbox/blocks/Icons/ikine.png +0 -0
  101. roboticstoolbox/blocks/Icons/inertia.png +0 -0
  102. roboticstoolbox/blocks/Icons/jacobian.png +0 -0
  103. roboticstoolbox/blocks/Icons/jtraj.png +0 -0
  104. roboticstoolbox/blocks/Icons/lspb.png +0 -0
  105. roboticstoolbox/blocks/Icons/multirotor.png +0 -0
  106. roboticstoolbox/blocks/Icons/multirotormixer.png +0 -0
  107. roboticstoolbox/blocks/Icons/multirotorplot.png +0 -0
  108. roboticstoolbox/blocks/Icons/point2tr.png +0 -0
  109. roboticstoolbox/blocks/Icons/tr2delta.png +0 -0
  110. roboticstoolbox/blocks/Icons/tr2t.png +0 -0
  111. roboticstoolbox/blocks/Icons/unicycle.png +0 -0
  112. roboticstoolbox/blocks/Icons/vehicleplot.png +0 -0
  113. roboticstoolbox/blocks/README.md +43 -0
  114. roboticstoolbox/blocks/__init__.py +6 -0
  115. roboticstoolbox/blocks/arm.py +1587 -0
  116. roboticstoolbox/blocks/mobile.py +500 -0
  117. roboticstoolbox/blocks/quad_model.py +132 -0
  118. roboticstoolbox/blocks/spatial.py +245 -0
  119. roboticstoolbox/blocks/uav.py +949 -0
  120. roboticstoolbox/core/Eigen/Cholesky +45 -0
  121. roboticstoolbox/core/Eigen/CholmodSupport +48 -0
  122. roboticstoolbox/core/Eigen/Core +384 -0
  123. roboticstoolbox/core/Eigen/Dense +7 -0
  124. roboticstoolbox/core/Eigen/Eigen +2 -0
  125. roboticstoolbox/core/Eigen/Eigenvalues +60 -0
  126. roboticstoolbox/core/Eigen/Geometry +59 -0
  127. roboticstoolbox/core/Eigen/Householder +29 -0
  128. roboticstoolbox/core/Eigen/IterativeLinearSolvers +48 -0
  129. roboticstoolbox/core/Eigen/Jacobi +32 -0
  130. roboticstoolbox/core/Eigen/KLUSupport +41 -0
  131. roboticstoolbox/core/Eigen/LU +47 -0
  132. roboticstoolbox/core/Eigen/MetisSupport +35 -0
  133. roboticstoolbox/core/Eigen/OrderingMethods +70 -0
  134. roboticstoolbox/core/Eigen/PaStiXSupport +49 -0
  135. roboticstoolbox/core/Eigen/PardisoSupport +35 -0
  136. roboticstoolbox/core/Eigen/QR +50 -0
  137. roboticstoolbox/core/Eigen/QtAlignedMalloc +39 -0
  138. roboticstoolbox/core/Eigen/SPQRSupport +34 -0
  139. roboticstoolbox/core/Eigen/SVD +50 -0
  140. roboticstoolbox/core/Eigen/Sparse +34 -0
  141. roboticstoolbox/core/Eigen/SparseCholesky +37 -0
  142. roboticstoolbox/core/Eigen/SparseCore +69 -0
  143. roboticstoolbox/core/Eigen/SparseLU +50 -0
  144. roboticstoolbox/core/Eigen/SparseQR +36 -0
  145. roboticstoolbox/core/Eigen/StdDeque +27 -0
  146. roboticstoolbox/core/Eigen/StdList +26 -0
  147. roboticstoolbox/core/Eigen/StdVector +27 -0
  148. roboticstoolbox/core/Eigen/SuperLUSupport +64 -0
  149. roboticstoolbox/core/Eigen/UmfPackSupport +40 -0
  150. roboticstoolbox/core/Eigen/src/Cholesky/LDLT.h +688 -0
  151. roboticstoolbox/core/Eigen/src/Cholesky/LLT.h +558 -0
  152. roboticstoolbox/core/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  153. roboticstoolbox/core/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  154. roboticstoolbox/core/Eigen/src/Core/ArithmeticSequence.h +413 -0
  155. roboticstoolbox/core/Eigen/src/Core/Array.h +417 -0
  156. roboticstoolbox/core/Eigen/src/Core/ArrayBase.h +226 -0
  157. roboticstoolbox/core/Eigen/src/Core/ArrayWrapper.h +209 -0
  158. roboticstoolbox/core/Eigen/src/Core/Assign.h +90 -0
  159. roboticstoolbox/core/Eigen/src/Core/AssignEvaluator.h +1010 -0
  160. roboticstoolbox/core/Eigen/src/Core/Assign_MKL.h +178 -0
  161. roboticstoolbox/core/Eigen/src/Core/BandMatrix.h +353 -0
  162. roboticstoolbox/core/Eigen/src/Core/Block.h +448 -0
  163. roboticstoolbox/core/Eigen/src/Core/BooleanRedux.h +162 -0
  164. roboticstoolbox/core/Eigen/src/Core/CommaInitializer.h +164 -0
  165. roboticstoolbox/core/Eigen/src/Core/ConditionEstimator.h +175 -0
  166. roboticstoolbox/core/Eigen/src/Core/CoreEvaluators.h +1741 -0
  167. roboticstoolbox/core/Eigen/src/Core/CoreIterators.h +132 -0
  168. roboticstoolbox/core/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  169. roboticstoolbox/core/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  170. roboticstoolbox/core/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  171. roboticstoolbox/core/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  172. roboticstoolbox/core/Eigen/src/Core/CwiseUnaryView.h +132 -0
  173. roboticstoolbox/core/Eigen/src/Core/DenseBase.h +701 -0
  174. roboticstoolbox/core/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  175. roboticstoolbox/core/Eigen/src/Core/DenseStorage.h +652 -0
  176. roboticstoolbox/core/Eigen/src/Core/Diagonal.h +258 -0
  177. roboticstoolbox/core/Eigen/src/Core/DiagonalMatrix.h +391 -0
  178. roboticstoolbox/core/Eigen/src/Core/DiagonalProduct.h +28 -0
  179. roboticstoolbox/core/Eigen/src/Core/Dot.h +318 -0
  180. roboticstoolbox/core/Eigen/src/Core/EigenBase.h +160 -0
  181. roboticstoolbox/core/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  182. roboticstoolbox/core/Eigen/src/Core/Fuzzy.h +155 -0
  183. roboticstoolbox/core/Eigen/src/Core/GeneralProduct.h +465 -0
  184. roboticstoolbox/core/Eigen/src/Core/GenericPacketMath.h +1040 -0
  185. roboticstoolbox/core/Eigen/src/Core/GlobalFunctions.h +194 -0
  186. roboticstoolbox/core/Eigen/src/Core/IO.h +258 -0
  187. roboticstoolbox/core/Eigen/src/Core/IndexedView.h +237 -0
  188. roboticstoolbox/core/Eigen/src/Core/Inverse.h +117 -0
  189. roboticstoolbox/core/Eigen/src/Core/Map.h +171 -0
  190. roboticstoolbox/core/Eigen/src/Core/MapBase.h +310 -0
  191. roboticstoolbox/core/Eigen/src/Core/MathFunctions.h +2057 -0
  192. roboticstoolbox/core/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  193. roboticstoolbox/core/Eigen/src/Core/Matrix.h +565 -0
  194. roboticstoolbox/core/Eigen/src/Core/MatrixBase.h +547 -0
  195. roboticstoolbox/core/Eigen/src/Core/NestByValue.h +85 -0
  196. roboticstoolbox/core/Eigen/src/Core/NoAlias.h +109 -0
  197. roboticstoolbox/core/Eigen/src/Core/NumTraits.h +335 -0
  198. roboticstoolbox/core/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  199. roboticstoolbox/core/Eigen/src/Core/PermutationMatrix.h +605 -0
  200. roboticstoolbox/core/Eigen/src/Core/PlainObjectBase.h +1128 -0
  201. roboticstoolbox/core/Eigen/src/Core/Product.h +191 -0
  202. roboticstoolbox/core/Eigen/src/Core/ProductEvaluators.h +1179 -0
  203. roboticstoolbox/core/Eigen/src/Core/Random.h +218 -0
  204. roboticstoolbox/core/Eigen/src/Core/Redux.h +515 -0
  205. roboticstoolbox/core/Eigen/src/Core/Ref.h +381 -0
  206. roboticstoolbox/core/Eigen/src/Core/Replicate.h +142 -0
  207. roboticstoolbox/core/Eigen/src/Core/Reshaped.h +454 -0
  208. roboticstoolbox/core/Eigen/src/Core/ReturnByValue.h +119 -0
  209. roboticstoolbox/core/Eigen/src/Core/Reverse.h +217 -0
  210. roboticstoolbox/core/Eigen/src/Core/Select.h +164 -0
  211. roboticstoolbox/core/Eigen/src/Core/SelfAdjointView.h +365 -0
  212. roboticstoolbox/core/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  213. roboticstoolbox/core/Eigen/src/Core/Solve.h +188 -0
  214. roboticstoolbox/core/Eigen/src/Core/SolveTriangular.h +235 -0
  215. roboticstoolbox/core/Eigen/src/Core/SolverBase.h +168 -0
  216. roboticstoolbox/core/Eigen/src/Core/StableNorm.h +251 -0
  217. roboticstoolbox/core/Eigen/src/Core/StlIterators.h +463 -0
  218. roboticstoolbox/core/Eigen/src/Core/Stride.h +116 -0
  219. roboticstoolbox/core/Eigen/src/Core/Swap.h +68 -0
  220. roboticstoolbox/core/Eigen/src/Core/Transpose.h +464 -0
  221. roboticstoolbox/core/Eigen/src/Core/Transpositions.h +386 -0
  222. roboticstoolbox/core/Eigen/src/Core/TriangularMatrix.h +1001 -0
  223. roboticstoolbox/core/Eigen/src/Core/VectorBlock.h +96 -0
  224. roboticstoolbox/core/Eigen/src/Core/VectorwiseOp.h +784 -0
  225. roboticstoolbox/core/Eigen/src/Core/Visitor.h +381 -0
  226. roboticstoolbox/core/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  227. roboticstoolbox/core/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  228. roboticstoolbox/core/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  229. roboticstoolbox/core/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  230. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  231. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  232. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  233. roboticstoolbox/core/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  234. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  235. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  236. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  237. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  238. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  239. roboticstoolbox/core/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  240. roboticstoolbox/core/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  241. roboticstoolbox/core/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  242. roboticstoolbox/core/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  243. roboticstoolbox/core/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  244. roboticstoolbox/core/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  245. roboticstoolbox/core/Eigen/src/Core/arch/Default/Half.h +942 -0
  246. roboticstoolbox/core/Eigen/src/Core/arch/Default/Settings.h +49 -0
  247. roboticstoolbox/core/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  248. roboticstoolbox/core/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  249. roboticstoolbox/core/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  250. roboticstoolbox/core/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  251. roboticstoolbox/core/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  252. roboticstoolbox/core/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  253. roboticstoolbox/core/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  254. roboticstoolbox/core/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  255. roboticstoolbox/core/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  256. roboticstoolbox/core/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  257. roboticstoolbox/core/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  258. roboticstoolbox/core/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  259. roboticstoolbox/core/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  260. roboticstoolbox/core/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  261. roboticstoolbox/core/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  262. roboticstoolbox/core/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  263. roboticstoolbox/core/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  264. roboticstoolbox/core/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  265. roboticstoolbox/core/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  266. roboticstoolbox/core/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  267. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  268. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  269. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  270. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  271. roboticstoolbox/core/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  272. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  273. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  274. roboticstoolbox/core/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  275. roboticstoolbox/core/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  276. roboticstoolbox/core/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  277. roboticstoolbox/core/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  278. roboticstoolbox/core/Eigen/src/Core/functors/StlFunctors.h +166 -0
  279. roboticstoolbox/core/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  280. roboticstoolbox/core/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  281. roboticstoolbox/core/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  282. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  283. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  284. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  285. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  286. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  287. roboticstoolbox/core/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  288. roboticstoolbox/core/Eigen/src/Core/products/Parallelizer.h +180 -0
  289. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  290. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  291. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  292. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  293. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  294. roboticstoolbox/core/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  295. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  296. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  297. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  298. roboticstoolbox/core/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  299. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  300. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  301. roboticstoolbox/core/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  302. roboticstoolbox/core/Eigen/src/Core/util/BlasUtil.h +583 -0
  303. roboticstoolbox/core/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  304. roboticstoolbox/core/Eigen/src/Core/util/Constants.h +563 -0
  305. roboticstoolbox/core/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  306. roboticstoolbox/core/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  307. roboticstoolbox/core/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  308. roboticstoolbox/core/Eigen/src/Core/util/IntegralConstant.h +272 -0
  309. roboticstoolbox/core/Eigen/src/Core/util/MKL_support.h +137 -0
  310. roboticstoolbox/core/Eigen/src/Core/util/Macros.h +1464 -0
  311. roboticstoolbox/core/Eigen/src/Core/util/Memory.h +1163 -0
  312. roboticstoolbox/core/Eigen/src/Core/util/Meta.h +812 -0
  313. roboticstoolbox/core/Eigen/src/Core/util/NonMPL2.h +3 -0
  314. roboticstoolbox/core/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  315. roboticstoolbox/core/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  316. roboticstoolbox/core/Eigen/src/Core/util/StaticAssert.h +221 -0
  317. roboticstoolbox/core/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  318. roboticstoolbox/core/Eigen/src/Core/util/XprHelper.h +856 -0
  319. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  320. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  321. roboticstoolbox/core/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  322. roboticstoolbox/core/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  323. roboticstoolbox/core/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  324. roboticstoolbox/core/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  325. roboticstoolbox/core/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  326. roboticstoolbox/core/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  327. roboticstoolbox/core/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  328. roboticstoolbox/core/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  329. roboticstoolbox/core/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  330. roboticstoolbox/core/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  331. roboticstoolbox/core/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  332. roboticstoolbox/core/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  333. roboticstoolbox/core/Eigen/src/Geometry/AlignedBox.h +486 -0
  334. roboticstoolbox/core/Eigen/src/Geometry/AngleAxis.h +247 -0
  335. roboticstoolbox/core/Eigen/src/Geometry/EulerAngles.h +114 -0
  336. roboticstoolbox/core/Eigen/src/Geometry/Homogeneous.h +501 -0
  337. roboticstoolbox/core/Eigen/src/Geometry/Hyperplane.h +282 -0
  338. roboticstoolbox/core/Eigen/src/Geometry/OrthoMethods.h +235 -0
  339. roboticstoolbox/core/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  340. roboticstoolbox/core/Eigen/src/Geometry/Quaternion.h +870 -0
  341. roboticstoolbox/core/Eigen/src/Geometry/Rotation2D.h +199 -0
  342. roboticstoolbox/core/Eigen/src/Geometry/RotationBase.h +206 -0
  343. roboticstoolbox/core/Eigen/src/Geometry/Scaling.h +188 -0
  344. roboticstoolbox/core/Eigen/src/Geometry/Transform.h +1563 -0
  345. roboticstoolbox/core/Eigen/src/Geometry/Translation.h +202 -0
  346. roboticstoolbox/core/Eigen/src/Geometry/Umeyama.h +166 -0
  347. roboticstoolbox/core/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  348. roboticstoolbox/core/Eigen/src/Householder/BlockHouseholder.h +110 -0
  349. roboticstoolbox/core/Eigen/src/Householder/Householder.h +176 -0
  350. roboticstoolbox/core/Eigen/src/Householder/HouseholderSequence.h +545 -0
  351. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  352. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  353. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  354. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  355. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  356. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  357. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  358. roboticstoolbox/core/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  359. roboticstoolbox/core/Eigen/src/Jacobi/Jacobi.h +483 -0
  360. roboticstoolbox/core/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  361. roboticstoolbox/core/Eigen/src/LU/Determinant.h +117 -0
  362. roboticstoolbox/core/Eigen/src/LU/FullPivLU.h +877 -0
  363. roboticstoolbox/core/Eigen/src/LU/InverseImpl.h +432 -0
  364. roboticstoolbox/core/Eigen/src/LU/PartialPivLU.h +624 -0
  365. roboticstoolbox/core/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  366. roboticstoolbox/core/Eigen/src/LU/arch/InverseSize4.h +351 -0
  367. roboticstoolbox/core/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  368. roboticstoolbox/core/Eigen/src/OrderingMethods/Amd.h +435 -0
  369. roboticstoolbox/core/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  370. roboticstoolbox/core/Eigen/src/OrderingMethods/Ordering.h +153 -0
  371. roboticstoolbox/core/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  372. roboticstoolbox/core/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  373. roboticstoolbox/core/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  374. roboticstoolbox/core/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  375. roboticstoolbox/core/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  376. roboticstoolbox/core/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  377. roboticstoolbox/core/Eigen/src/QR/HouseholderQR.h +434 -0
  378. roboticstoolbox/core/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  379. roboticstoolbox/core/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  380. roboticstoolbox/core/Eigen/src/SVD/BDCSVD.h +1366 -0
  381. roboticstoolbox/core/Eigen/src/SVD/JacobiSVD.h +812 -0
  382. roboticstoolbox/core/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  383. roboticstoolbox/core/Eigen/src/SVD/SVDBase.h +376 -0
  384. roboticstoolbox/core/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  385. roboticstoolbox/core/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  386. roboticstoolbox/core/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  387. roboticstoolbox/core/Eigen/src/SparseCore/AmbiVector.h +378 -0
  388. roboticstoolbox/core/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  389. roboticstoolbox/core/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  390. roboticstoolbox/core/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  391. roboticstoolbox/core/Eigen/src/SparseCore/SparseAssign.h +270 -0
  392. roboticstoolbox/core/Eigen/src/SparseCore/SparseBlock.h +571 -0
  393. roboticstoolbox/core/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  394. roboticstoolbox/core/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  395. roboticstoolbox/core/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  396. roboticstoolbox/core/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  397. roboticstoolbox/core/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  398. roboticstoolbox/core/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  399. roboticstoolbox/core/Eigen/src/SparseCore/SparseDot.h +98 -0
  400. roboticstoolbox/core/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  401. roboticstoolbox/core/Eigen/src/SparseCore/SparseMap.h +305 -0
  402. roboticstoolbox/core/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  403. roboticstoolbox/core/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  404. roboticstoolbox/core/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  405. roboticstoolbox/core/Eigen/src/SparseCore/SparseProduct.h +181 -0
  406. roboticstoolbox/core/Eigen/src/SparseCore/SparseRedux.h +49 -0
  407. roboticstoolbox/core/Eigen/src/SparseCore/SparseRef.h +397 -0
  408. roboticstoolbox/core/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  409. roboticstoolbox/core/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  410. roboticstoolbox/core/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  411. roboticstoolbox/core/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  412. roboticstoolbox/core/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  413. roboticstoolbox/core/Eigen/src/SparseCore/SparseUtil.h +186 -0
  414. roboticstoolbox/core/Eigen/src/SparseCore/SparseVector.h +478 -0
  415. roboticstoolbox/core/Eigen/src/SparseCore/SparseView.h +254 -0
  416. roboticstoolbox/core/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  417. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU.h +923 -0
  418. roboticstoolbox/core/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  419. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  420. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  421. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  422. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  423. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  424. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  425. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  426. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  427. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  428. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  429. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  430. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  431. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  432. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  433. roboticstoolbox/core/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  434. roboticstoolbox/core/Eigen/src/SparseQR/SparseQR.h +758 -0
  435. roboticstoolbox/core/Eigen/src/StlSupport/StdDeque.h +116 -0
  436. roboticstoolbox/core/Eigen/src/StlSupport/StdList.h +106 -0
  437. roboticstoolbox/core/Eigen/src/StlSupport/StdVector.h +131 -0
  438. roboticstoolbox/core/Eigen/src/StlSupport/details.h +84 -0
  439. roboticstoolbox/core/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  440. roboticstoolbox/core/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  441. roboticstoolbox/core/Eigen/src/misc/Image.h +82 -0
  442. roboticstoolbox/core/Eigen/src/misc/Kernel.h +79 -0
  443. roboticstoolbox/core/Eigen/src/misc/RealSvd2x2.h +55 -0
  444. roboticstoolbox/core/Eigen/src/misc/blas.h +440 -0
  445. roboticstoolbox/core/Eigen/src/misc/lapack.h +152 -0
  446. roboticstoolbox/core/Eigen/src/misc/lapacke.h +16292 -0
  447. roboticstoolbox/core/Eigen/src/misc/lapacke_mangling.h +17 -0
  448. roboticstoolbox/core/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  449. roboticstoolbox/core/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  450. roboticstoolbox/core/Eigen/src/plugins/BlockMethods.h +1442 -0
  451. roboticstoolbox/core/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  452. roboticstoolbox/core/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  453. roboticstoolbox/core/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  454. roboticstoolbox/core/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  455. roboticstoolbox/core/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  456. roboticstoolbox/core/Eigen/src/plugins/ReshapedMethods.h +149 -0
  457. roboticstoolbox/core/fknm.cpp +1557 -0
  458. roboticstoolbox/core/fknm.h +55 -0
  459. roboticstoolbox/core/frne.c +351 -0
  460. roboticstoolbox/core/frne.h +96 -0
  461. roboticstoolbox/core/ik.cpp +301 -0
  462. roboticstoolbox/core/ik.h +59 -0
  463. roboticstoolbox/core/linalg.cpp +316 -0
  464. roboticstoolbox/core/linalg.h +64 -0
  465. roboticstoolbox/core/methods.cpp +372 -0
  466. roboticstoolbox/core/methods.h +32 -0
  467. roboticstoolbox/core/ne.c +493 -0
  468. roboticstoolbox/core/structs.cpp +24 -0
  469. roboticstoolbox/core/structs.h +62 -0
  470. roboticstoolbox/core/vmath.c +163 -0
  471. roboticstoolbox/core/vmath.h +32 -0
  472. roboticstoolbox/fknm.cp313-win_amd64.pyd +0 -0
  473. roboticstoolbox/frne.cp313-win_amd64.pyd +0 -0
  474. roboticstoolbox/mobile/Animations.py +485 -0
  475. roboticstoolbox/mobile/Bug2.py +455 -0
  476. roboticstoolbox/mobile/CurvaturePolyPlanner.py +179 -0
  477. roboticstoolbox/mobile/DistanceTransformPlanner.py +395 -0
  478. roboticstoolbox/mobile/DstarPlanner.py +591 -0
  479. roboticstoolbox/mobile/DubinsPlanner.py +474 -0
  480. roboticstoolbox/mobile/EKF.py +1617 -0
  481. roboticstoolbox/mobile/LatticePlanner.py +419 -0
  482. roboticstoolbox/mobile/OccGrid.py +613 -0
  483. roboticstoolbox/mobile/PRMPlanner.py +348 -0
  484. roboticstoolbox/mobile/ParticleFilter.py +706 -0
  485. roboticstoolbox/mobile/PlannerBase.py +1009 -0
  486. roboticstoolbox/mobile/PoseGraph.py +544 -0
  487. roboticstoolbox/mobile/QuinticPolyPlanner.py +349 -0
  488. roboticstoolbox/mobile/RRTPlanner.py +359 -0
  489. roboticstoolbox/mobile/ReedsSheppPlanner.py +545 -0
  490. roboticstoolbox/mobile/Vehicle.py +1909 -0
  491. roboticstoolbox/mobile/__init__.py +193 -0
  492. roboticstoolbox/mobile/drivers.py +390 -0
  493. roboticstoolbox/mobile/landmarkmap.py +181 -0
  494. roboticstoolbox/mobile/sensors.py +771 -0
  495. roboticstoolbox/models/DH/AL5D.py +121 -0
  496. roboticstoolbox/models/DH/Ball.py +87 -0
  497. roboticstoolbox/models/DH/Baxter.py +91 -0
  498. roboticstoolbox/models/DH/Cobra600.py +63 -0
  499. roboticstoolbox/models/DH/Coil.py +80 -0
  500. roboticstoolbox/models/DH/Hyper.py +83 -0
  501. roboticstoolbox/models/DH/Hyper3d.py +85 -0
  502. roboticstoolbox/models/DH/IRB140.py +159 -0
  503. roboticstoolbox/models/DH/Jaco.py +102 -0
  504. roboticstoolbox/models/DH/KR5.py +112 -0
  505. roboticstoolbox/models/DH/LWR4.py +85 -0
  506. roboticstoolbox/models/DH/Mico.py +102 -0
  507. roboticstoolbox/models/DH/Orion5.py +91 -0
  508. roboticstoolbox/models/DH/P8.py +80 -0
  509. roboticstoolbox/models/DH/Panda.py +178 -0
  510. roboticstoolbox/models/DH/Planar2.py +69 -0
  511. roboticstoolbox/models/DH/Planar3.py +51 -0
  512. roboticstoolbox/models/DH/Puma560.py +326 -0
  513. roboticstoolbox/models/DH/README.md +216 -0
  514. roboticstoolbox/models/DH/Sawyer.py +85 -0
  515. roboticstoolbox/models/DH/Stanford.py +147 -0
  516. roboticstoolbox/models/DH/TwoLink.py +109 -0
  517. roboticstoolbox/models/DH/UR10.py +124 -0
  518. roboticstoolbox/models/DH/UR3.py +98 -0
  519. roboticstoolbox/models/DH/UR5.py +98 -0
  520. roboticstoolbox/models/DH/Uprighttl.py +24 -0
  521. roboticstoolbox/models/DH/__init__.py +52 -0
  522. roboticstoolbox/models/ETS/Frankie.py +90 -0
  523. roboticstoolbox/models/ETS/GenericSeven.py +54 -0
  524. roboticstoolbox/models/ETS/Omni.py +74 -0
  525. roboticstoolbox/models/ETS/Panda.py +69 -0
  526. roboticstoolbox/models/ETS/Planar2.py +49 -0
  527. roboticstoolbox/models/ETS/Planar_Y.py +65 -0
  528. roboticstoolbox/models/ETS/Puma560.py +69 -0
  529. roboticstoolbox/models/ETS/XYPanda.py +84 -0
  530. roboticstoolbox/models/ETS/__init__.py +20 -0
  531. roboticstoolbox/models/README.md +9 -0
  532. roboticstoolbox/models/URDF/AL5D.py +54 -0
  533. roboticstoolbox/models/URDF/Fetch.py +70 -0
  534. roboticstoolbox/models/URDF/FetchCamera.py +71 -0
  535. roboticstoolbox/models/URDF/Frankie.py +75 -0
  536. roboticstoolbox/models/URDF/FrankieOmni.py +94 -0
  537. roboticstoolbox/models/URDF/KinovaGen3.py +71 -0
  538. roboticstoolbox/models/URDF/LBR.py +59 -0
  539. roboticstoolbox/models/URDF/Mico.py +68 -0
  540. roboticstoolbox/models/URDF/PR2.py +64 -0
  541. roboticstoolbox/models/URDF/Panda.py +67 -0
  542. roboticstoolbox/models/URDF/Puma560.py +97 -0
  543. roboticstoolbox/models/URDF/UR10.py +53 -0
  544. roboticstoolbox/models/URDF/UR3.py +53 -0
  545. roboticstoolbox/models/URDF/UR5.py +74 -0
  546. roboticstoolbox/models/URDF/Valkyrie.py +84 -0
  547. roboticstoolbox/models/URDF/YuMi.py +109 -0
  548. roboticstoolbox/models/URDF/__init__.py +53 -0
  549. roboticstoolbox/models/URDF/px100.py +56 -0
  550. roboticstoolbox/models/URDF/px150.py +56 -0
  551. roboticstoolbox/models/URDF/rx150.py +56 -0
  552. roboticstoolbox/models/URDF/rx200.py +56 -0
  553. roboticstoolbox/models/URDF/vx300.py +56 -0
  554. roboticstoolbox/models/URDF/vx300s.py +56 -0
  555. roboticstoolbox/models/URDF/wx200.py +56 -0
  556. roboticstoolbox/models/URDF/wx250.py +56 -0
  557. roboticstoolbox/models/URDF/wx250s.py +56 -0
  558. roboticstoolbox/models/__init__.py +7 -0
  559. roboticstoolbox/models/list.py +119 -0
  560. roboticstoolbox/robot/BaseRobot.py +3133 -0
  561. roboticstoolbox/robot/DHFactor.py +522 -0
  562. roboticstoolbox/robot/DHLink.py +981 -0
  563. roboticstoolbox/robot/DHRobot.py +2520 -0
  564. roboticstoolbox/robot/Dynamics.py +1620 -0
  565. roboticstoolbox/robot/ELink.py +23 -0
  566. roboticstoolbox/robot/ERobot.py +25 -0
  567. roboticstoolbox/robot/ET.py +1097 -0
  568. roboticstoolbox/robot/ETS.py +3542 -0
  569. roboticstoolbox/robot/Gripper.py +282 -0
  570. roboticstoolbox/robot/IK.py +1522 -0
  571. roboticstoolbox/robot/Link.py +1698 -0
  572. roboticstoolbox/robot/PoERobot.py +348 -0
  573. roboticstoolbox/robot/Robot.py +2100 -0
  574. roboticstoolbox/robot/RobotKinematics.py +1725 -0
  575. roboticstoolbox/robot/RobotProto.py +92 -0
  576. roboticstoolbox/robot/__init__.py +54 -0
  577. roboticstoolbox/tools/DHFactor.py +375 -0
  578. roboticstoolbox/tools/Ticker.py +53 -0
  579. roboticstoolbox/tools/__init__.py +54 -0
  580. roboticstoolbox/tools/data.py +187 -0
  581. roboticstoolbox/tools/jsingu.py +51 -0
  582. roboticstoolbox/tools/null.py +48 -0
  583. roboticstoolbox/tools/numerical.py +96 -0
  584. roboticstoolbox/tools/p_servo.py +106 -0
  585. roboticstoolbox/tools/params.py +11 -0
  586. roboticstoolbox/tools/plot.py +109 -0
  587. roboticstoolbox/tools/trajectory.py +1152 -0
  588. roboticstoolbox/tools/types.py +13 -0
  589. roboticstoolbox/tools/urdf/__init__.py +45 -0
  590. roboticstoolbox/tools/urdf/tests/data/ur5.urdf +341 -0
  591. roboticstoolbox/tools/urdf/tests/test_urdf.py +116 -0
  592. roboticstoolbox/tools/urdf/urdf.py +1976 -0
  593. roboticstoolbox/tools/urdf/utils.py +50 -0
  594. roboticstoolbox/tools/xacro/__init__.py +1148 -0
  595. roboticstoolbox/tools/xacro/cli.py +128 -0
  596. roboticstoolbox/tools/xacro/color.py +66 -0
  597. roboticstoolbox/tools/xacro/tests/CMakeLists.txt +4 -0
  598. roboticstoolbox/tools/xacro/tests/broken.xacro +1 -0
  599. roboticstoolbox/tools/xacro/tests/emoji.xacro +5 -0
  600. roboticstoolbox/tools/xacro/tests/include1.xacro +4 -0
  601. roboticstoolbox/tools/xacro/tests/include1.xml +1 -0
  602. roboticstoolbox/tools/xacro/tests/include2.xacro +4 -0
  603. roboticstoolbox/tools/xacro/tests/include2.xml +1 -0
  604. roboticstoolbox/tools/xacro/tests/robots/README +4 -0
  605. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.gazebo.xacro +59 -0
  606. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.transmission.xacro +24 -0
  607. roboticstoolbox/tools/xacro/tests/robots/pr2/base_v0/base.urdf.xacro +264 -0
  608. roboticstoolbox/tools/xacro/tests/robots/pr2/common.xacro +71 -0
  609. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.gazebo.xacro +36 -0
  610. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.transmission.xacro +20 -0
  611. roboticstoolbox/tools/xacro/tests/robots/pr2/forearm_v0/forearm.urdf.xacro +130 -0
  612. roboticstoolbox/tools/xacro/tests/robots/pr2/gazebo/gazebo.urdf.xacro +24 -0
  613. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.gazebo.xacro +288 -0
  614. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.transmission.xacro +50 -0
  615. roboticstoolbox/tools/xacro/tests/robots/pr2/gripper_v0/gripper.urdf.xacro +374 -0
  616. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.gazebo.xacro +16 -0
  617. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.transmission.xacro +34 -0
  618. roboticstoolbox/tools/xacro/tests/robots/pr2/head_v0/head.urdf.xacro +147 -0
  619. roboticstoolbox/tools/xacro/tests/robots/pr2/materials.urdf.xacro +52 -0
  620. roboticstoolbox/tools/xacro/tests/robots/pr2/pr2.urdf.xacro +157 -0
  621. roboticstoolbox/tools/xacro/tests/robots/pr2/pr2_1.11.4.xml +3781 -0
  622. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/double_stereo_camera.gazebo.xacro +16 -0
  623. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/double_stereo_camera.urdf.xacro +61 -0
  624. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/head_sensor_package.gazebo.xacro +20 -0
  625. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/head_sensor_package.urdf.xacro +63 -0
  626. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/hokuyo_lx30_laser.gazebo.xacro +39 -0
  627. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/hokuyo_lx30_laser.urdf.xacro +27 -0
  628. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_camera.gazebo.xacro +87 -0
  629. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_camera.urdf.xacro +55 -0
  630. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_prosilica_camera.gazebo.xacro +193 -0
  631. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/kinect_prosilica_camera.urdf.xacro +181 -0
  632. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/microstrain_3dmgx2_imu.gazebo.xacro +20 -0
  633. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/microstrain_3dmgx2_imu.urdf.xacro +25 -0
  634. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/projector_wg6802418.gazebo.xacro +31 -0
  635. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/projector_wg6802418.urdf.xacro +42 -0
  636. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/prosilica_gc2450_camera.gazebo.xacro +43 -0
  637. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/prosilica_gc2450_camera.urdf.xacro +49 -0
  638. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/stereo_camera.gazebo.xacro +23 -0
  639. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/stereo_camera.urdf.xacro +71 -0
  640. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/wge100_camera.gazebo.xacro +46 -0
  641. roboticstoolbox/tools/xacro/tests/robots/pr2/sensors/wge100_camera.urdf.xacro +47 -0
  642. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.gazebo.xacro +40 -0
  643. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.transmission.xacro +35 -0
  644. roboticstoolbox/tools/xacro/tests/robots/pr2/shoulder_v0/shoulder.urdf.xacro +167 -0
  645. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.gazebo.xacro +11 -0
  646. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.transmission.xacro +14 -0
  647. roboticstoolbox/tools/xacro/tests/robots/pr2/tilting_laser_v0/tilting_laser.urdf.xacro +60 -0
  648. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.gazebo.xacro +37 -0
  649. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.transmission.xacro +22 -0
  650. roboticstoolbox/tools/xacro/tests/robots/pr2/torso_v0/torso.urdf.xacro +122 -0
  651. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.gazebo.xacro +39 -0
  652. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.transmission.xacro +28 -0
  653. roboticstoolbox/tools/xacro/tests/robots/pr2/upper_arm_v0/upper_arm.urdf.xacro +173 -0
  654. roboticstoolbox/tools/xacro/tests/settings.yaml +9 -0
  655. roboticstoolbox/tools/xacro/tests/subdir/foo.xacro +3 -0
  656. roboticstoolbox/tools/xacro/tests/subdir/include-recursive.xacro +5 -0
  657. roboticstoolbox/tools/xacro/tests/subdir/include1.xml +1 -0
  658. roboticstoolbox/tools/xacro/tests/test_xacro.py +1418 -0
  659. roboticstoolbox/tools/xacro/xmlutils.py +152 -0
  660. roboticstoolbox_python-1.3.0.dist-info/METADATA +552 -0
  661. roboticstoolbox_python-1.3.0.dist-info/RECORD +673 -0
  662. roboticstoolbox_python-1.3.0.dist-info/WHEEL +5 -0
  663. roboticstoolbox_python-1.3.0.dist-info/entry_points.txt +6 -0
  664. roboticstoolbox_python-1.3.0.dist-info/licenses/LICENSE +21 -0
  665. spatialgeometry/__init__.py +32 -0
  666. spatialgeometry/geom/CollisionShape.py +419 -0
  667. spatialgeometry/geom/SceneGroup.py +26 -0
  668. spatialgeometry/geom/SceneNode.py +315 -0
  669. spatialgeometry/geom/Shape.py +420 -0
  670. spatialgeometry/geom/__init__.py +26 -0
  671. spatialgeometry/scene.py +107 -0
  672. spatialgeometry/tools/__init__.py +0 -0
  673. spatialgeometry/tools/stdout_supress.py +302 -0
@@ -0,0 +1,1909 @@
1
+ """
2
+ Python Vehicle
3
+ @Author: Peter Corke, original MATLAB code and Python version
4
+ @Author: Kristian Gibson, initial MATLAB port
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ import warnings
9
+ import sys
10
+ from math import pi, sin, cos, tan
11
+ import numpy as np
12
+ from scipy import interpolate
13
+
14
+ import matplotlib.pyplot as plt
15
+ from matplotlib import animation
16
+
17
+ # from matplotlib import patches
18
+ # import matplotlib.transforms as mtransforms
19
+
20
+ from spatialmath import SE2, base
21
+ from roboticstoolbox.mobile.drivers import VehicleDriverBase
22
+ from roboticstoolbox.mobile.Animations import VehiclePolygon
23
+
24
+
25
+ def _isnotebook():
26
+ """
27
+ Determine if code is being run from a Jupyter notebook or JupyterLite.
28
+ """
29
+ if sys.platform == "emscripten":
30
+ return True
31
+
32
+ if "ipykernel" in sys.modules or "google.colab" in sys.modules:
33
+ return True
34
+
35
+ try:
36
+ get_ipython_fn = globals().get("get_ipython", None)
37
+ if callable(get_ipython_fn):
38
+ shell = get_ipython_fn().__class__.__name__
39
+ if shell == "ZMQInteractiveShell":
40
+ return True
41
+ return False
42
+ except Exception:
43
+ return False
44
+
45
+
46
+ def _refresh_animation_frame(fig, dt, pause):
47
+ """
48
+ Refresh animation for desktop and notebook backends.
49
+
50
+ Notebook inline backends do not always animate with ``plt.pause`` alone,
51
+ so we explicitly draw and re-display the figure there.
52
+ """
53
+ if fig is None:
54
+ return
55
+
56
+ if not pause:
57
+ try:
58
+ fig.canvas.draw_idle()
59
+ fig.canvas.flush_events()
60
+ except Exception:
61
+ pass
62
+ return
63
+
64
+ if _isnotebook():
65
+ try:
66
+ fig.canvas.draw_idle()
67
+ fig.canvas.flush_events()
68
+ except Exception:
69
+ pass
70
+
71
+ backend = plt.get_backend().lower()
72
+ if (
73
+ "inline" in backend
74
+ or "matplotlib_inline" in backend
75
+ or sys.platform == "emscripten"
76
+ ):
77
+ try:
78
+ import importlib
79
+
80
+ ipdisplay = importlib.import_module("IPython.display")
81
+ ipdisplay.clear_output(wait=True)
82
+ ipdisplay.display(fig)
83
+ return
84
+ except Exception:
85
+ pass
86
+
87
+ plt.pause(dt)
88
+
89
+
90
+ class Trailer:
91
+ def __init__(self, L1=1, L2=1, animation=None, polygon=None, **kwargs):
92
+ """
93
+ _summary_
94
+
95
+ :param L1: _description_, defaults to 1
96
+ :type L1: int, optional
97
+ :param L2: _description_, defaults to 1
98
+ :type L2: int, optional
99
+ :param animation: _description_, defaults to None
100
+ :type animation: _type_, optional
101
+ :param polygon: bounding polygon of vehicle
102
+ :type polygon: :class:`~spatialmath.geom2d.Polygon2`
103
+ """
104
+ self._L1 = L1
105
+ self._L2 = L2
106
+
107
+ self._polygon = polygon
108
+ if animation is not None:
109
+ if isinstance(animation, str):
110
+ animation = VehiclePolygon(animation)
111
+ self._animation = animation
112
+ elif polygon is not None:
113
+ self._animation = VehiclePolygon(polygon)
114
+
115
+ self._kwargs = kwargs
116
+
117
+
118
+ class VehicleBase(ABC):
119
+ def __init__(
120
+ self,
121
+ covar=None,
122
+ speed_max=np.inf,
123
+ accel_max=np.inf,
124
+ x0=[0, 0, 0],
125
+ dt=0.1,
126
+ control=None,
127
+ seed=0,
128
+ animation=None,
129
+ verbose=False,
130
+ plot=False,
131
+ workspace=None,
132
+ polygon=None,
133
+ trailers=None,
134
+ ):
135
+ r"""
136
+ Superclass for vehicle kinematic models
137
+
138
+ :param covar: odometry covariance, defaults to zero
139
+ :type covar: ndarray(2,2), optional
140
+ :param speed_max: maximum speed, defaults to :math:`\infty`
141
+ :type speed_max: float, optional
142
+ :param accel_max: maximum acceleration, defaults to :math:`\infty`
143
+ :type accel_max: float, optional
144
+ :param x0: Initial state, defaults to (0,0,0)
145
+ :type x0: array_like(3), optional
146
+ :param dt: sample update interval, defaults to 0.1
147
+ :type dt: float, optional
148
+ :param control: vehicle control inputs, defaults to None
149
+ :type control: array_like(2), interp1d, VehicleDriverBase
150
+ :param animation: Graphical animation of vehicle, defaults to None
151
+ :type animation: :class:`VehicleAnimationBase` subclass, optional
152
+ :param verbose: print lots of info, defaults to False
153
+ :type verbose: bool, optional
154
+ :param workspace: dimensions of 2D plot area, defaults to (-10:10) x (-10:10),
155
+ see :func:`~spatialmath.base.graphics.plotvol2`
156
+ :type workspace: float, array_like(2), array_like(4)
157
+ :param polygon: bounding polygon of vehicle
158
+ :type polygon: :class:`~spatialmath.geom2d.Polygon2`
159
+
160
+ This is an abstract superclass that simulates the motion of a mobile
161
+ robot under the action of a controller. The controller provides
162
+ control inputs to the vehicle, and the output odometry is returned.
163
+ The true state, effectively unknowable in practice, is computed
164
+ and accessible.
165
+
166
+ The workspace can be specified in several ways:
167
+
168
+ ============== ======= =======
169
+ ``workspace`` x-range y-range
170
+ ============== ======= =======
171
+ A (scalar) -A:A -A:A
172
+ [A, B] A:B A:B
173
+ [A, B, C, D] A:B C:D
174
+ ============== ======= =======
175
+
176
+ :note: Set ``seed=None`` to have it randomly initialized from the
177
+ operating system.
178
+
179
+ :seealso: :class:`Bicycle` :class:`Unicycle` :class:`VehicleAnimationBase`
180
+ """
181
+
182
+ self._V = covar
183
+ self._dt = dt
184
+ if x0 is None:
185
+ x0 = np.zeros((3,), dtype=float)
186
+ else:
187
+ x0 = base.getvector(x0)
188
+ if len(x0) not in (2, 3):
189
+ raise ValueError("x0 must be length 2 or 3")
190
+ self._x0 = x0
191
+ self._x = x0.copy()
192
+
193
+ self._random = np.random.default_rng(seed)
194
+ self._seed = seed
195
+ self._speed_max = speed_max
196
+ self._accel_max = accel_max
197
+ self._v_prev = [0]
198
+
199
+ self._polygon = polygon
200
+ if isinstance(animation, str):
201
+ animation = VehiclePolygon(animation)
202
+ self._animation = animation
203
+ self._ax = None
204
+
205
+ if control is not None:
206
+ self.add_driver(control)
207
+
208
+ self._dt = dt
209
+ self._t = 0
210
+ self._stopsim = False
211
+
212
+ self._verbose = verbose
213
+ self._plot = False
214
+
215
+ self._control = control
216
+ self._x_hist = []
217
+
218
+ if workspace:
219
+ try:
220
+ self._workspace = workspace.workspace
221
+ except AttributeError:
222
+ self._workspace = base.expand_dims(workspace)
223
+ else:
224
+ self._workspace = None
225
+
226
+ def __str__(self):
227
+ """
228
+ String representation of vehicle (superclass)
229
+
230
+ :return: String representation of vehicle object
231
+ :rtype: str
232
+ """
233
+ s = f"{self.__class__.__name__}: "
234
+ s += f"x = {base.array2str(self._x)}"
235
+ return s
236
+
237
+ def __repr__(self):
238
+ return str(self)
239
+
240
+ def f(self, x, odo, v=None):
241
+ r"""
242
+ State transition function
243
+
244
+ :param x: vehicle state :math:`(x, y, \theta)`
245
+ :type x: array_like(3), ndarray(n,3)
246
+ :param odo: vehicle odometry :math:`(\delta_d, \delta_\theta)`
247
+ :type odo: array_like(2)
248
+ :param v: additive odometry noise, defaults to (0,0)
249
+ :type v: array_like(2), optional
250
+ :return: predicted vehicle state
251
+ :rtype: ndarray(3)
252
+
253
+ Predict the next state based on current state and odometry
254
+ value. ``v`` is a random variable that represents additive
255
+ odometry noise for simulation purposes.
256
+
257
+ .. math::
258
+
259
+ f: \vec{x}_k, \delta_d, \delta_\theta \mapsto \vec{x}_{k+1}
260
+
261
+ For particle filters it is useful to apply the odometry to the
262
+ states of all particles and this can be achieved if ``x`` is a 2D
263
+ array with one state per row. ``v`` is ignored in this case.
264
+
265
+ .. note:: This is the state update equation used for EKF localization.
266
+
267
+ :seealso: :meth:`deriv` :meth:`Fx` :meth:`Fv`
268
+ """
269
+ odo = base.getvector(odo, 2)
270
+
271
+ if isinstance(x, np.ndarray) and x.ndim == 2:
272
+ # x is Nx3 set of vehicle states, do vectorized form
273
+ # used by particle filter
274
+ dd, dth = odo
275
+ theta = x[:, 2]
276
+ return (
277
+ np.array(x)
278
+ + np.c_[
279
+ dd * np.cos(theta), dd * np.sin(theta), np.full(theta.shape, dth)
280
+ ]
281
+ )
282
+ else:
283
+ # x is a vector
284
+ x = base.getvector(x, 3)
285
+ dd, dth = odo
286
+ theta = x[2]
287
+
288
+ if v is not None:
289
+ v = base.getvector(v, 2)
290
+ dd += v[0]
291
+ dth += v[1]
292
+
293
+ return x + np.r_[dd * np.cos(theta), dd * np.sin(theta), dth]
294
+
295
+ def Fx(self, x, odo):
296
+ r"""
297
+ Jacobian of state transition function df/dx
298
+
299
+ :param x: vehicle state :math:`(x, y, \theta)`
300
+ :type x: array_like(3)
301
+ :param odo: vehicle odometry :math:`(\delta_d, \delta_\theta)`
302
+ :type odo: array_like(2)
303
+ :return: Jacobian matrix
304
+ :rtype: ndarray(3,3)
305
+
306
+ Returns the Jacobian matrix :math:`\frac{\partial \vec{f}}{\partial \vec{x}}` for
307
+ the given state and odometry.
308
+
309
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fv`
310
+ """
311
+ dd, dth = odo
312
+ theta = x[2]
313
+
314
+ # fmt: off
315
+ J = np.array([
316
+ [1, 0, -dd * sin(theta)],
317
+ [0, 1, dd * cos(theta)],
318
+ [0, 0, 1],
319
+ ])
320
+ # fmt: on
321
+ return J
322
+
323
+ def Fv(self, x, odo):
324
+ r"""
325
+ Jacobian of state transition function df/dv
326
+
327
+ :param x: vehicle state :math:`(x, y, \theta)`
328
+ :type x: array_like(3)
329
+ :param odo: vehicle odometry :math:`(\delta_d, \delta_\theta)`
330
+ :type odo: array_like(2)
331
+ :return: Jacobian matrix
332
+ :rtype: ndarray(3,2)
333
+
334
+ Returns the Jacobian matrix :math:`\frac{\partial \vec{f}}{\partial \vec{v}}` for
335
+ the given state and odometry.
336
+
337
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fx`
338
+ """
339
+ dd, dth = odo
340
+ theta = x[2]
341
+
342
+ # fmt: off
343
+ J = np.array([
344
+ [cos(theta), 0],
345
+ [sin(theta), 0],
346
+ [0, 1],
347
+ ])
348
+ # fmt: on
349
+ return J
350
+
351
+ @property
352
+ def control(self):
353
+ """
354
+ Get/set vehicle control (superclass)
355
+
356
+ :getter: Returns vehicle's control
357
+ :setter: Sets the vehicle's control
358
+ :type: 2-tuple, callable, interp1d or VehicleDriver
359
+
360
+ This is the input to the vehicle during a simulation performed
361
+ by :meth:`run`. The control input can be:
362
+
363
+ * a constant tuple as the control inputs to the vehicle
364
+ * a function called as ``f(vehicle, t, x)`` that returns a tuple
365
+ * an interpolator called as ``f(t)`` that returns a tuple
366
+ * a driver agent, subclass of :class:`~roboticstoolbox.mobile.driversVehicleDriverBase`
367
+
368
+ Example:
369
+
370
+ .. runblock:: pycon
371
+
372
+ >>> from roboticstoolbox import Bicycle, RandomPath
373
+ >>> bike = Bicycle()
374
+ >>> bike.control = RandomPath(10)
375
+ >>> print(bike)
376
+
377
+ :seealso: :meth:`run` :meth:`eval_control` :obj:`scipy.interpolate.interp1d` :class:`~roboticstoolbox.mobile.drivers.VehicleDriverBase`
378
+ """
379
+ return self._control
380
+
381
+ @control.setter
382
+ def control(self, control):
383
+
384
+ # * a function called as ``f(vehicle, t, x)`` that returns a tuple
385
+ # * an interpolator called as f(t) that returns a tuple, see
386
+ # SciPy interp1d
387
+
388
+ self._control = control
389
+ if isinstance(control, VehicleDriverBase):
390
+ # if this is a driver agent, connect it to the vehicle
391
+ control.vehicle = self
392
+
393
+ def eval_control(self, control, x):
394
+ """
395
+ Evaluate vehicle control input (superclass method)
396
+
397
+ :param control: vehicle control
398
+ :type control: [type]
399
+ :param x: vehicle state :math:`(x, y, \theta)`
400
+ :type x: array_like(3)
401
+ :raises ValueError: bad control
402
+ :return: vehicle control inputs
403
+ :rtype: ndarray(2)
404
+
405
+ Evaluates the control for this time step and state. Control is set
406
+ by the :meth:`control` property to:
407
+
408
+ * a constant tuple as the control inputs to the vehicle
409
+ * a function called as ``f(vehicle, t, x)`` that returns a tuple
410
+ * an interpolator called as f(t) that returns a tuple
411
+ * a driver agent, subclass of :class:`VehicleDriverBase`
412
+
413
+ Vehicle steering, speed and acceleration limits are applied to the
414
+ result before being input to the vehicle model.
415
+
416
+ :seealso: :meth:`run` :meth:`control` :func:`scipy.interpolate.interp1d`
417
+ """
418
+ # was called control() in the MATLAB version
419
+
420
+ if base.isvector(control, 2):
421
+ # control is a constant
422
+ u = base.getvector(control, 2)
423
+
424
+ elif isinstance(control, VehicleDriverBase):
425
+ # vehicle has a driver object
426
+ u = control.demand()
427
+
428
+ elif isinstance(control, interpolate.interpolate.interp1d):
429
+ # control is an interp1d object
430
+ u = control(self._t)
431
+
432
+ elif callable(control):
433
+ # control is a user function of time and state
434
+ u = control(self, self._t, x)
435
+
436
+ else:
437
+ raise ValueError("bad control specified")
438
+
439
+ # apply limits
440
+ ulim = self.u_limited(u)
441
+ return ulim
442
+
443
+ def limits_va(self, v, v_prev):
444
+ """
445
+ Apply velocity and acceleration limits (superclass)
446
+
447
+ :param v: desired velocity
448
+ :type v: float
449
+ :param v_prev: previous velocity, reference to list
450
+ :type v_prev: list with single element
451
+ :return: allowed velocity
452
+ :rtype: float
453
+
454
+ Determine allowable velocity given desired velocity, speed and
455
+ acceleration limits.
456
+
457
+ .. note:: This function requires previous velocity, ``v_prev`` to enable
458
+ acceleration limiting. This is passed as a reference to a mutable value,
459
+ a single-element list. This is reset to zero at the start of each simulation.
460
+ """
461
+ # acceleration limit
462
+ vp = v_prev[0]
463
+ if self._accel_max is not None:
464
+ if (v - vp) / self._dt > self._accel_max:
465
+ v = vp + self._accel_max * self._dt
466
+ elif (v - vp) / self._dt < -self._accel_max:
467
+ v = vp - self._accel_max * self._dt
468
+ v_prev[0] = v
469
+
470
+ # speed limit
471
+ if self._speed_max is not None:
472
+ v = np.clip(v, -self._speed_max, self._speed_max)
473
+ return v
474
+
475
+ def polygon(self, q):
476
+ """
477
+ Bounding polygon at vehicle configuration
478
+
479
+ :param q: vehicle configuration :math:`(x, y, \theta)`
480
+ :type q: array_like(3)
481
+ :return: bounding polygon of vehicle at configuration ``q``
482
+ :rtype: :class:`~spatialmath.geom2d.Polygon2`
483
+
484
+ The bounding polygon of the vehicle is returned for the configuration
485
+ ``q``. Can be used for collision checking using the :meth:`~spatialmath.geom2d.Polygon2.intersects`
486
+ method.
487
+
488
+ :seealso: :class:`~spatialmath.geom2d.Polygon2`
489
+ """
490
+ return self._polygon.transformed(SE2(q))
491
+
492
+ # This function is overridden by the child class
493
+ @abstractmethod
494
+ def deriv(self, x, u):
495
+ pass
496
+
497
+ def add_driver(self, driver):
498
+ """
499
+ Add a driver agent (superclass)
500
+
501
+ :param driver: a driver agent object
502
+ :type driver: VehicleDriverBase subclass
503
+
504
+ .. warning:: Deprecated. Use ``vehicle.control = driver`` instead.
505
+
506
+ :seealso: :class:`VehicleDriverBase` :meth:`control`
507
+ """
508
+
509
+ warnings.warn("add_driver is deprecated, use veh.control=driver instead")
510
+ self._control = driver
511
+ driver._veh = self
512
+
513
+ def run(self, T=10, x0=None, control=None, animate=True):
514
+ r"""
515
+ Simulate motion of vehicle (superclass)
516
+
517
+ :param T: Simulation time in seconds, defaults to 10
518
+ :type T: float, optional
519
+ :param x0: Initial state, defaults to value given to Vehicle constructor
520
+ :type x0: array_like(3) or array_like(2)
521
+ :param control: vehicle control inputs, defaults to None
522
+ :type control: array_like(2), callable, driving agent
523
+ :param animate: Enable graphical animation of vehicle, defaults to False
524
+ :type animate: bool, optional
525
+ :return: State trajectory, each row is :math:`(x,y,\theta)`.
526
+ :rtype: ndarray(n,3)
527
+
528
+ Runs the vehicle simulation for ``T`` seconds and optionally plots
529
+ an animation. The method :meth:`step` performs each time step.
530
+
531
+ The control inputs are provided by ``control`` which can be:
532
+
533
+ * a constant tuple as the control inputs to the vehicle
534
+ * a function called as ``f(vehicle, t, x)`` that returns a tuple
535
+ * an interpolator called as ``f(t)`` that returns a tuple, see
536
+ SciPy interp1d
537
+ * a driver agent, subclass of :class:`VehicleDriverBase`
538
+
539
+ This is evaluated by :meth:`eval_control` which applies velocity,
540
+ acceleration and steering limits.
541
+
542
+ The simulation can be stopped prematurely by the control function
543
+ calling :meth:`stopsim`.
544
+
545
+ .. note::
546
+ * the simulation is fixed-time step with the step given by the ``dt``
547
+ attribute set by the constructor.
548
+ * integration uses rectangular integration.
549
+
550
+ :seealso: :meth:`init` :meth:`step` :meth:`control` :meth:`run_animation`
551
+ """
552
+
553
+ self.init(control=control, animate=animate, x0=x0)
554
+
555
+ for i in range(round(T / self.dt)):
556
+ self.step(animate=animate)
557
+
558
+ # check for user requested stop
559
+ if self._stopsim:
560
+ print("USER REEQUESTED STOP AT time", self._t)
561
+ break
562
+
563
+ return self.x_hist
564
+
565
+ def run_animation(self, T=10, x0=None, control=None, format=None, file=None):
566
+ r"""
567
+ Simulate motion of vehicle (superclass)
568
+
569
+ :param T: Simulation time in seconds, defaults to 10
570
+ :type T: float, optional
571
+ :param x0: Initial state, defaults to value given to Vehicle constructor
572
+ :type x0: array_like(3) or array_like(2)
573
+ :param control: vehicle control inputs, defaults to None
574
+ :type control: array_like(2), callable, driving agent
575
+ :param format: Output format
576
+ :type format: str, optional
577
+ :param file: File name
578
+ :type file: str, optional
579
+ :return: Matplotlib animation object
580
+ :rtype: :meth:`matplotlib.animation.FuncAnimation`
581
+
582
+ Runs the vehicle simulation for ``T`` seconds and returns an animation
583
+ in various formats::
584
+
585
+ ``format`` ``file`` description
586
+ ============ ========= ============================
587
+ ``"html"`` str, None return HTML5 video
588
+ ``"jshtml"`` str, None return JS+HTML video
589
+ ``"gif"`` str return animated GIF
590
+ ``"mp4"`` str return MP4/H264 video
591
+ ``None`` return a ``FuncAnimation`` object
592
+
593
+ The allowables types for ``file`` are given in the second column. A str
594
+ value is the file name. If ``None`` is an option then return the video as a string.
595
+
596
+ For the last case, a reference to the animation object must be held if used for
597
+ animation in a Jupyter cell::
598
+
599
+ anim = robot.run_animation(T=20)
600
+
601
+ The control inputs are provided by ``control`` which can be:
602
+
603
+ * a constant tuple as the control inputs to the vehicle
604
+ * a function called as ``f(vehicle, t, x)`` that returns a tuple
605
+ * an interpolator called as ``f(t)`` that returns a tuple, see
606
+ SciPy interp1d
607
+ * a driver agent, subclass of :class:`VehicleDriverBase`
608
+
609
+ This is evaluated by :meth:`eval_control` which applies velocity,
610
+ acceleration and steering limits.
611
+
612
+ The simulation can be stopped prematurely by the control function
613
+ calling :meth:`stopsim`.
614
+
615
+ .. note::
616
+ * the simulation is fixed-time step with the step given by the ``dt``
617
+ attribute set by the constructor.
618
+ * integration uses rectangular integration.
619
+
620
+ :seealso: :meth:`init` :meth:`step` :meth:`control` :meth:`run_animation`
621
+ """
622
+
623
+ fig, ax = plt.subplots()
624
+
625
+ nframes = round(T / self.dt)
626
+ anim = animation.FuncAnimation(
627
+ fig=fig,
628
+ func=lambda i: self.step(animate=True, pause=False),
629
+ init_func=lambda: self.init(animate=True),
630
+ frames=nframes,
631
+ interval=self.dt * 1000,
632
+ blit=False,
633
+ repeat=False,
634
+ )
635
+ # anim._interval = self.dt*1000/2
636
+ # anim._repeat = True
637
+ ret = None
638
+ if format == "html":
639
+ ret = anim.to_html5_video() # convert to embeddable HTML5 animation
640
+ elif format == "jshtml":
641
+ ret = anim.to_jshtml() # convert to embeddable Javascript/HTML animation
642
+ elif format == "gif":
643
+ anim.save(
644
+ file, writer=animation.PillowWriter(fps=1 / self.dt)
645
+ ) # convert to GIF
646
+ ret = None
647
+ elif format == "mp4":
648
+ anim.save(
649
+ file, writer=animation.FFMpegWriter(fps=1 / self.dt)
650
+ ) # convert to mp4/H264
651
+ ret = None
652
+ elif format == None:
653
+ # return the anim object
654
+ return anim
655
+ else:
656
+ raise ValueError("unknown format")
657
+
658
+ if ret is not None and file is not None:
659
+ with open(file, "w") as f:
660
+ f.write(ret)
661
+ ret = None
662
+ plt.close(fig)
663
+ return ret
664
+
665
+ def init(self, x0=None, control=None, animate=True):
666
+ """
667
+ Initialize for simulation (superclass)
668
+
669
+ :param x0: Initial state, defaults to value given to Vehicle constructor
670
+ :type x0: array_like(3) or array_like(2)
671
+
672
+
673
+ Performs the following initializations:
674
+
675
+ #. Clears the state history
676
+ #. Set the private random number generator to initial value
677
+ #. Sets state :math:`x = x_0`
678
+ #. Sets previous velocity to zero
679
+ #. If a driver is attached, initialize it
680
+ #. If animation is enabled, initialize that
681
+
682
+ If animation is enabled by constructor and no animation object is given,
683
+ use a default ``VehiclePolygon("car")``
684
+
685
+ :seealso: :class:`VehicleAnimationBase` :meth:`run`
686
+ """
687
+ if x0 is not None:
688
+ self._x = base.getvector(x0, 3)
689
+ else:
690
+ self._x = self._x0.copy()
691
+
692
+ self._x_hist = []
693
+
694
+ if self._seed is not None:
695
+ self._random = np.random.default_rng(self._seed)
696
+
697
+ if control is not None:
698
+ # override control
699
+ self._control = control
700
+
701
+ if isinstance(self._control, VehicleDriverBase):
702
+ self._control.init()
703
+
704
+ self._t = 0
705
+ self._v_prev = [0]
706
+
707
+ # initialize the graphics
708
+ if animate and self._animation is not None:
709
+ # setup the plot
710
+ self._ax = base.plotvol2(self.workspace)
711
+
712
+ self._ax.set_xlabel("x")
713
+ self._ax.set_ylabel("y")
714
+ self._ax.set_aspect("equal")
715
+ try:
716
+ self._ax.figure.canvas.manager.set_window_title(
717
+ f"Robotics Toolbox for Python (Figure {self._ax.figure.number})"
718
+ )
719
+ except AttributeError:
720
+ pass
721
+
722
+ self._animation.add(ax=self._ax) # add vehicle animation to axis
723
+ self._timer = plt.figtext(0.85, 0.95, "") # display time counter
724
+
725
+ # initialize the driver
726
+ if isinstance(self._control, VehicleDriverBase):
727
+ self._control.init(ax=self._ax)
728
+
729
+ def plot(self, x):
730
+ self._animation.update(x)
731
+
732
+ def step(self, u=None, animate=True, pause=True):
733
+ r"""
734
+ Step simulator by one time step (superclass)
735
+
736
+ :return: odometry :math:`(\delta_d, \delta_\theta)`
737
+ :rtype: ndarray(2)
738
+
739
+ #. Obtain the vehicle control inputs
740
+ #. Integrate the vehicle state forward one timestep
741
+ #. Updates the stored state and state history
742
+ #. Update animation if enabled.
743
+ #. Returns the odometry
744
+
745
+ - ``veh.step((vel, steer))`` for a Bicycle vehicle model
746
+ - ``veh.step((vel, vel_diff))`` for a Unicycle vehicle model
747
+ - ``veh.step()`` as above but control is taken from the ``control``
748
+ attribute which might be a function or driver agent.
749
+
750
+
751
+ Example:
752
+
753
+ .. runblock:: pycon
754
+
755
+ >>> from roboticstoolbox import Bicycle
756
+ >>> bike = Bicycle() # default bicycle model
757
+ >>> bike.step((1, 0.2)) # one step: v=1, γ=0.2
758
+ >>> bike.x
759
+ >>> bike.step((1, 0.2)) # another step: v=1, γ=0.2
760
+ >>> bike.x
761
+
762
+ .. note:: Vehicle control input limits are applied.
763
+
764
+ :seealso: :func:`control`, :func:`update`, :func:`run`
765
+ """
766
+ # determine vehicle control
767
+ if u is not None:
768
+ u = self.eval_control(u, self._x)
769
+ else:
770
+ u = self.eval_control(self._control, self._x)
771
+
772
+ # update state (used to be function control() in MATLAB version)
773
+ xd = self._dt * self.deriv(self._x, u) # delta state
774
+
775
+ # update state vector
776
+ self._x += xd
777
+ self._x_hist.append(tuple(self._x))
778
+
779
+ # print('VEH', u, self.x)
780
+
781
+ # odometry comes from change in state vector
782
+ odo = np.r_[np.linalg.norm(xd[0:2]), xd[2]]
783
+
784
+ if self._V is not None:
785
+ odo += self.random.multivariate_normal((0, 0), self._V)
786
+
787
+ # do the graphics
788
+ if animate and self._animation:
789
+ self.plot(self._x)
790
+ # if self._timer is not None:
791
+ # self._timer.set_text(f"t = {self._t:.2f}")
792
+ _refresh_animation_frame(
793
+ self._ax.figure if self._ax else None, self._dt, pause
794
+ )
795
+ # plt.show(block=False)
796
+ # pass
797
+
798
+ self._t += self._dt
799
+
800
+ # be verbose
801
+ if self._verbose:
802
+ print(
803
+ f"{self._t:8.2f}: u=({u[0]:8.2f}, {u[1]:8.2f}), x=({self._x[0]:8.2f},"
804
+ f" {self._x[1]:8.2f}, {self._x[2]:8.2f})"
805
+ )
806
+
807
+ return odo
808
+
809
+ @property
810
+ def workspace(self):
811
+ """
812
+ Size of robot workspace (superclass)
813
+
814
+ :return: workspace bounds [xmin, xmax, ymin, ymax]
815
+ :rtype: ndarray(4)
816
+
817
+ Returns the bounds of the workspace as specified by constructor
818
+ option ``workspace``
819
+ """
820
+
821
+ # get workspace specified for Vehicle or from its driver
822
+ if self._workspace is not None:
823
+ return self._workspace
824
+ if self._control is not None and hasattr(self._control, "_workspace"):
825
+ return self._control._workspace
826
+
827
+ @property
828
+ def x(self):
829
+ r"""
830
+ Get vehicle state/configuration (superclass)
831
+
832
+ :return: Vehicle state :math:`(x, y, \theta)`
833
+ :rtype: ndarray(3)
834
+
835
+ :seealso: :meth:`q`
836
+ """
837
+ return self._x
838
+
839
+ @property
840
+ def q(self):
841
+ r"""
842
+ Get vehicle state/configuration (superclass)
843
+
844
+ :return: Vehicle state :math:`(x, y, \theta)`
845
+ :rtype: ndarray(3)
846
+
847
+ :seealso: :meth:`x`
848
+ """
849
+ return self._x
850
+
851
+ @property
852
+ def x0(self):
853
+ r"""
854
+ Get vehicle initial state/configuration (superclass)
855
+
856
+ :return: Vehicle state :math:`(x, y, \theta)`
857
+ :rtype: ndarray(3)
858
+
859
+ Set by :class:`VehicleBase` subclass constructor. The state is set to this value
860
+ at the beginning of each simulation run.
861
+
862
+ :seealso: :meth:`run`
863
+ """
864
+ return self._x0
865
+
866
+ @x0.setter
867
+ def x0(self, x0):
868
+ r"""
869
+ Set vehicle initial state/configuration (superclass)
870
+
871
+ :param x0: Vehicle state :math:`(x, y, \theta)`
872
+ :type x0: array_like(3)
873
+
874
+ The state is set to this value at the beginning of each simulation
875
+ run. Overrides the value set by :class:`VehicleBase` subclass constructor.
876
+
877
+ :seealso: :func:`run`
878
+ """
879
+ self._x0 = base.getvector(x0, 3)
880
+
881
+ @property
882
+ def random(self):
883
+ """
884
+ Get private random number generator
885
+
886
+ :return: NumPy random number generator
887
+ :rtype: :class:`numpy.random.Generator`
888
+
889
+ Has methods including:
890
+
891
+ - :meth:`integers(low, high, size, endpoint) <numpy.random.Generator.integers>`
892
+ - :meth:`random(size) <numpy.random.Generator.random>`
893
+ - :meth:`uniform(low, high, size) <numpy.random.Generator.uniform>`
894
+ - :meth:`normal(mean, std, size) <numpy.random.Generator.normal>`
895
+ - :meth:`multivariate_normal(mean, covar, size) <numpy.random.Generator.multivariate_normal>`
896
+
897
+ The generator is initialized with the seed provided at constructor
898
+ time every time :meth:`init` is called.
899
+
900
+ :seealso: :meth:`init` :func:`numpy.random.default_rng`
901
+ """
902
+ return self._random
903
+
904
+ @property
905
+ def x_hist(self):
906
+ """
907
+ Get vehicle state/configuration history (superclass)
908
+
909
+ :return: Vehicle state history
910
+ :rtype: ndarray(n,3)
911
+
912
+ The state :math:`(x, y, \theta)` at each time step resulting from a
913
+ simulation run, one row per timestep.
914
+
915
+ :seealso: :meth:`run`
916
+ """
917
+ return np.array(self._x_hist)
918
+
919
+ @property
920
+ def speed_max(self):
921
+ """
922
+ Get maximum speed of vehicle (superclass)
923
+
924
+ :return: maximum speed
925
+ :rtype: float
926
+
927
+ Set by :meth:`VehicleBase` subclass constructor.
928
+
929
+ :seealso: :meth:`accel_max` :meth:`steer_max` :meth:`u_limited`
930
+ """
931
+ return self._speed_max
932
+
933
+ @property
934
+ def accel_max(self):
935
+ """
936
+ Get maximum acceleration of vehicle (superclass)
937
+
938
+ :return: maximum acceleration
939
+ :rtype: float
940
+
941
+ Set by :meth:`VehicleBase` subclass constructor.
942
+
943
+ :seealso: :meth:`speed_max` :meth:`steer_max` :meth:`u_limited`
944
+ """
945
+ return self._accel_max
946
+
947
+ @property
948
+ def dt(self):
949
+ """
950
+ Get sample time (superclass)
951
+
952
+ :return: discrete time step for simulation
953
+ :rtype: float
954
+
955
+ Set by :meth:`VehicleBase` subclass constructor. Used by
956
+ :meth:`step` to update state.
957
+
958
+ :seealso: :meth:`run`
959
+ """
960
+ return self._dt
961
+
962
+ @property
963
+ def verbose(self):
964
+ """
965
+ Get verbosity (superclass)
966
+
967
+ :return: verbosity level
968
+ :rtype: bool
969
+
970
+ Set by :class:`VehicleBase` subclass constructor.
971
+ """
972
+ return self._verbose
973
+
974
+ @verbose.setter
975
+ def verbose(self, verbose):
976
+ """
977
+ Set verbosity (superclass)
978
+
979
+ :return: verbosity level
980
+ :rtype: bool
981
+
982
+ Set by :class:`VehicleBase` subclass constructor.
983
+ """
984
+ self._verbose = verbose
985
+
986
+ def stopsim(self):
987
+ """
988
+ Stop the simulation (superclass)
989
+
990
+ A control function can stop the simulation initated by the ``run``
991
+ method.
992
+
993
+ :seealso: :meth:`run`
994
+ """
995
+ self._stopsim = True
996
+
997
+ def plot_xy(self, *args, block=None, **kwargs):
998
+ """
999
+ Plot xy-path from history
1000
+
1001
+ :param block: block until plot dismissed, defaults to None
1002
+ :type block: bool, optional
1003
+ :param args: positional arguments passed to :meth:`~matplotlib.axes.Axes.plot`
1004
+ :param kwargs: keyword arguments passed to :meth:`~matplotlib.axes.Axes.plot`
1005
+
1006
+
1007
+ The :math:`(x,y)` trajectory from the simulation history is plotted as
1008
+ :math:`x` vs :math:`y`.
1009
+
1010
+ :seealso: :meth:`run` :meth:`plot_xyt`
1011
+ """
1012
+ if args is None and "color" not in kwargs:
1013
+ kwargs["color"] = "b"
1014
+ xyt = self.x_hist
1015
+ plt.plot(xyt[:, 0], xyt[:, 1], *args, **kwargs)
1016
+ if block is not None:
1017
+ plt.show(block=block)
1018
+
1019
+ def plot_xyt(self, block=None, **kwargs):
1020
+ """
1021
+ Plot configuration vs time from history
1022
+
1023
+ :param block: block until plot dismissed, defaults to False
1024
+ :type block: bool, optional
1025
+ :param args: positional arguments passed to :meth:`~matplotlib.axes.Axes.plot`
1026
+ :param kwargs: keyword arguments passed to :meth:`~matplotlib.axes.Axes.plot`
1027
+
1028
+ The :math:`(x,y, \theta)` trajectory from the simulation history is plotted
1029
+ against time.
1030
+
1031
+ :seealso: :meth:`run` :meth:`plot_xy`
1032
+ """
1033
+ xyt = self.x_hist
1034
+ t = np.arange(0, xyt.shape[0] * self._dt, self._dt)
1035
+ plt.plot(xyt[:, 0], xyt[:, :], **kwargs)
1036
+ plt.legend(["x", "y", "$\\theta$"])
1037
+ if block is not None:
1038
+ plt.show(block=block)
1039
+
1040
+
1041
+ # ========================================================================= #
1042
+
1043
+
1044
+ class Bicycle(VehicleBase):
1045
+ def __init__(self, L=1, steer_max=0.45 * pi, **kwargs):
1046
+ r"""
1047
+ Create bicycle kinematic model
1048
+
1049
+ :param L: wheel base, defaults to 1
1050
+ :type L: float, optional
1051
+ :param steer_max: maximum steering angle, defaults to :math:`0.45\pi`
1052
+ :type steer_max: float, optional
1053
+ :param kwargs: additional arguments passed to :class:`VehicleBase`
1054
+ constructor
1055
+
1056
+ Model the motion of a bicycle model with equations of motion given by:
1057
+
1058
+ .. math::
1059
+
1060
+ \dot{x} &= v \cos \theta \\
1061
+ \dot{y} &= v \sin \theta \\
1062
+ \dot{\theta} &= \frac{v}{L} \tan \gamma
1063
+
1064
+ where :math:`v` is the velocity in body frame x-direction, and
1065
+ :math:`\gamma` is the angle of the steered wheel.
1066
+
1067
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fx` meth:`Fv` :class:`VehicleBase`
1068
+ """
1069
+ super().__init__(**kwargs)
1070
+
1071
+ self._l = L
1072
+ self._steer_max = steer_max
1073
+
1074
+ def __str__(self):
1075
+
1076
+ s = super().__str__()
1077
+ s += (
1078
+ f"\n L={self._l}, steer_max={self._steer_max:g},"
1079
+ f" speed_max={self._speed_max:g}, accel_max={self._accel_max:g}"
1080
+ )
1081
+ return s
1082
+
1083
+ @property
1084
+ def l(self):
1085
+ """
1086
+ Vehicle wheelbase
1087
+
1088
+ :return: vehicle wheelbase
1089
+ :rtype: float
1090
+ """
1091
+ return self._l
1092
+
1093
+ @property
1094
+ def radius_min(self):
1095
+ r"""
1096
+ Vehicle turning radius
1097
+
1098
+ :return: radius of minimum possible turning circle
1099
+ :rtype: float
1100
+
1101
+ Minimum turning radius based on maximum steered wheel angle and wheelbase.
1102
+
1103
+ .. math::
1104
+ \frac{l}{\tan \gamma_{max}}
1105
+
1106
+ :seealso: :meth:`curvature_max`
1107
+ """
1108
+ return self.l / np.tan(self.steer_max)
1109
+
1110
+ @property
1111
+ def curvature_max(self):
1112
+ r"""
1113
+ Vehicle maximum path curvature
1114
+
1115
+ :return: maximum curvature
1116
+ :rtype: float
1117
+
1118
+ Maximum path curvature based on maximum steered wheel angle and wheelbase.
1119
+
1120
+ .. math::
1121
+ \frac{\tan \gamma_{max}}{l}
1122
+
1123
+ :seealso: :meth:`radius_min`
1124
+ """
1125
+ return 1.0 / self.radius_min
1126
+
1127
+ @property
1128
+ def steer_max(self):
1129
+ """
1130
+ Vehicle maximum steered wheel angle
1131
+
1132
+ :return: maximum angle
1133
+ :rtype: float
1134
+ """
1135
+ return self._steer_max
1136
+
1137
+ def deriv(self, x, u, limits=True):
1138
+ r"""
1139
+ Time derivative of state
1140
+
1141
+ :param x: vehicle state :math:`(x, y, \theta)`
1142
+ :type x: array_like(3)
1143
+ :param u: control input :math:`(v, \gamma)`
1144
+ :type u: array_like(2)
1145
+ :param limits: limits are applied to input, default True
1146
+ :type limits: bool
1147
+ :return: state derivative :math:`(\dot{x}, \dot{y}, \dot{\theta})`
1148
+ :rtype: ndarray(3)
1149
+
1150
+ Returns the time derivative of state (3x1) at the state ``x`` with velocity :math:`v`
1151
+ and steered wheel angle :math:`\gamma`
1152
+
1153
+ .. math::
1154
+ \dot{x} &= v \cos \theta \\
1155
+ \dot{y} &= v \sin \theta \\
1156
+ \dot{\theta} &= \frac{v}{L} \tan \gamma
1157
+
1158
+ If ``limits`` is True then speed, acceleration and steer-angle limits are
1159
+ applied to ``u``.
1160
+
1161
+ :seealso: :meth:`f`
1162
+ """
1163
+
1164
+ # unpack some variables
1165
+ theta = x[2]
1166
+
1167
+ if limits:
1168
+ u = self.u_limited(u)
1169
+ v = u[0]
1170
+ gamma = u[1]
1171
+
1172
+ return v * np.r_[cos(theta), sin(theta), tan(gamma) / self.l]
1173
+
1174
+ def u_limited(self, u):
1175
+ r"""
1176
+ Apply vehicle velocity, acceleration and steering limits
1177
+
1178
+ :param u: Desired vehicle inputs :math:`(v, \gamma)`
1179
+ :type u: array_like(2)
1180
+ :return: Allowable vehicle inputs :math:`(v, \gamma)`
1181
+ :rtype: ndarray(2)
1182
+
1183
+ Velocity and acceleration limits are applied to :math:`v` and
1184
+ steered wheel angle limits are applied to :math:`\gamma`.
1185
+ """
1186
+ # limit speed and steer angle
1187
+ ulim = np.array(u)
1188
+ ulim[0] = self.limits_va(u[0], self._v_prev)
1189
+ ulim[1] = np.clip(u[1], -self._steer_max, self._steer_max)
1190
+
1191
+ return ulim
1192
+
1193
+
1194
+ # ========================================================================= #
1195
+
1196
+
1197
+ class Unicycle(VehicleBase):
1198
+ def __init__(self, W=1, steer_max=np.inf, **kwargs):
1199
+ r"""
1200
+ Create unicycle kinematic model
1201
+
1202
+ :param W: vehicle width, defaults to 1
1203
+ :type W: float, optional
1204
+ :param steer_max: maximum turn rate
1205
+ :type steer_max: float
1206
+ :param kwargs: additional arguments passed to :class:`VehicleBase`
1207
+ constructor
1208
+
1209
+ Model the motion of a unicycle model with equations of motion given by:
1210
+
1211
+ .. math::
1212
+
1213
+ \dot{x} &= v \cos \theta \\
1214
+ \dot{y} &= v \sin \theta \\
1215
+ \dot{\theta} &= \omega
1216
+
1217
+ where :math:`v` is the velocity in body frame x-direction, and
1218
+ :math:`\omega` is the turn rate.
1219
+
1220
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fx` meth:`Fv` :class:`Vehicle`
1221
+ """
1222
+ super().__init__(**kwargs)
1223
+ self._W = W
1224
+ self._steer_max = steer_max
1225
+
1226
+ def __str__(self):
1227
+
1228
+ s = super().__str__()
1229
+ s += (
1230
+ f"\n W={self._W}, steer_max={self._steer_max:g},"
1231
+ f" vel_max={self._speed_max}, accel_max={self._accel_max}"
1232
+ )
1233
+ return s
1234
+
1235
+ def deriv(self, x, u, limits=True):
1236
+ r"""
1237
+ Time derivative of state
1238
+
1239
+ :param x: vehicle state :math:`(x, y, \theta)`
1240
+ :type x: array_like(3)
1241
+ :param u: control input :math:`(v, \omega)`
1242
+ :type u: array_like(2)
1243
+ :param limits: limits are applied to input, default True
1244
+ :type limits: bool
1245
+ :return: state derivative :math:`(\dot{x}, \dot{y}, \dot{\theta})`
1246
+ :rtype: ndarray(3)
1247
+
1248
+ Returns the time derivative of state (3x1) at the state ``x`` with velocity :math:`v`
1249
+ and turn rate :math:`\omega`
1250
+
1251
+ .. math::
1252
+ \dot{x} &= v \cos \theta \\
1253
+ \dot{y} &= v \sin \theta \\
1254
+ \dot{\theta} &= \omega
1255
+
1256
+ If ``limits`` is True then speed, acceleration and steer-angle limits are
1257
+ applied to ``u``.
1258
+
1259
+ :seealso: :meth:`f`
1260
+ """
1261
+ if limits:
1262
+ u = self.u_limited(u)
1263
+ # unpack some variables
1264
+ theta = x[2]
1265
+ v = u[0]
1266
+ vdiff = u[1]
1267
+
1268
+ return np.r_[v * cos(theta), v * sin(theta), vdiff / self._W]
1269
+
1270
+ def u_limited(self, u):
1271
+ r"""
1272
+ Apply vehicle velocity, acceleration and steering limits
1273
+
1274
+ :param u: Desired vehicle inputs :math:`(v, \omega)`
1275
+ :type u: array_like(2)
1276
+ :return: Allowable vehicle inputs :math:`(v, \omega)`
1277
+ :rtype: ndarray(2)
1278
+
1279
+ Velocity and acceleration limits are applied to :math:`v` and
1280
+ turn rate limits are applied to :math:`\omega`.
1281
+ """
1282
+
1283
+ # limit speed and steer angle
1284
+ ulim = np.array(u)
1285
+ ulim[0] = self.limits_va(u[0], self._v_prev)
1286
+ ulim[1] = np.maximum(-self._steer_max, np.minimum(self._steer_max, u[1]))
1287
+
1288
+ return ulim
1289
+
1290
+
1291
+ # ========================================================================= #
1292
+
1293
+
1294
+ class DiffSteer(Unicycle):
1295
+ def __init__(self, W=1, **kwargs):
1296
+ r"""
1297
+ Create differential steering kinematic model
1298
+
1299
+ :param W: vehicle width, defaults to 1
1300
+ :type W: float, optional
1301
+ :param kwargs: additional arguments passed to :class:`VehicleBase`
1302
+ constructor
1303
+
1304
+ Model the motion of a unicycle model with equations of motion given by:
1305
+
1306
+ .. math::
1307
+
1308
+ \dot{x} &= v \cos \theta \\
1309
+ \dot{y} &= v \sin \theta \\
1310
+ \dot{\theta} &= \omega
1311
+
1312
+ where :math:`v = (v_R + v_L)/2` is the velocity in body frame x-direction, and
1313
+ :math:`\omega = (v_R - v_L)/W` is the turn rate.
1314
+
1315
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fx` meth:`Fv` :class:`Vehicle`
1316
+ """
1317
+ super().__init__(**kwargs)
1318
+ self._W = W
1319
+ self._v_prev_L = [0]
1320
+ self._v_prev_R = [0]
1321
+
1322
+ def __str__(self):
1323
+
1324
+ s = super().__str__()
1325
+ return s
1326
+
1327
+ def init(self, **kwargs):
1328
+ super().init(**kwargs)
1329
+ self._v_prev_L = [0]
1330
+ self._v_prev_R = [0]
1331
+
1332
+ def u_limited(self, u):
1333
+ r"""
1334
+ Apply vehicle velocity and acceleration limits
1335
+
1336
+ :param u: Desired vehicle inputs :math:`(v_L, v_R)`
1337
+ :type u: array_like(2)
1338
+ :return: Allowable vehicle inputs :math:`(v_L, v_R)`
1339
+ :rtype: ndarray(2)
1340
+
1341
+ Velocity and acceleration limits are applied to :math:`v` and
1342
+ turn rate limits are applied to :math:`\omega`.
1343
+ """
1344
+
1345
+ # limit speed and acceleration of each wheel/track
1346
+ ulim = np.array(u)
1347
+ ulim[0] = self.limits_va(u[0], self._v_prev_L)
1348
+ ulim[1] = self.limits_va(u[1], self._v_prev_R)
1349
+
1350
+ return ulim
1351
+
1352
+ def deriv(self, x, u, limits=True):
1353
+ r"""
1354
+ Time derivative of state
1355
+
1356
+ :param x: vehicle state :math:`(x, y, \theta)`
1357
+ :type x: array_like(3)
1358
+ :param u: Desired vehicle inputs :math:`(v_L, v_R)`
1359
+ :type u: array_like(2)
1360
+ :param limits: limits are applied to input, default True
1361
+ :type limits: bool
1362
+ :return: state derivative :math:`(\dot{x}, \dot{y}, \dot{\theta})`
1363
+ :rtype: ndarray(3)
1364
+
1365
+ Returns the time derivative of state (3x1) at the state ``x`` with left and
1366
+ right wheel speeds ``u``.
1367
+
1368
+ .. math::
1369
+
1370
+ \dot{x} &= v \cos \theta \\
1371
+ \dot{y} &= v \sin \theta \\
1372
+ \dot{\theta} &= \omega
1373
+
1374
+ where :math:`v = (v_R + v_L)/2` is the velocity in body frame x-direction, and
1375
+ :math:`\omega = (v_R - v_L)/W` is the turn rate.
1376
+
1377
+ If ``limits`` is True then speed and acceleration limits are applied to the
1378
+ wheel speeds ``u``.
1379
+
1380
+ :seealso: :meth:`f`
1381
+ """
1382
+ if limits:
1383
+ u = self.u_limited(u)
1384
+ # unpack some variables
1385
+ theta = x[2]
1386
+ vleft = u[0]
1387
+ vright = u[1]
1388
+
1389
+ # convert wheel speeds to forward and differential velocity
1390
+ v = (vright + vleft) / 2.0
1391
+ vdiff = vright - vleft
1392
+
1393
+ return np.r_[v * cos(theta), v * sin(theta), vdiff / self._W]
1394
+
1395
+
1396
+ # ========================================================================= #
1397
+
1398
+
1399
+ class DiffSteerTrailer(Unicycle):
1400
+ def __init__(self, W=1, L1=1, L2=1, x0=[0.0, 0, 0, 0], trailer=None, **kwargs):
1401
+ r"""
1402
+ Create differential steering kinematic model with trailer
1403
+
1404
+ :param W: vehicle width, defaults to 1
1405
+ :type W: float, optional
1406
+ :param L1: distance from rear axle to trailer hitch, defaults to 1
1407
+ :type L1: float, optional
1408
+ :param L2: distance from trailer hitch to trailer axle, defaults to 1
1409
+ :type L2: float, optional
1410
+ :param kwargs: additional arguments passed to :class:`VehicleBase`
1411
+ constructor
1412
+
1413
+ Model the motion of a unicycle model with equations of motion given by:
1414
+
1415
+ .. math::
1416
+
1417
+ \dot{x} &= v \cos \theta \\
1418
+ \dot{y} &= v \sin \theta \\
1419
+ \dot{\theta} &= \omega \\
1420
+ \dot{\delta} &= \frac{v}{L_1} \sin(\theta - \delta)
1421
+
1422
+ where :math:`v = (v_R + v_L)/2` is the velocity in body frame x-direction,
1423
+ :math:`\omega = (v_R - v_L)/W` is the turn rate, and :math:`\delta` is the
1424
+ hitch angle.
1425
+
1426
+ :seealso: :meth:`f` :meth:`deriv` :meth:`Fx` meth:`Fv` :class:`Vehicle`
1427
+ """
1428
+ super().__init__(**kwargs)
1429
+ self._x0 = np.r_[x0]
1430
+ self._x = x0.copy()
1431
+ self._W = W
1432
+ self._L1 = L1
1433
+ self._L2 = L2
1434
+ self._animation_trailer = trailer
1435
+ self._v_prev_L = [0]
1436
+ self._v_prev_R = [0]
1437
+
1438
+ def __str__(self):
1439
+
1440
+ s = super().__str__()
1441
+ return s
1442
+
1443
+ def init(self, **kwargs):
1444
+ super().init(**kwargs)
1445
+ self._animation_trailer.add(ax=self._ax) # add trailer animation to axis
1446
+
1447
+ def plot(self, x):
1448
+ self._animation.update(x[:3]) # show robot
1449
+
1450
+ theta = x[2]
1451
+ eta = theta + x[3]
1452
+ Q = (
1453
+ x[:2]
1454
+ - self._L1 * np.r_[cos(theta), sin(theta)]
1455
+ - self._L2 * np.r_[cos(eta), sin(eta)]
1456
+ )
1457
+ self._animation_trailer.update(np.concatenate((Q, [eta]))) # show trailer
1458
+
1459
+ def deriv(self, x, u, limits=True):
1460
+ r"""
1461
+ Time derivative of state
1462
+
1463
+ :param x: vehicle state :math:`(x, y, \theta, \delta)`
1464
+ :type x: array_like(3)
1465
+ :param u: Desired vehicle inputs :math:`(v_L, v_R)`
1466
+ :type u: array_like(2)
1467
+ :param limits: limits are applied to input, default True
1468
+ :type limits: bool
1469
+ :return: state derivative :math:`(\dot{x}, \dot{y}, \dot{\theta})`
1470
+ :rtype: ndarray(3)
1471
+
1472
+ Returns the time derivative of state (4x1) at the state ``x`` with left and
1473
+ right wheel speeds ``u``.
1474
+
1475
+ .. math::
1476
+
1477
+ \dot{x} &= v \cos \theta \\
1478
+ \dot{y} &= v \sin \theta \\
1479
+ \dot{\theta} &= \omega \\
1480
+ \dot{\delta} &= \frac{v}{L_1} \sin(\theta - \delta)
1481
+
1482
+ where :math:`v = (v_R + v_L)/2` is the velocity in body frame x-direction, and
1483
+ :math:`\omega = (v_R - v_L)/W` is the turn rate.
1484
+
1485
+ If ``limits`` is True then speed and acceleration limits are applied to the
1486
+ wheel speeds ``u``.
1487
+
1488
+ :seealso: :meth:`f`
1489
+ """
1490
+ if limits:
1491
+ u = self.u_limited(u)
1492
+ # unpack some variables
1493
+ theta = x[2]
1494
+ delta = x[3]
1495
+ vleft = u[0]
1496
+ vright = u[1]
1497
+
1498
+ # convert wheel speeds to forward and differential velocity
1499
+ v = (vright + vleft) / 2.0
1500
+ vdiff = vright - vleft
1501
+
1502
+ # xd yd thetad
1503
+ X = np.r_[v * cos(theta), v * sin(theta), vdiff / self._W, 0]
1504
+
1505
+ hx = X[0] + self._L1 * X[2] * sin(theta)
1506
+ hy = X[1] - self._L1 * X[2] * cos(theta)
1507
+
1508
+ # trailer kino-dynamics
1509
+ if X[2] > 0.01:
1510
+ pass
1511
+ eta = theta + delta
1512
+ etad = (hy * cos(eta) - hx * sin(eta)) / self._L2
1513
+ X[3] = etad - X[2] # deltad = etad - thetad
1514
+ print(X[2], eta, etad)
1515
+
1516
+ return X
1517
+
1518
+
1519
+ # composite of vehicle + trailers
1520
+ class VehicleTrailer(VehicleBase):
1521
+ def __init__(self, vehicle, trailers, x0=None, verbose=False):
1522
+ r"""
1523
+ Create a kinematic system with a vehicle with one or more trailers
1524
+
1525
+ :param vehicle: vehicle model
1526
+ :type vehicle: :class:`VehicleBase` such as `Bicycle`, `Unicycle` or `DiffSteer`
1527
+ :param trailers: trailer model or list of trailer models
1528
+ :type trailers: :class:`Trailer` or list of :class:`Trailer`
1529
+ :param x0: initial state, defaults to [0, 0, 0, 0, ...]
1530
+ :type x0: array_like(3+m) where `m` is the number of trailers
1531
+ :param kwargs: additional arguments passed to :class:`VehicleBase`
1532
+ constructor
1533
+
1534
+ The vehicle motion model is defined by `vehicle`. The trailers have car-like
1535
+ kinematics with a lateral non-sliding constraint. Each trailer is connected to
1536
+ the preceding one (vehicle or trailer) by a hitch defined by two lengths `L1` and `L2`.
1537
+
1538
+ The state of the system is :math:`(x, y, \theta, \delta_i, \cdots)` where
1539
+ :math:`(x,y)` is the position of the centre of vehicle, :math:`\theta` is the
1540
+ heading angle, and :math:`\delta_i` is the hitch angle for the `i`-th trailer.
1541
+
1542
+ :seealso: :class:`VehicleBase` :class:`Trailer`
1543
+ """
1544
+ self.vehicle = vehicle
1545
+ if isinstance(trailers, Trailer):
1546
+ self.trailers = [trailers]
1547
+ else:
1548
+ self.trailers = trailers
1549
+
1550
+ if x0 is None:
1551
+ x0 = np.zeros((3 + len(self.trailers),))
1552
+ self._x0 = x0
1553
+ self._verbose = verbose
1554
+
1555
+ def __str__(self):
1556
+ """
1557
+ Pretty print the vehicle and trailers
1558
+ """
1559
+
1560
+ s = str(self.vehicle)
1561
+ for k, trailer in enumerate(self.trailers):
1562
+ s += f"\n + trailer {k}: L1={trailer._L1}, L2={trailer._L2}"
1563
+ return s
1564
+
1565
+ def polygon(self, q):
1566
+ r"""
1567
+ Bounding polygons at vehicle configuration
1568
+
1569
+ :param q: vehicle configuration :math:`(x, y, \theta, \delta_i, \cdots)`
1570
+ :type q: array_like(3+m) where `m` is the number of trailers
1571
+ :return: list of bounding polygons of vehicle at configuration ``q``
1572
+ :rtype: :class:`~spatialmath.geom2d.Polygon2`
1573
+
1574
+ The bounding polygon of the vehicle is returned for the configuration
1575
+ ``q``. Can be used for collision checking using the :meth:`~spatialmath.geom2d.Polygon2.intersects`
1576
+ method.
1577
+
1578
+ :seealso: :class:`~spatialmath.geom2d.Polygon2`
1579
+ """
1580
+ polygons = [self.vehicle._polygon.transformed(SE2(q))]
1581
+
1582
+ for trailer, delta in zip(self.trailers, q[3:]):
1583
+ polygons.append(trailer._polygon.transformed(SE2(delta)))
1584
+
1585
+ return polygons
1586
+
1587
+ def init(self, **kwargs):
1588
+ self.vehicle.init(**kwargs)
1589
+ self._x = self._x0
1590
+ self._t = 0
1591
+ self._x_hist = []
1592
+
1593
+ for trailer in self.trailers:
1594
+ if trailer._animation is not None:
1595
+ trailer._animation.add(
1596
+ ax=self.vehicle._ax
1597
+ ) # add trailer animation to axis
1598
+
1599
+ @property
1600
+ def dt(self):
1601
+ return self.vehicle.dt
1602
+
1603
+ def run(self, T=10, x0=None, control=None, animate=True):
1604
+ r"""
1605
+ Simulate motion of vehicle and m trailers
1606
+
1607
+ :param T: Simulation time in seconds, defaults to 10
1608
+ :type T: float, optional
1609
+ :param x0: Initial state, defaults to value given to :class:`VehicleTrailer` constructor
1610
+ :type x0: array_like(3+m) where `m` is the number of trailers, optional
1611
+ :param control: vehicle control inputs, defaults to None
1612
+ :type control: array_like(2), callable, driving agent
1613
+ :param animate: Enable graphical animation of vehicle, defaults to False
1614
+ :type animate: bool, optional
1615
+ :return: State trajectory, each row is :math:`(x,y,\theta, \delta_i, \cdots)`.
1616
+ :rtype: ndarray(n,3)
1617
+
1618
+ Runs the vehicle and trailer simulation for ``T`` seconds and optionally plots
1619
+ an animation. The method :meth:`step` performs each time step.
1620
+
1621
+ The control inputs to the vehicle are provided by ``control`` which can be:
1622
+
1623
+ * a constant tuple as the control inputs to the vehicle
1624
+ * a function called as ``f(vehicle, t, x)`` that returns a tuple
1625
+ * an interpolator called as ``f(t)`` that returns a tuple, see
1626
+ SciPy interp1d
1627
+ * a driver agent, subclass of :class:`VehicleDriverBase`
1628
+
1629
+ This is evaluated by :meth:`eval_control` which applies velocity,
1630
+ acceleration and steering limits.
1631
+
1632
+ The simulation can be stopped prematurely by the control function
1633
+ calling :meth:`stopsim`.
1634
+
1635
+ .. note::
1636
+ * the simulation is fixed-time step with the step given by the ``dt``
1637
+ attribute set by the constructor.
1638
+ * integration uses rectangular integration.
1639
+
1640
+ :seealso: :meth:`init` :meth:`step` :meth:`control` :meth:`run_animation`
1641
+ """
1642
+
1643
+ self.init(control=control, animate=animate, x0=x0)
1644
+
1645
+ for i in range(round(T / self.dt)):
1646
+ self.step(animate=animate)
1647
+
1648
+ # check for user requested stop
1649
+ if self.vehicle._stopsim:
1650
+ print("USER REEQUESTED STOP AT time", self._t)
1651
+ break
1652
+
1653
+ return self.x_hist
1654
+
1655
+ def step(self, u=None, animate=True, pause=True):
1656
+ r"""
1657
+ Step simulator by one time step
1658
+
1659
+ #. Obtain the vehicle control inputs
1660
+ #. Integrate the vehicle state forward one timestep
1661
+ #. Updates the stored state and state history
1662
+ #. Update animation if enabled.
1663
+
1664
+ Example:
1665
+
1666
+ .. runblock:: pycon
1667
+
1668
+ >>> from roboticstoolbox import Bicycle
1669
+ >>> vt = VehicleTrailer(Bicycle(), Trailer()) # default bicycle model
1670
+ >>> vt.step((1, 0.2)) # one step: v=1, γ=0.2
1671
+ >>> vt.x
1672
+ >>> vt.run(5) # run simulatin for 5 seconds
1673
+
1674
+ .. note:: Vehicle control input limits are applied.
1675
+
1676
+ :seealso: :func:`control`, :func:`update`, :func:`run`
1677
+ """
1678
+ # determine vehicle control
1679
+ if u is not None:
1680
+ u = self.eval_control(u, self._x)
1681
+ else:
1682
+ u = self.vehicle.eval_control(self.vehicle._control, self._x)
1683
+
1684
+ # update state (used to be function control() in MATLAB version)
1685
+ xd = self.dt * self.deriv(self._x, u) # delta state
1686
+
1687
+ # update state vector
1688
+ self._x += xd
1689
+ self.vehicle._x = self._x[:3]
1690
+ self._x_hist.append(tuple(self._x))
1691
+
1692
+ # print('VEH', u, self.x)
1693
+
1694
+ # do the graphics
1695
+ if animate and self.vehicle._animation:
1696
+ x = self._x[:3].copy()
1697
+ self.vehicle._animation.update(x) # show robot
1698
+
1699
+ for trailer, delta in zip(self.trailers, self._x[3:]):
1700
+ x[:2] -= (
1701
+ trailer._L1 * np.r_[cos(x[2]), sin(x[2])]
1702
+ + trailer._L2 * np.r_[cos(x[2] + delta), sin(x[2] + delta)]
1703
+ )
1704
+ x[2] += delta
1705
+ trailer._animation.update(x) # show trailer
1706
+ # if self._timer is not None:
1707
+ # self._timer.set_text(f"t = {self._t:.2f}")
1708
+ _refresh_animation_frame(
1709
+ self.vehicle._ax.figure if self.vehicle._ax else None, self.dt, pause
1710
+ )
1711
+ # plt.show(block=False)
1712
+ # pass
1713
+
1714
+ self._t += self.dt
1715
+ self.vehicle._t = self._t
1716
+
1717
+ # be verbose
1718
+ if self._verbose:
1719
+ print(
1720
+ f"{self._t:8.2f}: u=({u[0]:8.2f}, {u[1]:8.2f}), x=({self._x[0]:8.2f},"
1721
+ f" {self._x[1]:8.2f}, {self._x[2]:8.2f})"
1722
+ )
1723
+
1724
+ def plot(self, x):
1725
+ self._animation.update(x[:3]) # show robot
1726
+
1727
+ theta = x[2]
1728
+ eta = theta + x[3]
1729
+ Q = (
1730
+ x[:2]
1731
+ - self._L1 * (cos(theta), sin(theta))
1732
+ - self._L2 * (cos(eta), sin(eta))
1733
+ )
1734
+ self._animation_trailer.update(np.concatenate((Q, [eta]))) # show trailer
1735
+
1736
+ def deriv(self, x, u, limits=True):
1737
+ r"""
1738
+ Time derivative of state
1739
+
1740
+ :param x: vehicle + trailer state :math:`(x, y, \theta, \delta_i, \cdots)`
1741
+ :type x: array_like(3+m) where `m` is the number of trailers
1742
+ :param u: Desired vehicle inputs, meaning depends on vehicle type
1743
+ :type u: array_like()
1744
+ :param limits: limits are applied to input, default True
1745
+ :type limits: bool
1746
+ :return: state derivative :math:`(\dot{x}, \dot{y}, \dot{\theta}, \dot{\delta}_i, \cdots)`
1747
+ :rtype: ndarray(3)
1748
+
1749
+ Returns the time derivative of state (3+m) at the state ``x`` with left and
1750
+ right wheel speeds ``u``.
1751
+
1752
+ If the velocity of the lead vehicle is :math:`(\dot{x}_l, \dot{y}_l, \dot{\theta}_l)`
1753
+ then the velocity of the hitch point is:
1754
+
1755
+ .. math::
1756
+
1757
+ \dot{x}_h &= \dot{x}_l + \ell_1 \dot{theta}_l \sin \theta_l \\
1758
+ \dot{y}_h &= \dot{y}_l - \ell_1 \dot{theta}_l \cos \theta_l \\
1759
+
1760
+ and the change of heading angle of the follower is:
1761
+
1762
+ .. math::
1763
+
1764
+ \dot{theta}_f = \frac{\dot{y}_h \cos(\theta_f - \delta_f) - \dot{x}_h \sin(\theta_f - \delta_f)}{\ell_2}
1765
+
1766
+ and the change of the hitch angle is
1767
+
1768
+ .. math::
1769
+
1770
+ \dot{\delta} = \dot{theta}_f - \dot{theta}_l
1771
+
1772
+ If ``limits`` is True then speed and acceleration limits are applied to the
1773
+ wheel speeds ``u``.
1774
+
1775
+ :seealso: :meth:`VehicleBas.f`
1776
+ """
1777
+ dx = self.vehicle.deriv(x[:3], u, limits)
1778
+
1779
+ # velocity and orientation of vehicle/trailer before
1780
+ xd = dx[0]
1781
+ yd = dx[1]
1782
+ thetad = dx[2]
1783
+ theta = x[2]
1784
+
1785
+ for trailer, delta in zip(self.trailers, x[3:]):
1786
+ # hitch point velocity
1787
+ hx = xd + trailer._L1 * thetad * sin(theta)
1788
+ hy = yd - trailer._L1 * thetad * cos(theta)
1789
+
1790
+ eta = theta + delta
1791
+ etad = (hy * cos(eta) - hx * sin(eta)) / trailer._L2
1792
+ deltad = etad - thetad # hitch angle velocity
1793
+
1794
+ # print(X[2], eta, etad)
1795
+ dx = np.concatenate((dx, [deltad])) # append to derivative vector
1796
+
1797
+ # compute velocity of trailer's rear axle midpoint
1798
+ xd = hx + etad * trailer._L2 * sin(eta)
1799
+ yd = hy - etad * trailer._L2 * cos(eta)
1800
+ thetad = etad
1801
+
1802
+ return dx
1803
+
1804
+
1805
+ if __name__ == "__main__":
1806
+ from roboticstoolbox import RandomPath
1807
+
1808
+ import roboticstoolbox as rtb
1809
+ import time
1810
+
1811
+ def steering(v, t, x):
1812
+ speed = (0.5, 0.5)
1813
+ if 3 <= t < 5:
1814
+ speed = (0.4, 0.6)
1815
+ elif 5 <= t < 7:
1816
+ speed = (0.6, 0.4)
1817
+
1818
+ return speed
1819
+
1820
+ a = rtb.VehiclePolygon(shape="car", color="blue")
1821
+ t = rtb.VehiclePolygon(shape="box", color="red")
1822
+ veh = DiffSteer(animation=a, control=steering, workspace=10)
1823
+ vt = VehicleTrailer(veh, Trailer(L1=1, L2=2, animation=t))
1824
+ print(vt)
1825
+ print(vt.deriv([0, 0, 0, 0], [1, 1]))
1826
+ vt.run(10)
1827
+ print(veh.x_hist)
1828
+
1829
+ # a = rtb.VehiclePolygon(shape="car", color="blue")
1830
+ # t = rtb.VehiclePolygon(shape="car", color="red")
1831
+ # veh = DiffSteerTrailer(animation=a, trailer=t, workspace=10)
1832
+ # veh.control = control
1833
+ # time.sleep(5)
1834
+ # veh.run(10)
1835
+ # print(veh.x_hist)
1836
+
1837
+ # a = rtb.VehicleMarker(marker="s", markerfacecolor="b")
1838
+ # veh = rtb.Bicycle(animation=a, workspace=10)
1839
+ # veh.control = (4, 0.5)
1840
+ # veh.run(20)
1841
+
1842
+ # V = np.eye(2) * 0.001
1843
+ # robot = Bicycle(covar=V, animation="car")
1844
+ # odo = robot.step((1, 0.3), animate=False)
1845
+
1846
+ # robot.control = RandomPath(workspace=10)
1847
+
1848
+ # # robot.run(T=10, animate=True)
1849
+ # # plt.show(block=True)
1850
+
1851
+ # anim = robot.run_animation(T=10, format="html", file="veh.html")
1852
+
1853
+ # anim.save("veh.mp4", writer=animation.FFMpegWriter(fps=1/robot.dt)) # convert to mp4/H264
1854
+ # with open("veh.html", "w") as f:
1855
+ # f.write(anim.to_html5_video())
1856
+
1857
+ # from math import pi
1858
+
1859
+ # V = np.diag(np.r_[0.02, 0.5 * pi / 180] ** 2)
1860
+
1861
+ # v = VehiclePolygon()
1862
+ # # v = VehicleIcon('greycar2', scale=2, rotation=90)
1863
+
1864
+ # veh = Bicycle(covar=V, animation=v, control=RandomPath(10), verbose=False)
1865
+ # print(veh)
1866
+
1867
+ # odo = veh.step(1, 0.3)
1868
+ # print(odo)
1869
+
1870
+ # print(veh.x)
1871
+
1872
+ # print(veh.f([0, 0, 0], odo))
1873
+
1874
+ # def control(v, t, x):
1875
+ # goal = (6,6)
1876
+ # goal_heading = atan2(goal[1]-x[1], goal[0]-x[0])
1877
+ # d_heading = base.angdiff(goal_heading, x[2])
1878
+ # v.stopif(base.norm(x[0:2] - goal) < 0.1)
1879
+
1880
+ # return (1, d_heading)
1881
+
1882
+ # veh.control=RandomPath(10)
1883
+ # p = veh.run(1000, plot=True)
1884
+ # # plt.show()
1885
+ # print(p)
1886
+
1887
+ # veh.plot_xyt_t()
1888
+ # veh.plot(p)
1889
+
1890
+ # t, x = veh.path(5, u=control)
1891
+ # print(t)
1892
+
1893
+ # fig, ax = plt.subplots()
1894
+
1895
+ # ax.set_xlim(-5, 5)
1896
+ # ax.set_ylim(-5, 5)
1897
+
1898
+ # v = VehicleAnimation.Polygon(shape='triangle', maxdim=0.1, color='r')
1899
+ # v = VehicleAnimation.Icon('car3.png', maxdim=2, centre=[0.3, 0.5])
1900
+ # v = VehicleAnimation.Icon('/Users/corkep/Dropbox/code/robotics-toolbox-python/roboticstoolbox/data/car1.png', maxdim=2, centre=[0.3, 0.5])
1901
+ # v = VehicleAnimation.icon('car3.png', maxdim=2, centre=[0.3, 0.5])
1902
+ # v = VehicleAnimation.marker()
1903
+ # v.start()
1904
+ # plt.grid(True)
1905
+ # # plt.axis('equal')
1906
+
1907
+ # for theta in np.linspace(0, 2 * np.pi, 100):
1908
+ # v.update([0, 0, theta])
1909
+ # plt.pause(0.1)