mink 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. mink/.mypy_cache/.gitignore +2 -0
  2. mink/.mypy_cache/3.12/@plugins_snapshot.json +1 -0
  3. mink/.mypy_cache/3.12/__future__.data.json +1 -0
  4. mink/.mypy_cache/3.12/__future__.meta.json +1 -0
  5. mink/.mypy_cache/3.12/_ast.data.json +1 -0
  6. mink/.mypy_cache/3.12/_ast.meta.json +1 -0
  7. mink/.mypy_cache/3.12/_codecs.data.json +1 -0
  8. mink/.mypy_cache/3.12/_codecs.meta.json +1 -0
  9. mink/.mypy_cache/3.12/_collections_abc.data.json +1 -0
  10. mink/.mypy_cache/3.12/_collections_abc.meta.json +1 -0
  11. mink/.mypy_cache/3.12/_ctypes.data.json +1 -0
  12. mink/.mypy_cache/3.12/_ctypes.meta.json +1 -0
  13. mink/.mypy_cache/3.12/_thread.data.json +1 -0
  14. mink/.mypy_cache/3.12/_thread.meta.json +1 -0
  15. mink/.mypy_cache/3.12/_typeshed/__init__.data.json +1 -0
  16. mink/.mypy_cache/3.12/_typeshed/__init__.meta.json +1 -0
  17. mink/.mypy_cache/3.12/_warnings.data.json +1 -0
  18. mink/.mypy_cache/3.12/_warnings.meta.json +1 -0
  19. mink/.mypy_cache/3.12/abc.data.json +1 -0
  20. mink/.mypy_cache/3.12/abc.meta.json +1 -0
  21. mink/.mypy_cache/3.12/array.data.json +1 -0
  22. mink/.mypy_cache/3.12/array.meta.json +1 -0
  23. mink/.mypy_cache/3.12/ast.data.json +1 -0
  24. mink/.mypy_cache/3.12/ast.meta.json +1 -0
  25. mink/.mypy_cache/3.12/builtins.data.json +1 -0
  26. mink/.mypy_cache/3.12/builtins.meta.json +1 -0
  27. mink/.mypy_cache/3.12/codecs.data.json +1 -0
  28. mink/.mypy_cache/3.12/codecs.meta.json +1 -0
  29. mink/.mypy_cache/3.12/collections/__init__.data.json +1 -0
  30. mink/.mypy_cache/3.12/collections/__init__.meta.json +1 -0
  31. mink/.mypy_cache/3.12/collections/abc.data.json +1 -0
  32. mink/.mypy_cache/3.12/collections/abc.meta.json +1 -0
  33. mink/.mypy_cache/3.12/contextlib.data.json +1 -0
  34. mink/.mypy_cache/3.12/contextlib.meta.json +1 -0
  35. mink/.mypy_cache/3.12/ctypes/__init__.data.json +1 -0
  36. mink/.mypy_cache/3.12/ctypes/__init__.meta.json +1 -0
  37. mink/.mypy_cache/3.12/dataclasses.data.json +1 -0
  38. mink/.mypy_cache/3.12/dataclasses.meta.json +1 -0
  39. mink/.mypy_cache/3.12/datetime.data.json +1 -0
  40. mink/.mypy_cache/3.12/datetime.meta.json +1 -0
  41. mink/.mypy_cache/3.12/email/__init__.data.json +1 -0
  42. mink/.mypy_cache/3.12/email/__init__.meta.json +1 -0
  43. mink/.mypy_cache/3.12/email/charset.data.json +1 -0
  44. mink/.mypy_cache/3.12/email/charset.meta.json +1 -0
  45. mink/.mypy_cache/3.12/email/contentmanager.data.json +1 -0
  46. mink/.mypy_cache/3.12/email/contentmanager.meta.json +1 -0
  47. mink/.mypy_cache/3.12/email/errors.data.json +1 -0
  48. mink/.mypy_cache/3.12/email/errors.meta.json +1 -0
  49. mink/.mypy_cache/3.12/email/header.data.json +1 -0
  50. mink/.mypy_cache/3.12/email/header.meta.json +1 -0
  51. mink/.mypy_cache/3.12/email/message.data.json +1 -0
  52. mink/.mypy_cache/3.12/email/message.meta.json +1 -0
  53. mink/.mypy_cache/3.12/email/policy.data.json +1 -0
  54. mink/.mypy_cache/3.12/email/policy.meta.json +1 -0
  55. mink/.mypy_cache/3.12/enum.data.json +1 -0
  56. mink/.mypy_cache/3.12/enum.meta.json +1 -0
  57. mink/.mypy_cache/3.12/genericpath.data.json +1 -0
  58. mink/.mypy_cache/3.12/genericpath.meta.json +1 -0
  59. mink/.mypy_cache/3.12/importlib/__init__.data.json +1 -0
  60. mink/.mypy_cache/3.12/importlib/__init__.meta.json +1 -0
  61. mink/.mypy_cache/3.12/importlib/abc.data.json +1 -0
  62. mink/.mypy_cache/3.12/importlib/abc.meta.json +1 -0
  63. mink/.mypy_cache/3.12/importlib/machinery.data.json +1 -0
  64. mink/.mypy_cache/3.12/importlib/machinery.meta.json +1 -0
  65. mink/.mypy_cache/3.12/importlib/metadata/__init__.data.json +1 -0
  66. mink/.mypy_cache/3.12/importlib/metadata/__init__.meta.json +1 -0
  67. mink/.mypy_cache/3.12/importlib/metadata/_meta.data.json +1 -0
  68. mink/.mypy_cache/3.12/importlib/metadata/_meta.meta.json +1 -0
  69. mink/.mypy_cache/3.12/importlib/readers.data.json +1 -0
  70. mink/.mypy_cache/3.12/importlib/readers.meta.json +1 -0
  71. mink/.mypy_cache/3.12/importlib/resources/__init__.data.json +1 -0
  72. mink/.mypy_cache/3.12/importlib/resources/__init__.meta.json +1 -0
  73. mink/.mypy_cache/3.12/importlib/resources/abc.data.json +1 -0
  74. mink/.mypy_cache/3.12/importlib/resources/abc.meta.json +1 -0
  75. mink/.mypy_cache/3.12/io.data.json +1 -0
  76. mink/.mypy_cache/3.12/io.meta.json +1 -0
  77. mink/.mypy_cache/3.12/logging/__init__.data.json +1 -0
  78. mink/.mypy_cache/3.12/logging/__init__.meta.json +1 -0
  79. mink/.mypy_cache/3.12/math.data.json +1 -0
  80. mink/.mypy_cache/3.12/math.meta.json +1 -0
  81. mink/.mypy_cache/3.12/mink/limits/limit.data.json +1 -0
  82. mink/.mypy_cache/3.12/mink/limits/limit.meta.json +1 -0
  83. mink/.mypy_cache/3.12/mmap.data.json +1 -0
  84. mink/.mypy_cache/3.12/mmap.meta.json +1 -0
  85. mink/.mypy_cache/3.12/numpy/__init__.data.json +1 -0
  86. mink/.mypy_cache/3.12/numpy/__init__.meta.json +1 -0
  87. mink/.mypy_cache/3.12/numpy/_pytesttester.data.json +1 -0
  88. mink/.mypy_cache/3.12/numpy/_pytesttester.meta.json +1 -0
  89. mink/.mypy_cache/3.12/numpy/_typing/__init__.data.json +1 -0
  90. mink/.mypy_cache/3.12/numpy/_typing/__init__.meta.json +1 -0
  91. mink/.mypy_cache/3.12/numpy/_typing/_add_docstring.data.json +1 -0
  92. mink/.mypy_cache/3.12/numpy/_typing/_add_docstring.meta.json +1 -0
  93. mink/.mypy_cache/3.12/numpy/_typing/_array_like.data.json +1 -0
  94. mink/.mypy_cache/3.12/numpy/_typing/_array_like.meta.json +1 -0
  95. mink/.mypy_cache/3.12/numpy/_typing/_callable.data.json +1 -0
  96. mink/.mypy_cache/3.12/numpy/_typing/_callable.meta.json +1 -0
  97. mink/.mypy_cache/3.12/numpy/_typing/_char_codes.data.json +1 -0
  98. mink/.mypy_cache/3.12/numpy/_typing/_char_codes.meta.json +1 -0
  99. mink/.mypy_cache/3.12/numpy/_typing/_dtype_like.data.json +1 -0
  100. mink/.mypy_cache/3.12/numpy/_typing/_dtype_like.meta.json +1 -0
  101. mink/.mypy_cache/3.12/numpy/_typing/_extended_precision.data.json +1 -0
  102. mink/.mypy_cache/3.12/numpy/_typing/_extended_precision.meta.json +1 -0
  103. mink/.mypy_cache/3.12/numpy/_typing/_nbit.data.json +1 -0
  104. mink/.mypy_cache/3.12/numpy/_typing/_nbit.meta.json +1 -0
  105. mink/.mypy_cache/3.12/numpy/_typing/_nested_sequence.data.json +1 -0
  106. mink/.mypy_cache/3.12/numpy/_typing/_nested_sequence.meta.json +1 -0
  107. mink/.mypy_cache/3.12/numpy/_typing/_scalars.data.json +1 -0
  108. mink/.mypy_cache/3.12/numpy/_typing/_scalars.meta.json +1 -0
  109. mink/.mypy_cache/3.12/numpy/_typing/_shape.data.json +1 -0
  110. mink/.mypy_cache/3.12/numpy/_typing/_shape.meta.json +1 -0
  111. mink/.mypy_cache/3.12/numpy/_typing/_ufunc.data.json +1 -0
  112. mink/.mypy_cache/3.12/numpy/_typing/_ufunc.meta.json +1 -0
  113. mink/.mypy_cache/3.12/numpy/_utils/__init__.data.json +1 -0
  114. mink/.mypy_cache/3.12/numpy/_utils/__init__.meta.json +1 -0
  115. mink/.mypy_cache/3.12/numpy/_utils/_convertions.data.json +1 -0
  116. mink/.mypy_cache/3.12/numpy/_utils/_convertions.meta.json +1 -0
  117. mink/.mypy_cache/3.12/numpy/core/__init__.data.json +1 -0
  118. mink/.mypy_cache/3.12/numpy/core/__init__.meta.json +1 -0
  119. mink/.mypy_cache/3.12/numpy/core/_asarray.data.json +1 -0
  120. mink/.mypy_cache/3.12/numpy/core/_asarray.meta.json +1 -0
  121. mink/.mypy_cache/3.12/numpy/core/_internal.data.json +1 -0
  122. mink/.mypy_cache/3.12/numpy/core/_internal.meta.json +1 -0
  123. mink/.mypy_cache/3.12/numpy/core/_type_aliases.data.json +1 -0
  124. mink/.mypy_cache/3.12/numpy/core/_type_aliases.meta.json +1 -0
  125. mink/.mypy_cache/3.12/numpy/core/_ufunc_config.data.json +1 -0
  126. mink/.mypy_cache/3.12/numpy/core/_ufunc_config.meta.json +1 -0
  127. mink/.mypy_cache/3.12/numpy/core/arrayprint.data.json +1 -0
  128. mink/.mypy_cache/3.12/numpy/core/arrayprint.meta.json +1 -0
  129. mink/.mypy_cache/3.12/numpy/core/defchararray.data.json +1 -0
  130. mink/.mypy_cache/3.12/numpy/core/defchararray.meta.json +1 -0
  131. mink/.mypy_cache/3.12/numpy/core/einsumfunc.data.json +1 -0
  132. mink/.mypy_cache/3.12/numpy/core/einsumfunc.meta.json +1 -0
  133. mink/.mypy_cache/3.12/numpy/core/fromnumeric.data.json +1 -0
  134. mink/.mypy_cache/3.12/numpy/core/fromnumeric.meta.json +1 -0
  135. mink/.mypy_cache/3.12/numpy/core/function_base.data.json +1 -0
  136. mink/.mypy_cache/3.12/numpy/core/function_base.meta.json +1 -0
  137. mink/.mypy_cache/3.12/numpy/core/multiarray.data.json +1 -0
  138. mink/.mypy_cache/3.12/numpy/core/multiarray.meta.json +1 -0
  139. mink/.mypy_cache/3.12/numpy/core/numeric.data.json +1 -0
  140. mink/.mypy_cache/3.12/numpy/core/numeric.meta.json +1 -0
  141. mink/.mypy_cache/3.12/numpy/core/numerictypes.data.json +1 -0
  142. mink/.mypy_cache/3.12/numpy/core/numerictypes.meta.json +1 -0
  143. mink/.mypy_cache/3.12/numpy/core/records.data.json +1 -0
  144. mink/.mypy_cache/3.12/numpy/core/records.meta.json +1 -0
  145. mink/.mypy_cache/3.12/numpy/core/shape_base.data.json +1 -0
  146. mink/.mypy_cache/3.12/numpy/core/shape_base.meta.json +1 -0
  147. mink/.mypy_cache/3.12/numpy/core/umath.data.json +1 -0
  148. mink/.mypy_cache/3.12/numpy/core/umath.meta.json +1 -0
  149. mink/.mypy_cache/3.12/numpy/ctypeslib.data.json +1 -0
  150. mink/.mypy_cache/3.12/numpy/ctypeslib.meta.json +1 -0
  151. mink/.mypy_cache/3.12/numpy/dtypes.data.json +1 -0
  152. mink/.mypy_cache/3.12/numpy/dtypes.meta.json +1 -0
  153. mink/.mypy_cache/3.12/numpy/exceptions.data.json +1 -0
  154. mink/.mypy_cache/3.12/numpy/exceptions.meta.json +1 -0
  155. mink/.mypy_cache/3.12/numpy/fft/__init__.data.json +1 -0
  156. mink/.mypy_cache/3.12/numpy/fft/__init__.meta.json +1 -0
  157. mink/.mypy_cache/3.12/numpy/fft/_pocketfft.data.json +1 -0
  158. mink/.mypy_cache/3.12/numpy/fft/_pocketfft.meta.json +1 -0
  159. mink/.mypy_cache/3.12/numpy/fft/helper.data.json +1 -0
  160. mink/.mypy_cache/3.12/numpy/fft/helper.meta.json +1 -0
  161. mink/.mypy_cache/3.12/numpy/lib/__init__.data.json +1 -0
  162. mink/.mypy_cache/3.12/numpy/lib/__init__.meta.json +1 -0
  163. mink/.mypy_cache/3.12/numpy/lib/_version.data.json +1 -0
  164. mink/.mypy_cache/3.12/numpy/lib/_version.meta.json +1 -0
  165. mink/.mypy_cache/3.12/numpy/lib/arraypad.data.json +1 -0
  166. mink/.mypy_cache/3.12/numpy/lib/arraypad.meta.json +1 -0
  167. mink/.mypy_cache/3.12/numpy/lib/arraysetops.data.json +1 -0
  168. mink/.mypy_cache/3.12/numpy/lib/arraysetops.meta.json +1 -0
  169. mink/.mypy_cache/3.12/numpy/lib/arrayterator.data.json +1 -0
  170. mink/.mypy_cache/3.12/numpy/lib/arrayterator.meta.json +1 -0
  171. mink/.mypy_cache/3.12/numpy/lib/format.data.json +1 -0
  172. mink/.mypy_cache/3.12/numpy/lib/format.meta.json +1 -0
  173. mink/.mypy_cache/3.12/numpy/lib/function_base.data.json +1 -0
  174. mink/.mypy_cache/3.12/numpy/lib/function_base.meta.json +1 -0
  175. mink/.mypy_cache/3.12/numpy/lib/histograms.data.json +1 -0
  176. mink/.mypy_cache/3.12/numpy/lib/histograms.meta.json +1 -0
  177. mink/.mypy_cache/3.12/numpy/lib/index_tricks.data.json +1 -0
  178. mink/.mypy_cache/3.12/numpy/lib/index_tricks.meta.json +1 -0
  179. mink/.mypy_cache/3.12/numpy/lib/mixins.data.json +1 -0
  180. mink/.mypy_cache/3.12/numpy/lib/mixins.meta.json +1 -0
  181. mink/.mypy_cache/3.12/numpy/lib/nanfunctions.data.json +1 -0
  182. mink/.mypy_cache/3.12/numpy/lib/nanfunctions.meta.json +1 -0
  183. mink/.mypy_cache/3.12/numpy/lib/npyio.data.json +1 -0
  184. mink/.mypy_cache/3.12/numpy/lib/npyio.meta.json +1 -0
  185. mink/.mypy_cache/3.12/numpy/lib/polynomial.data.json +1 -0
  186. mink/.mypy_cache/3.12/numpy/lib/polynomial.meta.json +1 -0
  187. mink/.mypy_cache/3.12/numpy/lib/scimath.data.json +1 -0
  188. mink/.mypy_cache/3.12/numpy/lib/scimath.meta.json +1 -0
  189. mink/.mypy_cache/3.12/numpy/lib/shape_base.data.json +1 -0
  190. mink/.mypy_cache/3.12/numpy/lib/shape_base.meta.json +1 -0
  191. mink/.mypy_cache/3.12/numpy/lib/stride_tricks.data.json +1 -0
  192. mink/.mypy_cache/3.12/numpy/lib/stride_tricks.meta.json +1 -0
  193. mink/.mypy_cache/3.12/numpy/lib/twodim_base.data.json +1 -0
  194. mink/.mypy_cache/3.12/numpy/lib/twodim_base.meta.json +1 -0
  195. mink/.mypy_cache/3.12/numpy/lib/type_check.data.json +1 -0
  196. mink/.mypy_cache/3.12/numpy/lib/type_check.meta.json +1 -0
  197. mink/.mypy_cache/3.12/numpy/lib/ufunclike.data.json +1 -0
  198. mink/.mypy_cache/3.12/numpy/lib/ufunclike.meta.json +1 -0
  199. mink/.mypy_cache/3.12/numpy/lib/utils.data.json +1 -0
  200. mink/.mypy_cache/3.12/numpy/lib/utils.meta.json +1 -0
  201. mink/.mypy_cache/3.12/numpy/linalg/__init__.data.json +1 -0
  202. mink/.mypy_cache/3.12/numpy/linalg/__init__.meta.json +1 -0
  203. mink/.mypy_cache/3.12/numpy/linalg/linalg.data.json +1 -0
  204. mink/.mypy_cache/3.12/numpy/linalg/linalg.meta.json +1 -0
  205. mink/.mypy_cache/3.12/numpy/ma/__init__.data.json +1 -0
  206. mink/.mypy_cache/3.12/numpy/ma/__init__.meta.json +1 -0
  207. mink/.mypy_cache/3.12/numpy/ma/core.data.json +1 -0
  208. mink/.mypy_cache/3.12/numpy/ma/core.meta.json +1 -0
  209. mink/.mypy_cache/3.12/numpy/ma/extras.data.json +1 -0
  210. mink/.mypy_cache/3.12/numpy/ma/extras.meta.json +1 -0
  211. mink/.mypy_cache/3.12/numpy/ma/mrecords.data.json +1 -0
  212. mink/.mypy_cache/3.12/numpy/ma/mrecords.meta.json +1 -0
  213. mink/.mypy_cache/3.12/numpy/matrixlib/__init__.data.json +1 -0
  214. mink/.mypy_cache/3.12/numpy/matrixlib/__init__.meta.json +1 -0
  215. mink/.mypy_cache/3.12/numpy/matrixlib/defmatrix.data.json +1 -0
  216. mink/.mypy_cache/3.12/numpy/matrixlib/defmatrix.meta.json +1 -0
  217. mink/.mypy_cache/3.12/numpy/polynomial/__init__.data.json +1 -0
  218. mink/.mypy_cache/3.12/numpy/polynomial/__init__.meta.json +1 -0
  219. mink/.mypy_cache/3.12/numpy/polynomial/_polybase.data.json +1 -0
  220. mink/.mypy_cache/3.12/numpy/polynomial/_polybase.meta.json +1 -0
  221. mink/.mypy_cache/3.12/numpy/polynomial/chebyshev.data.json +1 -0
  222. mink/.mypy_cache/3.12/numpy/polynomial/chebyshev.meta.json +1 -0
  223. mink/.mypy_cache/3.12/numpy/polynomial/hermite.data.json +1 -0
  224. mink/.mypy_cache/3.12/numpy/polynomial/hermite.meta.json +1 -0
  225. mink/.mypy_cache/3.12/numpy/polynomial/hermite_e.data.json +1 -0
  226. mink/.mypy_cache/3.12/numpy/polynomial/hermite_e.meta.json +1 -0
  227. mink/.mypy_cache/3.12/numpy/polynomial/laguerre.data.json +1 -0
  228. mink/.mypy_cache/3.12/numpy/polynomial/laguerre.meta.json +1 -0
  229. mink/.mypy_cache/3.12/numpy/polynomial/legendre.data.json +1 -0
  230. mink/.mypy_cache/3.12/numpy/polynomial/legendre.meta.json +1 -0
  231. mink/.mypy_cache/3.12/numpy/polynomial/polynomial.data.json +1 -0
  232. mink/.mypy_cache/3.12/numpy/polynomial/polynomial.meta.json +1 -0
  233. mink/.mypy_cache/3.12/numpy/polynomial/polyutils.data.json +1 -0
  234. mink/.mypy_cache/3.12/numpy/polynomial/polyutils.meta.json +1 -0
  235. mink/.mypy_cache/3.12/numpy/random/__init__.data.json +1 -0
  236. mink/.mypy_cache/3.12/numpy/random/__init__.meta.json +1 -0
  237. mink/.mypy_cache/3.12/numpy/random/_generator.data.json +1 -0
  238. mink/.mypy_cache/3.12/numpy/random/_generator.meta.json +1 -0
  239. mink/.mypy_cache/3.12/numpy/random/_mt19937.data.json +1 -0
  240. mink/.mypy_cache/3.12/numpy/random/_mt19937.meta.json +1 -0
  241. mink/.mypy_cache/3.12/numpy/random/_pcg64.data.json +1 -0
  242. mink/.mypy_cache/3.12/numpy/random/_pcg64.meta.json +1 -0
  243. mink/.mypy_cache/3.12/numpy/random/_philox.data.json +1 -0
  244. mink/.mypy_cache/3.12/numpy/random/_philox.meta.json +1 -0
  245. mink/.mypy_cache/3.12/numpy/random/_sfc64.data.json +1 -0
  246. mink/.mypy_cache/3.12/numpy/random/_sfc64.meta.json +1 -0
  247. mink/.mypy_cache/3.12/numpy/random/bit_generator.data.json +1 -0
  248. mink/.mypy_cache/3.12/numpy/random/bit_generator.meta.json +1 -0
  249. mink/.mypy_cache/3.12/numpy/random/mtrand.data.json +1 -0
  250. mink/.mypy_cache/3.12/numpy/random/mtrand.meta.json +1 -0
  251. mink/.mypy_cache/3.12/numpy/testing/__init__.data.json +1 -0
  252. mink/.mypy_cache/3.12/numpy/testing/__init__.meta.json +1 -0
  253. mink/.mypy_cache/3.12/numpy/testing/_private/__init__.data.json +1 -0
  254. mink/.mypy_cache/3.12/numpy/testing/_private/__init__.meta.json +1 -0
  255. mink/.mypy_cache/3.12/numpy/testing/_private/utils.data.json +1 -0
  256. mink/.mypy_cache/3.12/numpy/testing/_private/utils.meta.json +1 -0
  257. mink/.mypy_cache/3.12/numpy/typing/__init__.data.json +1 -0
  258. mink/.mypy_cache/3.12/numpy/typing/__init__.meta.json +1 -0
  259. mink/.mypy_cache/3.12/numpy/version.data.json +1 -0
  260. mink/.mypy_cache/3.12/numpy/version.meta.json +1 -0
  261. mink/.mypy_cache/3.12/os/__init__.data.json +1 -0
  262. mink/.mypy_cache/3.12/os/__init__.meta.json +1 -0
  263. mink/.mypy_cache/3.12/os/path.data.json +1 -0
  264. mink/.mypy_cache/3.12/os/path.meta.json +1 -0
  265. mink/.mypy_cache/3.12/pathlib.data.json +1 -0
  266. mink/.mypy_cache/3.12/pathlib.meta.json +1 -0
  267. mink/.mypy_cache/3.12/posixpath.data.json +1 -0
  268. mink/.mypy_cache/3.12/posixpath.meta.json +1 -0
  269. mink/.mypy_cache/3.12/re.data.json +1 -0
  270. mink/.mypy_cache/3.12/re.meta.json +1 -0
  271. mink/.mypy_cache/3.12/sre_compile.data.json +1 -0
  272. mink/.mypy_cache/3.12/sre_compile.meta.json +1 -0
  273. mink/.mypy_cache/3.12/sre_constants.data.json +1 -0
  274. mink/.mypy_cache/3.12/sre_constants.meta.json +1 -0
  275. mink/.mypy_cache/3.12/sre_parse.data.json +1 -0
  276. mink/.mypy_cache/3.12/sre_parse.meta.json +1 -0
  277. mink/.mypy_cache/3.12/string.data.json +1 -0
  278. mink/.mypy_cache/3.12/string.meta.json +1 -0
  279. mink/.mypy_cache/3.12/subprocess.data.json +1 -0
  280. mink/.mypy_cache/3.12/subprocess.meta.json +1 -0
  281. mink/.mypy_cache/3.12/sys/__init__.data.json +1 -0
  282. mink/.mypy_cache/3.12/sys/__init__.meta.json +1 -0
  283. mink/.mypy_cache/3.12/sys/_monitoring.data.json +1 -0
  284. mink/.mypy_cache/3.12/sys/_monitoring.meta.json +1 -0
  285. mink/.mypy_cache/3.12/textwrap.data.json +1 -0
  286. mink/.mypy_cache/3.12/textwrap.meta.json +1 -0
  287. mink/.mypy_cache/3.12/threading.data.json +1 -0
  288. mink/.mypy_cache/3.12/threading.meta.json +1 -0
  289. mink/.mypy_cache/3.12/time.data.json +1 -0
  290. mink/.mypy_cache/3.12/time.meta.json +1 -0
  291. mink/.mypy_cache/3.12/types.data.json +1 -0
  292. mink/.mypy_cache/3.12/types.meta.json +1 -0
  293. mink/.mypy_cache/3.12/typing.data.json +1 -0
  294. mink/.mypy_cache/3.12/typing.meta.json +1 -0
  295. mink/.mypy_cache/3.12/typing_extensions.data.json +1 -0
  296. mink/.mypy_cache/3.12/typing_extensions.meta.json +1 -0
  297. mink/.mypy_cache/3.12/unittest/__init__.data.json +1 -0
  298. mink/.mypy_cache/3.12/unittest/__init__.meta.json +1 -0
  299. mink/.mypy_cache/3.12/unittest/_log.data.json +1 -0
  300. mink/.mypy_cache/3.12/unittest/_log.meta.json +1 -0
  301. mink/.mypy_cache/3.12/unittest/async_case.data.json +1 -0
  302. mink/.mypy_cache/3.12/unittest/async_case.meta.json +1 -0
  303. mink/.mypy_cache/3.12/unittest/case.data.json +1 -0
  304. mink/.mypy_cache/3.12/unittest/case.meta.json +1 -0
  305. mink/.mypy_cache/3.12/unittest/loader.data.json +1 -0
  306. mink/.mypy_cache/3.12/unittest/loader.meta.json +1 -0
  307. mink/.mypy_cache/3.12/unittest/main.data.json +1 -0
  308. mink/.mypy_cache/3.12/unittest/main.meta.json +1 -0
  309. mink/.mypy_cache/3.12/unittest/result.data.json +1 -0
  310. mink/.mypy_cache/3.12/unittest/result.meta.json +1 -0
  311. mink/.mypy_cache/3.12/unittest/runner.data.json +1 -0
  312. mink/.mypy_cache/3.12/unittest/runner.meta.json +1 -0
  313. mink/.mypy_cache/3.12/unittest/signals.data.json +1 -0
  314. mink/.mypy_cache/3.12/unittest/signals.meta.json +1 -0
  315. mink/.mypy_cache/3.12/unittest/suite.data.json +1 -0
  316. mink/.mypy_cache/3.12/unittest/suite.meta.json +1 -0
  317. mink/.mypy_cache/3.12/warnings.data.json +1 -0
  318. mink/.mypy_cache/3.12/warnings.meta.json +1 -0
  319. mink/.mypy_cache/3.12/zipfile.data.json +1 -0
  320. mink/.mypy_cache/3.12/zipfile.meta.json +1 -0
  321. mink/.mypy_cache/CACHEDIR.TAG +3 -0
  322. mink/__init__.py +75 -0
  323. mink/configuration.py +215 -0
  324. mink/constants.py +34 -0
  325. mink/exceptions.py +98 -0
  326. mink/lie/__init__.py +13 -0
  327. mink/lie/base.py +156 -0
  328. mink/lie/se3.py +249 -0
  329. mink/lie/so3.py +224 -0
  330. mink/lie/tests/__init__.py +0 -0
  331. mink/lie/tests/test_axioms.py +51 -0
  332. mink/lie/tests/test_operations.py +77 -0
  333. mink/lie/tests/utils.py +20 -0
  334. mink/lie/utils.py +29 -0
  335. mink/limits/__init__.py +16 -0
  336. mink/limits/collision_avoidance_limit.py +274 -0
  337. mink/limits/configuration_limit.py +126 -0
  338. mink/limits/exceptions.py +7 -0
  339. mink/limits/limit.py +41 -0
  340. mink/limits/velocity_limit.py +92 -0
  341. mink/py.typed +0 -0
  342. mink/solve_ik.py +105 -0
  343. mink/tasks/__init__.py +26 -0
  344. mink/tasks/com_task.py +82 -0
  345. mink/tasks/exceptions.py +27 -0
  346. mink/tasks/frame_task.py +114 -0
  347. mink/tasks/posture_task.py +103 -0
  348. mink/tasks/task.py +105 -0
  349. mink/utils.py +128 -0
  350. mink-0.0.1.dist-info/METADATA +71 -0
  351. mink-0.0.1.dist-info/RECORD +352 -0
  352. mink-0.0.1.dist-info/WHEEL +4 -0
mink/lie/se3.py ADDED
@@ -0,0 +1,249 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ import mujoco
6
+ import numpy as np
7
+
8
+ from ..exceptions import InvalidMocapBody
9
+ from .base import MatrixLieGroup
10
+ from .so3 import SO3
11
+ from .utils import get_epsilon, skew
12
+
13
+ _IDENTITY_WXYZ_XYZ = np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], dtype=np.float64)
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class SE3(MatrixLieGroup):
18
+ """Special Euclidean group for proper rigid transforms in 3D.
19
+
20
+ Internal parameterization is (qw, qx, qy, qz, x, y, z). Tangent parameterization is
21
+ (vx, vy, vz, omega_x, omega_y, omega_z).
22
+ """
23
+
24
+ wxyz_xyz: np.ndarray
25
+ matrix_dim: int = 4
26
+ parameters_dim: int = 7
27
+ tangent_dim: int = 6
28
+ space_dim: int = 3
29
+
30
+ def __repr__(self) -> str:
31
+ quat = np.round(self.wxyz_xyz[:4], 5)
32
+ xyz = np.round(self.wxyz_xyz[4:], 5)
33
+ return f"{self.__class__.__name__}(wxyz={quat}, xyz={xyz})"
34
+
35
+ def copy(self) -> SE3:
36
+ return SE3(wxyz_xyz=np.array(self.wxyz_xyz))
37
+
38
+ def parameters(self) -> np.ndarray:
39
+ return self.wxyz_xyz
40
+
41
+ @classmethod
42
+ def identity(cls) -> SE3:
43
+ return SE3(wxyz_xyz=_IDENTITY_WXYZ_XYZ)
44
+
45
+ @classmethod
46
+ def from_rotation_and_translation(
47
+ cls,
48
+ rotation: SO3,
49
+ translation: np.ndarray,
50
+ ) -> SE3:
51
+ assert translation.shape == (SE3.space_dim,)
52
+ return SE3(wxyz_xyz=np.concatenate([rotation.wxyz, translation]))
53
+
54
+ @classmethod
55
+ def from_rotation(cls, rotation: SO3) -> SE3:
56
+ return SE3.from_rotation_and_translation(
57
+ rotation=rotation,
58
+ translation=np.zeros(
59
+ SE3.space_dim,
60
+ ),
61
+ )
62
+
63
+ @classmethod
64
+ def from_translation(cls, translation: np.ndarray) -> SE3:
65
+ return SE3.from_rotation_and_translation(
66
+ rotation=SO3.identity(), translation=translation
67
+ )
68
+
69
+ @classmethod
70
+ def from_matrix(cls, matrix: np.ndarray) -> SE3:
71
+ assert matrix.shape == (SE3.matrix_dim, SE3.matrix_dim)
72
+ return SE3.from_rotation_and_translation(
73
+ rotation=SO3.from_matrix(matrix[:3, :3]),
74
+ translation=matrix[:3, 3],
75
+ )
76
+
77
+ @classmethod
78
+ def from_mocap_id(cls, data: mujoco.MjData, mocap_id: int) -> SE3:
79
+ return SE3.from_rotation_and_translation(
80
+ rotation=SO3(data.mocap_quat[mocap_id]),
81
+ translation=data.mocap_pos[mocap_id],
82
+ )
83
+
84
+ @classmethod
85
+ def from_mocap_name(
86
+ cls, model: mujoco.MjModel, data: mujoco.MjData, mocap_name: str
87
+ ) -> SE3:
88
+ mocap_id = model.body(mocap_name).mocapid[0]
89
+ if mocap_id == -1:
90
+ raise InvalidMocapBody(mocap_name, model)
91
+ return SE3.from_mocap_id(data, mocap_id)
92
+
93
+ @classmethod
94
+ def sample_uniform(cls) -> SE3:
95
+ return SE3.from_rotation_and_translation(
96
+ rotation=SO3.sample_uniform(),
97
+ translation=np.random.uniform(-1.0, 1.0, size=(SE3.space_dim,)),
98
+ )
99
+
100
+ def rotation(self) -> SO3:
101
+ return SO3(wxyz=self.wxyz_xyz[:4])
102
+
103
+ def translation(self) -> np.ndarray:
104
+ return self.wxyz_xyz[4:]
105
+
106
+ def as_matrix(self) -> np.ndarray:
107
+ hmat = np.eye(self.matrix_dim, dtype=np.float64)
108
+ hmat[:3, :3] = self.rotation().as_matrix()
109
+ hmat[:3, 3] = self.translation()
110
+ return hmat
111
+
112
+ @classmethod
113
+ def exp(cls, tangent: np.ndarray) -> SE3:
114
+ assert tangent.shape == (SE3.tangent_dim,)
115
+ rotation = SO3.exp(tangent[3:])
116
+ theta_squared = tangent[3:] @ tangent[3:]
117
+ use_taylor = theta_squared < get_epsilon(theta_squared.dtype)
118
+ theta_squared_safe = 1.0 if use_taylor else theta_squared
119
+ theta_safe = np.sqrt(theta_squared_safe)
120
+ skew_omega = skew(tangent[3:])
121
+ if use_taylor:
122
+ V = rotation.as_matrix()
123
+ else:
124
+ V = (
125
+ np.eye(3, dtype=np.float64)
126
+ + (1.0 - np.cos(theta_safe)) / (theta_squared_safe) * skew_omega
127
+ + (theta_safe - np.sin(theta_safe))
128
+ / (theta_squared_safe * theta_safe)
129
+ * (skew_omega @ skew_omega)
130
+ )
131
+ return SE3.from_rotation_and_translation(
132
+ rotation=rotation,
133
+ translation=V @ tangent[:3],
134
+ )
135
+
136
+ def inverse(self) -> SE3:
137
+ R_inv = self.rotation().inverse()
138
+ return SE3.from_rotation_and_translation(
139
+ rotation=R_inv,
140
+ translation=-(R_inv @ self.translation()),
141
+ )
142
+
143
+ def normalize(self) -> SE3:
144
+ return SE3.from_rotation_and_translation(
145
+ rotation=self.rotation().normalize(),
146
+ translation=self.translation(),
147
+ )
148
+
149
+ def apply(self, target: np.ndarray) -> np.ndarray:
150
+ assert target.shape == (SE3.space_dim,)
151
+ return self.rotation() @ target + self.translation()
152
+
153
+ def multiply(self, other: SE3) -> SE3:
154
+ return SE3.from_rotation_and_translation(
155
+ rotation=self.rotation() @ other.rotation(),
156
+ translation=(self.rotation() @ other.translation()) + self.translation(),
157
+ )
158
+
159
+ def log(self) -> np.ndarray:
160
+ omega = self.rotation().log()
161
+ theta_squared = omega @ omega
162
+ use_taylor = theta_squared < get_epsilon(theta_squared.dtype)
163
+ skew_omega = skew(omega)
164
+ theta_squared_safe = 1.0 if use_taylor else theta_squared
165
+ theta_safe = np.sqrt(theta_squared_safe)
166
+ half_theta_safe = 0.5 * theta_safe
167
+ skew_omega_norm = skew_omega @ skew_omega
168
+ if use_taylor:
169
+ V_inv = (
170
+ np.eye(3, dtype=np.float64) - 0.5 * skew_omega + skew_omega_norm / 12.0
171
+ )
172
+ else:
173
+ V_inv = (
174
+ np.eye(3, dtype=np.float64)
175
+ - 0.5 * skew_omega
176
+ + (
177
+ 1.0
178
+ - theta_safe
179
+ * np.cos(half_theta_safe)
180
+ / (2.0 * np.sin(half_theta_safe))
181
+ )
182
+ / theta_squared_safe
183
+ * skew_omega_norm
184
+ )
185
+ return np.concatenate([V_inv @ self.translation(), omega])
186
+
187
+ def adjoint(self) -> np.ndarray:
188
+ R = self.rotation().as_matrix()
189
+ return np.block(
190
+ [
191
+ [R, skew(self.translation()) @ R],
192
+ [np.zeros((3, 3), dtype=np.float64), R],
193
+ ]
194
+ )
195
+
196
+ # Jacobians.
197
+
198
+ # Eqn 179 a)
199
+ @classmethod
200
+ def ljac(cls, other: np.ndarray) -> np.ndarray:
201
+ theta = other[3:]
202
+ if theta @ theta < get_epsilon(theta.dtype):
203
+ return np.eye(cls.tangent_dim)
204
+ Q = _getQ(other)
205
+ J = SO3.ljac(theta)
206
+ O = np.zeros((3, 3))
207
+ return np.block([[J, Q], [O, J]])
208
+
209
+ # Eqn 179 b)
210
+ @classmethod
211
+ def ljacinv(cls, other: np.ndarray) -> np.ndarray:
212
+ theta = other[3:]
213
+ if theta @ theta < get_epsilon(theta.dtype):
214
+ return np.eye(cls.tangent_dim)
215
+ Q = _getQ(other)
216
+ J_inv = SO3.ljacinv(theta)
217
+ O = np.zeros((3, 3))
218
+ return np.block([[J_inv, -J_inv @ Q @ J_inv], [O, J_inv]])
219
+
220
+
221
+ # Eqn 180.
222
+ def _getQ(c) -> np.ndarray:
223
+ theta_sq = c[3:] @ c[3:]
224
+ A = 0.5
225
+ if theta_sq < get_epsilon(theta_sq.dtype):
226
+ B = (1.0 / 6.0) + (1.0 / 120.0) * theta_sq
227
+ C = -(1.0 / 24.0) + (1.0 / 720.0) * theta_sq
228
+ D = -(1.0 / 60.0)
229
+ else:
230
+ theta = np.sqrt(theta_sq)
231
+ sin_theta = np.sin(theta)
232
+ cos_theta = np.cos(theta)
233
+ B = (theta - sin_theta) / (theta_sq * theta)
234
+ C = (1.0 - theta_sq / 2.0 - cos_theta) / (theta_sq * theta_sq)
235
+ D = ((2) * theta - (3) * sin_theta + theta * cos_theta) / (
236
+ (2) * theta_sq * theta_sq * theta
237
+ )
238
+ V = skew(c[:3])
239
+ W = skew(c[3:])
240
+ VW = V @ W
241
+ WV = VW.T
242
+ WVW = WV @ W
243
+ VWW = VW @ W
244
+ return (
245
+ +A * V
246
+ + B * (WV + VW + WVW)
247
+ - C * (VWW - VWW.T - 3 * WVW)
248
+ + D * (WVW @ W + W @ WVW)
249
+ )
mink/lie/so3.py ADDED
@@ -0,0 +1,224 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import NamedTuple
5
+
6
+ import mujoco
7
+ import numpy as np
8
+
9
+ from .base import MatrixLieGroup
10
+ from .utils import get_epsilon, skew
11
+
12
+ _IDENTITIY_WXYZ = np.array([1.0, 0.0, 0.0, 0.0], dtype=np.float64)
13
+ _INVERT_QUAT_SIGN = np.array([1.0, -1.0, -1.0, -1.0], dtype=np.float64)
14
+
15
+
16
+ class RollPitchYaw(NamedTuple):
17
+ roll: float
18
+ pitch: float
19
+ yaw: float
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class SO3(MatrixLieGroup):
24
+ """Special orthogonal group for 3D rotations.
25
+
26
+ Internal parameterization is (qw, qx, qy, qz). Tangent parameterization is
27
+ (omega_x, omega_y, omega_z).
28
+ """
29
+
30
+ wxyz: np.ndarray
31
+ matrix_dim: int = 3
32
+ parameters_dim: int = 4
33
+ tangent_dim: int = 3
34
+ space_dim: int = 3
35
+
36
+ def __post_init__(self) -> None:
37
+ if self.wxyz.shape != (self.parameters_dim,):
38
+ raise ValueError(
39
+ f"Expeced wxyz to be a length 4 vector but got {self.wxyz.shape[0]}."
40
+ )
41
+
42
+ def __repr__(self) -> str:
43
+ wxyz = np.round(self.wxyz, 5)
44
+ return f"{self.__class__.__name__}(wxyz={wxyz})"
45
+
46
+ def parameters(self) -> np.ndarray:
47
+ return self.wxyz
48
+
49
+ def copy(self) -> SO3:
50
+ return SO3(wxyz=self.wxyz.copy())
51
+
52
+ @classmethod
53
+ def from_x_radians(cls, theta: float) -> SO3:
54
+ return SO3.exp(np.array([theta, 0.0, 0.0], dtype=np.float64))
55
+
56
+ @classmethod
57
+ def from_y_radians(cls, theta: float) -> SO3:
58
+ return SO3.exp(np.array([0.0, theta, 0.0], dtype=np.float64))
59
+
60
+ @classmethod
61
+ def from_z_radians(cls, theta: float) -> SO3:
62
+ return SO3.exp(np.array([0.0, 0.0, theta], dtype=np.float64))
63
+
64
+ @classmethod
65
+ def from_rpy_radians(
66
+ cls,
67
+ roll: float,
68
+ pitch: float,
69
+ yaw: float,
70
+ ) -> SO3:
71
+ return (
72
+ SO3.from_z_radians(yaw)
73
+ @ SO3.from_y_radians(pitch)
74
+ @ SO3.from_x_radians(roll)
75
+ )
76
+
77
+ @classmethod
78
+ def from_matrix(cls, matrix: np.ndarray) -> SO3:
79
+ assert matrix.shape == (SO3.matrix_dim, SO3.matrix_dim)
80
+ wxyz = np.zeros(SO3.parameters_dim, dtype=np.float64)
81
+ mujoco.mju_mat2Quat(wxyz, matrix.ravel())
82
+ return SO3(wxyz=wxyz)
83
+
84
+ @classmethod
85
+ def identity(cls) -> SO3:
86
+ return SO3(wxyz=_IDENTITIY_WXYZ)
87
+
88
+ @classmethod
89
+ def sample_uniform(cls) -> SO3:
90
+ # Ref: https://lavalle.pl/planning/node198.html
91
+ u1, u2, u3 = np.random.uniform(
92
+ low=np.zeros(shape=(3,)),
93
+ high=np.array([1.0, 2.0 * np.pi, 2.0 * np.pi]),
94
+ )
95
+ a = np.sqrt(1.0 - u1)
96
+ b = np.sqrt(u1)
97
+ wxyz = np.array(
98
+ [
99
+ a * np.sin(u2),
100
+ a * np.cos(u2),
101
+ b * np.sin(u3),
102
+ b * np.cos(u3),
103
+ ],
104
+ dtype=np.float64,
105
+ )
106
+ return SO3(wxyz=wxyz)
107
+
108
+ # Eq. 138.
109
+ def as_matrix(self) -> np.ndarray:
110
+ mat = np.zeros(9, dtype=np.float64)
111
+ mujoco.mju_quat2Mat(mat, self.wxyz)
112
+ return mat.reshape(3, 3)
113
+
114
+ def compute_roll_radians(self) -> float:
115
+ q0, q1, q2, q3 = self.wxyz
116
+ return np.arctan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1**2 + q2**2))
117
+
118
+ def compute_pitch_radians(self) -> float:
119
+ q0, q1, q2, q3 = self.wxyz
120
+ return np.arcsin(2 * (q0 * q2 - q3 * q1))
121
+
122
+ def compute_yaw_radians(self) -> float:
123
+ q0, q1, q2, q3 = self.wxyz
124
+ return np.arctan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2**2 + q3**2))
125
+
126
+ def as_rpy_radians(self) -> RollPitchYaw:
127
+ return RollPitchYaw(
128
+ roll=self.compute_roll_radians(),
129
+ pitch=self.compute_pitch_radians(),
130
+ yaw=self.compute_yaw_radians(),
131
+ )
132
+
133
+ # Paragraph above Appendix B.A.
134
+ def inverse(self) -> SO3:
135
+ return SO3(wxyz=self.wxyz * _INVERT_QUAT_SIGN)
136
+
137
+ def normalize(self) -> SO3:
138
+ return SO3(wxyz=self.wxyz / np.linalg.norm(self.wxyz))
139
+
140
+ # Eq. 136.
141
+ def apply(self, target: np.ndarray) -> np.ndarray:
142
+ assert target.shape == (SO3.space_dim,)
143
+ padded_target = np.concatenate([np.zeros(1, dtype=np.float64), target])
144
+ return (self @ SO3(wxyz=padded_target) @ self.inverse()).wxyz[1:]
145
+
146
+ def multiply(self, other: SO3) -> SO3:
147
+ res = np.empty(self.parameters_dim, dtype=np.float64)
148
+ mujoco.mju_mulQuat(res, self.wxyz, other.wxyz)
149
+ return SO3(wxyz=res)
150
+
151
+ ##
152
+ #
153
+ ##
154
+
155
+ # Eq. 132.
156
+ @classmethod
157
+ def exp(cls, tangent: np.ndarray) -> SO3:
158
+ assert tangent.shape == (SO3.tangent_dim,)
159
+ theta_squared = tangent @ tangent
160
+ theta_pow_4 = theta_squared * theta_squared
161
+ use_taylor = theta_squared < get_epsilon(tangent.dtype)
162
+ safe_theta = 1.0 if use_taylor else np.sqrt(theta_squared)
163
+ safe_half_theta = 0.5 * safe_theta
164
+ if use_taylor:
165
+ real = 1.0 - theta_squared / 8.0 + theta_pow_4 / 384.0
166
+ imaginary = 0.5 - theta_squared / 48.0 + theta_pow_4 / 3840.0
167
+ else:
168
+ real = np.cos(safe_half_theta)
169
+ imaginary = np.sin(safe_half_theta) / safe_theta
170
+ wxyz = np.concatenate([np.array([real]), imaginary * tangent])
171
+ return SO3(wxyz=wxyz)
172
+
173
+ # Eq. 133.
174
+ def log(self) -> np.ndarray:
175
+ w = self.wxyz[0]
176
+ norm_sq = self.wxyz[1:] @ self.wxyz[1:]
177
+ use_taylor = norm_sq < get_epsilon(norm_sq.dtype)
178
+ norm_safe = 1.0 if use_taylor else np.sqrt(norm_sq)
179
+ w_safe = w if use_taylor else 1.0
180
+ atan_n_over_w = np.arctan2(-norm_safe if w < 0 else norm_safe, abs(w))
181
+ if use_taylor:
182
+ atan_factor = 2.0 / w_safe - 2.0 / 3.0 * norm_sq / w_safe**3
183
+ else:
184
+ if abs(w) < get_epsilon(w.dtype):
185
+ scl = 1.0 if w > 0.0 else -1.0
186
+ atan_factor = scl * np.pi / norm_safe
187
+ else:
188
+ atan_factor = 2.0 * atan_n_over_w / norm_safe
189
+ return atan_factor * self.wxyz[1:]
190
+
191
+ # Eq. 139.
192
+ def adjoint(self) -> np.ndarray:
193
+ return self.as_matrix()
194
+
195
+ # Jacobians.
196
+
197
+ # Eqn. 145, 174.
198
+ @classmethod
199
+ def ljac(cls, other: np.ndarray) -> np.ndarray:
200
+ theta = np.sqrt(other @ other)
201
+ use_taylor = theta < get_epsilon(theta.dtype)
202
+ if use_taylor:
203
+ t2 = theta**2
204
+ A = (1.0 / 2.0) * (1.0 - t2 / 12.0 * (1.0 - t2 / 30.0 * (1.0 - t2 / 56.0)))
205
+ B = (1.0 / 6.0) * (1.0 - t2 / 20.0 * (1.0 - t2 / 42.0 * (1.0 - t2 / 72.0)))
206
+ else:
207
+ A = (1 - np.cos(theta)) / (theta**2)
208
+ B = (theta - np.sin(theta)) / (theta**3)
209
+ skew_other = skew(other)
210
+ return np.eye(3) + A * skew_other + B * (skew_other @ skew_other)
211
+
212
+ @classmethod
213
+ def ljacinv(cls, other: np.ndarray) -> np.ndarray:
214
+ theta = np.sqrt(other @ other)
215
+ use_taylor = theta < get_epsilon(theta.dtype)
216
+ if use_taylor:
217
+ t2 = theta**2
218
+ A = (1.0 / 12.0) * (1.0 + t2 / 60.0 * (1.0 + t2 / 42.0 * (1.0 + t2 / 40.0)))
219
+ else:
220
+ A = (1.0 / theta**2) * (
221
+ 1.0 - (theta * np.sin(theta) / (2.0 * (1.0 - np.cos(theta))))
222
+ )
223
+ skew_other = skew(other)
224
+ return np.eye(3) - 0.5 * skew_other + A * (skew_other @ skew_other)
File without changes
@@ -0,0 +1,51 @@
1
+ """Tests for group axioms."""
2
+
3
+ from typing import Type
4
+
5
+ from absl.testing import absltest, parameterized
6
+
7
+ from mink import lie
8
+
9
+ from ..base import MatrixLieGroup
10
+ from .utils import assert_transforms_close
11
+
12
+
13
+ @parameterized.named_parameters(
14
+ ("SO3", lie.SO3),
15
+ ("SE3", lie.SE3),
16
+ )
17
+ class TestAxioms(parameterized.TestCase):
18
+ def test_closure(self, group: Type[MatrixLieGroup]):
19
+ transform_a = group.sample_uniform()
20
+ transform_b = group.sample_uniform()
21
+ composed = transform_a @ transform_b
22
+ assert_transforms_close(composed, composed.normalize())
23
+ composed = transform_b @ transform_a
24
+ assert_transforms_close(composed, composed.normalize())
25
+ composed = transform_a @ transform_b
26
+ assert_transforms_close(composed, composed.normalize())
27
+
28
+ def test_identity(self, group: Type[MatrixLieGroup]):
29
+ transform = group.sample_uniform()
30
+ identity = group.identity()
31
+ assert_transforms_close(transform, identity @ transform)
32
+ assert_transforms_close(transform, transform @ identity)
33
+
34
+ def test_inverse(self, group: Type[MatrixLieGroup]):
35
+ transform = group.sample_uniform()
36
+ identity = group.identity()
37
+ assert_transforms_close(identity, transform.inverse() @ transform)
38
+ assert_transforms_close(identity, transform @ transform.inverse())
39
+
40
+ def test_associative(self, group: Type[MatrixLieGroup]):
41
+ transform_a = group.sample_uniform()
42
+ transform_b = group.sample_uniform()
43
+ transform_c = group.sample_uniform()
44
+ assert_transforms_close(
45
+ (transform_a @ transform_b) @ transform_c,
46
+ transform_a @ (transform_b @ transform_c),
47
+ )
48
+
49
+
50
+ if __name__ == "__main__":
51
+ absltest.main()
@@ -0,0 +1,77 @@
1
+ """Tests for general operation definitions."""
2
+
3
+ from typing import Type
4
+
5
+ import numpy as np
6
+ from absl.testing import absltest, parameterized
7
+
8
+ from ..base import MatrixLieGroup
9
+ from ..se3 import SE3
10
+ from ..so3 import SO3
11
+ from .utils import assert_transforms_close
12
+
13
+
14
+ @parameterized.named_parameters(
15
+ ("SO3", SO3),
16
+ ("SE3", SE3),
17
+ )
18
+ class TestOperations(parameterized.TestCase):
19
+ def test_inverse_bijective(self, group: Type[MatrixLieGroup]):
20
+ """Check inverse of inverse."""
21
+ transform = group.sample_uniform()
22
+ assert_transforms_close(transform, transform.inverse().inverse())
23
+
24
+ def test_matrix_bijective(self, group: Type[MatrixLieGroup]):
25
+ """Check that we can convert to and from matrices."""
26
+ transform = group.sample_uniform()
27
+ assert_transforms_close(transform, group.from_matrix(transform.as_matrix()))
28
+
29
+ def test_log_exp_bijective(self, group: Type[MatrixLieGroup]):
30
+ """Check 1-to-1 mapping for log <=> exp operations."""
31
+ transform = group.sample_uniform()
32
+
33
+ tangent = transform.log()
34
+ self.assertEqual(tangent.shape, (group.tangent_dim,))
35
+
36
+ exp_transform = group.exp(tangent)
37
+ assert_transforms_close(transform, exp_transform)
38
+ np.testing.assert_allclose(tangent, exp_transform.log())
39
+
40
+ def test_adjoint(self, group: Type[MatrixLieGroup]):
41
+ transform = group.sample_uniform()
42
+ omega = np.random.randn(group.tangent_dim)
43
+ assert_transforms_close(
44
+ transform @ group.exp(omega),
45
+ group.exp(transform.adjoint() @ omega) @ transform,
46
+ )
47
+
48
+ def test_rminus(self, group: Type[MatrixLieGroup]):
49
+ T_wa = group.sample_uniform()
50
+ T_wb = group.sample_uniform()
51
+ T_ab = T_wa.inverse() @ T_wb
52
+ np.testing.assert_allclose(T_wb.rminus(T_wa), T_ab.log())
53
+
54
+ def test_rplus(self, group: Type[MatrixLieGroup]):
55
+ T_wa = group.sample_uniform()
56
+ T_wb = group.sample_uniform()
57
+ T_ab = T_wa.inverse() @ T_wb
58
+ assert_transforms_close(T_wa.rplus(T_ab.log()), T_wb)
59
+
60
+ def test_jlog(self, group: Type[MatrixLieGroup]):
61
+ state = group.sample_uniform()
62
+ w = np.random.rand(state.tangent_dim) * 1e-4
63
+ state_pert = state.plus(w).log()
64
+ state_lin = state.log() + state.jlog() @ w
65
+ np.testing.assert_allclose(state_pert, state_lin, atol=1e-7)
66
+
67
+
68
+ class TestGroupSpecificOperations(absltest.TestCase):
69
+ """Group specific tests."""
70
+
71
+ def test_so3_rpy_bijective(self):
72
+ T = SO3.sample_uniform()
73
+ assert_transforms_close(T, SO3.from_rpy_radians(*T.as_rpy_radians()))
74
+
75
+
76
+ if __name__ == "__main__":
77
+ absltest.main()
@@ -0,0 +1,20 @@
1
+ import numpy as np
2
+
3
+ from ..base import MatrixLieGroup
4
+ from ..se3 import SE3, SO3
5
+
6
+
7
+ def assert_transforms_close(a: MatrixLieGroup, b: MatrixLieGroup) -> None:
8
+ np.testing.assert_allclose(a.as_matrix(), b.as_matrix(), atol=1e-7)
9
+
10
+ # Account for quaternion double cover (q = -q).
11
+ pa = a.parameters()
12
+ pb = b.parameters()
13
+ if isinstance(a, SO3):
14
+ pa *= np.sign(pa[0])
15
+ pb *= np.sign(pb[0])
16
+ elif isinstance(a, SE3):
17
+ pa[:4] *= np.sign(pa[0])
18
+ pb[:4] *= np.sign(pb[0])
19
+
20
+ np.testing.assert_allclose(pa, pb, atol=1e-7)
mink/lie/utils.py ADDED
@@ -0,0 +1,29 @@
1
+ import mujoco
2
+ import numpy as np
3
+
4
+
5
+ def get_epsilon(dtype: np.dtype) -> float:
6
+ return {
7
+ np.dtype("float32"): 1e-5,
8
+ np.dtype("float64"): 1e-10,
9
+ }[dtype]
10
+
11
+
12
+ def skew(x: np.ndarray) -> np.ndarray:
13
+ assert x.shape == (3,)
14
+ wx, wy, wz = x
15
+ return np.array(
16
+ [
17
+ [0.0, -wz, wy],
18
+ [wz, 0.0, -wx],
19
+ [-wy, wx, 0.0],
20
+ ]
21
+ )
22
+
23
+
24
+ def mat2quat(mat: np.ndarray):
25
+ """Convert a MuJoCo matrix (9,) to a quaternion (4,)."""
26
+ assert mat.shape == (9,)
27
+ quat = np.empty(4, dtype=np.float64)
28
+ mujoco.mju_mat2Quat(quat, mat)
29
+ return quat
@@ -0,0 +1,16 @@
1
+ """Kinematic limits."""
2
+
3
+ from .collision_avoidance_limit import CollisionAvoidanceLimit
4
+ from .configuration_limit import ConfigurationLimit
5
+ from .exceptions import LimitDefinitionError
6
+ from .limit import Constraint, Limit
7
+ from .velocity_limit import VelocityLimit
8
+
9
+ __all__ = (
10
+ "ConfigurationLimit",
11
+ "CollisionAvoidanceLimit",
12
+ "Constraint",
13
+ "Limit",
14
+ "VelocityLimit",
15
+ "LimitDefinitionError",
16
+ )