virtualmodelcontrol 0.1.0__tar.gz → 0.3.0__tar.gz

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 (268) hide show
  1. virtualmodelcontrol-0.3.0/.gitignore +39 -0
  2. virtualmodelcontrol-0.3.0/CHANGELOG.md +291 -0
  3. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/CITATION.cff +2 -2
  4. virtualmodelcontrol-0.3.0/PKG-INFO +167 -0
  5. virtualmodelcontrol-0.3.0/README.md +123 -0
  6. virtualmodelcontrol-0.3.0/docs/_ext/video.py +49 -0
  7. virtualmodelcontrol-0.3.0/docs/_static/create-lab.png +0 -0
  8. virtualmodelcontrol-0.3.0/docs/_static/custom.css +172 -0
  9. virtualmodelcontrol-0.3.0/docs/_static/favicon.svg +1 -0
  10. virtualmodelcontrol-0.3.0/docs/_static/logo-light.svg +1 -0
  11. virtualmodelcontrol-0.3.0/docs/_static/logo.svg +1 -0
  12. virtualmodelcontrol-0.3.0/docs/_static/readme-hero.svg +1743 -0
  13. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/docs/_templates/autosummary/module.rst +1 -1
  14. virtualmodelcontrol-0.3.0/docs/_templates/partials/toc.html +25 -0
  15. virtualmodelcontrol-0.3.0/docs/api/index.md +24 -0
  16. virtualmodelcontrol-0.3.0/docs/concepts/conventions.md +71 -0
  17. virtualmodelcontrol-0.3.0/docs/concepts/efficiency.md +140 -0
  18. virtualmodelcontrol-0.3.0/docs/concepts/finger.md +119 -0
  19. virtualmodelcontrol-0.3.0/docs/concepts/library.md +62 -0
  20. virtualmodelcontrol-0.3.0/docs/concepts/passivity.md +84 -0
  21. virtualmodelcontrol-0.3.0/docs/concepts/pcc.md +104 -0
  22. virtualmodelcontrol-0.3.0/docs/concepts/vmc.md +91 -0
  23. virtualmodelcontrol-0.3.0/docs/conf.py +110 -0
  24. virtualmodelcontrol-0.3.0/docs/development/contributing.md +81 -0
  25. virtualmodelcontrol-0.3.0/docs/development/roadmap.md +2 -0
  26. virtualmodelcontrol-0.3.0/docs/docs_setup.py +10 -0
  27. virtualmodelcontrol-0.3.0/docs/examples/finger.md +189 -0
  28. virtualmodelcontrol-0.3.0/docs/examples/hand.md +198 -0
  29. virtualmodelcontrol-0.3.0/docs/examples/hanging-arm.md +221 -0
  30. virtualmodelcontrol-0.3.0/docs/examples/soft-arm.md +278 -0
  31. virtualmodelcontrol-0.3.0/docs/examples/turtle.md +162 -0
  32. virtualmodelcontrol-0.3.0/docs/examples/two-arms.md +180 -0
  33. virtualmodelcontrol-0.3.0/docs/index.md +150 -0
  34. virtualmodelcontrol-0.3.0/docs/installation.md +134 -0
  35. virtualmodelcontrol-0.3.0/docs/schematics/__init__.py +1 -0
  36. virtualmodelcontrol-0.3.0/docs/schematics/_draw.py +107 -0
  37. virtualmodelcontrol-0.3.0/docs/schematics/bimanual.py +56 -0
  38. virtualmodelcontrol-0.3.0/docs/schematics/control_loop.py +29 -0
  39. virtualmodelcontrol-0.3.0/docs/schematics/energy_flow.py +42 -0
  40. virtualmodelcontrol-0.3.0/docs/schematics/finger.py +70 -0
  41. virtualmodelcontrol-0.3.0/docs/schematics/four_steps.py +52 -0
  42. virtualmodelcontrol-0.3.0/docs/schematics/hand.py +49 -0
  43. virtualmodelcontrol-0.3.0/docs/schematics/helyx.py +79 -0
  44. virtualmodelcontrol-0.3.0/docs/schematics/library_map.py +63 -0
  45. virtualmodelcontrol-0.3.0/docs/schematics/mechanism.py +132 -0
  46. virtualmodelcontrol-0.3.0/docs/schematics/params.py +37 -0
  47. virtualmodelcontrol-0.3.0/docs/schematics/pcc.py +40 -0
  48. virtualmodelcontrol-0.3.0/docs/schematics/turtle.py +84 -0
  49. virtualmodelcontrol-0.3.0/docs/schematics/ur5.py +105 -0
  50. virtualmodelcontrol-0.3.0/docs/scripts/readme_figure.py +51 -0
  51. virtualmodelcontrol-0.3.0/docs/troubleshooting.md +68 -0
  52. virtualmodelcontrol-0.3.0/docs/tutorials/build-a-robot.md +181 -0
  53. virtualmodelcontrol-0.3.0/docs/tutorials/configurations.md +220 -0
  54. virtualmodelcontrol-0.3.0/docs/tutorials/contact.md +199 -0
  55. virtualmodelcontrol-0.3.0/docs/tutorials/coordinates-and-components.md +161 -0
  56. virtualmodelcontrol-0.3.0/docs/tutorials/energy.md +193 -0
  57. virtualmodelcontrol-0.3.0/docs/tutorials/extend.md +193 -0
  58. virtualmodelcontrol-0.3.0/docs/tutorials/first-controller.md +161 -0
  59. virtualmodelcontrol-0.3.0/docs/tutorials/interactive.md +221 -0
  60. virtualmodelcontrol-0.3.0/docs/tutorials/introduction.md +82 -0
  61. virtualmodelcontrol-0.3.0/docs/tutorials/kinematics.md +144 -0
  62. virtualmodelcontrol-0.3.0/docs/tutorials/parameters.md +183 -0
  63. virtualmodelcontrol-0.3.0/docs/tutorials/reach.yaml +39 -0
  64. virtualmodelcontrol-0.3.0/docs/tutorials/real-time.md +232 -0
  65. virtualmodelcontrol-0.3.0/docs/tutorials/run-logs.md +306 -0
  66. virtualmodelcontrol-0.3.0/docs/tutorials/run-settings.yaml +4 -0
  67. virtualmodelcontrol-0.3.0/docs/tutorials/swaps.md +155 -0
  68. virtualmodelcontrol-0.3.0/docs/tutorials/tuning.md +202 -0
  69. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/pyproject.toml +51 -9
  70. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/__init__.py +46 -1
  71. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/_version.py +2 -2
  72. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/compiler.py +28 -10
  73. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/__init__.py +8 -0
  74. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/controllers.py +71 -0
  75. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/coordinates.py +186 -0
  76. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/experiment.py +228 -0
  77. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/files.py +67 -0
  78. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/config/spec.py +60 -0
  79. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/control/__init__.py +18 -0
  80. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/control/blending.py +81 -0
  81. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/control/controller.py +43 -5
  82. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/control/output.py +86 -0
  83. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/control/schedule.py +124 -0
  84. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/dynamics.py +3 -1
  85. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/__init__.py +38 -0
  86. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/bus.py +203 -0
  87. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/check.py +41 -0
  88. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/dynamixel.py +162 -0
  89. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/homing.py +70 -0
  90. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/hardware/profile.py +194 -0
  91. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/identification/__init__.py +7 -0
  92. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/identification/efficiency.py +45 -0
  93. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/identification/plateaus.py +31 -0
  94. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/identification/stiffness.py +70 -0
  95. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/__init__.py +25 -0
  96. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/controls.py +82 -0
  97. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/interactive.py +111 -0
  98. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/joystick.py +101 -0
  99. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/keyboard.py +64 -0
  100. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/recorder.py +87 -0
  101. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/session.py +96 -0
  102. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/interactive/window.py +205 -0
  103. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/__init__.py +20 -0
  104. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/__init__.py +18 -2
  105. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/mechanisms/components/constrained.py +68 -0
  106. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/dissipation.py +22 -0
  107. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/sources.py +25 -1
  108. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/storage.py +32 -0
  109. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/__init__.py +3 -0
  110. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/mechanisms/coordinates/geometry.py +74 -0
  111. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/__init__.py +6 -0
  112. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/actuation.py +24 -11
  113. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/assembly.py +26 -9
  114. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/models/efficiency.py +70 -0
  115. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/models/joint_space.py +33 -0
  116. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/kinematic.py +14 -3
  117. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/models/kinematics.py +93 -0
  118. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/rigid/poe.py +71 -8
  119. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/__init__.py +5 -0
  120. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/adapt.py +622 -0
  121. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/bimanual.py +178 -0
  122. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/helyx.py +158 -0
  123. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/turtle.py +99 -0
  124. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/robots/ur5.py +75 -0
  125. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/__init__.py +41 -0
  126. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/joint_io.py +52 -0
  127. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/node.py +53 -0
  128. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/params.py +43 -0
  129. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/plant.py +121 -0
  130. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/ros/twin.py +82 -0
  131. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/sim/__init__.py +21 -0
  132. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/sim/model_plant.py +13 -0
  133. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/sim/replay.py +33 -0
  134. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/sim/run.py +257 -0
  135. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/sim/runlog.py +150 -0
  136. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/system.py +3 -1
  137. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/viz/__init__.py +35 -0
  138. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/viz/animation.py +141 -0
  139. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/viz/draw.py +269 -0
  140. virtualmodelcontrol-0.3.0/src/virtualmodelcontrol/viz/style.py +91 -0
  141. virtualmodelcontrol-0.3.0/tests/config/test_config.py +396 -0
  142. virtualmodelcontrol-0.3.0/tests/control/test_blending.py +68 -0
  143. virtualmodelcontrol-0.3.0/tests/control/test_output.py +63 -0
  144. virtualmodelcontrol-0.3.0/tests/control/test_schedule.py +101 -0
  145. virtualmodelcontrol-0.3.0/tests/data/configs/finger.yaml +28 -0
  146. virtualmodelcontrol-0.3.0/tests/data/configs/hand.yaml +21 -0
  147. virtualmodelcontrol-0.3.0/tests/data/configs/soft-arm.yaml +45 -0
  148. virtualmodelcontrol-0.3.0/tests/data/configs/turtle.yaml +18 -0
  149. virtualmodelcontrol-0.3.0/tests/data/configs/two-arms.yaml +23 -0
  150. virtualmodelcontrol-0.3.0/tests/data/configs/ur5-hand.yaml +12 -0
  151. virtualmodelcontrol-0.3.0/tests/data/derivatives.npz +0 -0
  152. virtualmodelcontrol-0.3.0/tests/data/efficiency.npz +0 -0
  153. virtualmodelcontrol-0.3.0/tests/data/hand.npz +0 -0
  154. virtualmodelcontrol-0.3.0/tests/data/turtle.npz +0 -0
  155. virtualmodelcontrol-0.3.0/tests/hardware/test_dynamixel.py +164 -0
  156. virtualmodelcontrol-0.3.0/tests/hardware/test_profile.py +85 -0
  157. virtualmodelcontrol-0.3.0/tests/hardware/test_templates.py +47 -0
  158. virtualmodelcontrol-0.3.0/tests/identification/test_efficiency_fit.py +68 -0
  159. virtualmodelcontrol-0.3.0/tests/identification/test_stiffness_fit.py +27 -0
  160. virtualmodelcontrol-0.3.0/tests/interactive/conftest.py +58 -0
  161. virtualmodelcontrol-0.3.0/tests/interactive/test_controls.py +83 -0
  162. virtualmodelcontrol-0.3.0/tests/interactive/test_interactive.py +261 -0
  163. virtualmodelcontrol-0.3.0/tests/interactive/test_joystick.py +74 -0
  164. virtualmodelcontrol-0.3.0/tests/interactive/test_keyboard.py +62 -0
  165. virtualmodelcontrol-0.3.0/tests/interactive/test_session.py +127 -0
  166. virtualmodelcontrol-0.3.0/tests/interactive/test_window.py +191 -0
  167. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/mechanisms/test_components.py +15 -0
  168. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/mechanisms/test_components_golden.py +34 -9
  169. virtualmodelcontrol-0.3.0/tests/mechanisms/test_contact.py +69 -0
  170. virtualmodelcontrol-0.3.0/tests/models/test_actuation.py +92 -0
  171. virtualmodelcontrol-0.3.0/tests/models/test_efficiency.py +52 -0
  172. virtualmodelcontrol-0.3.0/tests/models/test_kinematics.py +57 -0
  173. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/robots/test_adapt.py +27 -0
  174. virtualmodelcontrol-0.3.0/tests/robots/test_bimanual.py +53 -0
  175. virtualmodelcontrol-0.3.0/tests/robots/test_hand.py +84 -0
  176. virtualmodelcontrol-0.3.0/tests/robots/test_parametric.py +136 -0
  177. virtualmodelcontrol-0.3.0/tests/robots/test_turtle.py +50 -0
  178. virtualmodelcontrol-0.3.0/tests/robots/test_ur5.py +78 -0
  179. virtualmodelcontrol-0.3.0/tests/ros/conftest.py +9 -0
  180. virtualmodelcontrol-0.3.0/tests/ros/test_joint_io.py +29 -0
  181. virtualmodelcontrol-0.3.0/tests/ros/test_ros.py +136 -0
  182. virtualmodelcontrol-0.3.0/tests/sim/test_paced.py +108 -0
  183. virtualmodelcontrol-0.3.0/tests/sim/test_record.py +201 -0
  184. virtualmodelcontrol-0.3.0/tests/sim/test_replay.py +106 -0
  185. virtualmodelcontrol-0.3.0/tests/sim/test_run.py +127 -0
  186. virtualmodelcontrol-0.3.0/tests/sim/test_runlog.py +169 -0
  187. virtualmodelcontrol-0.3.0/tests/sim/test_wallclock.py +121 -0
  188. virtualmodelcontrol-0.3.0/tests/test_deprecations.py +106 -0
  189. virtualmodelcontrol-0.3.0/tests/test_docs.py +74 -0
  190. virtualmodelcontrol-0.3.0/tests/test_import.py +47 -0
  191. virtualmodelcontrol-0.3.0/tests/test_readme.py +18 -0
  192. virtualmodelcontrol-0.3.0/tests/viz/test_animate.py +88 -0
  193. virtualmodelcontrol-0.3.0/tests/viz/test_viz.py +66 -0
  194. virtualmodelcontrol-0.1.0/.gitignore +0 -24
  195. virtualmodelcontrol-0.1.0/CHANGELOG.md +0 -40
  196. virtualmodelcontrol-0.1.0/PKG-INFO +0 -82
  197. virtualmodelcontrol-0.1.0/README.md +0 -47
  198. virtualmodelcontrol-0.1.0/docs/_static/custom.css +0 -4
  199. virtualmodelcontrol-0.1.0/docs/conf.py +0 -51
  200. virtualmodelcontrol-0.1.0/docs/development/architecture.md +0 -44
  201. virtualmodelcontrol-0.1.0/docs/development/contributing.md +0 -49
  202. virtualmodelcontrol-0.1.0/docs/getting-started/first-controller.md +0 -79
  203. virtualmodelcontrol-0.1.0/docs/getting-started/install.md +0 -50
  204. virtualmodelcontrol-0.1.0/docs/getting-started/simulate.md +0 -67
  205. virtualmodelcontrol-0.1.0/docs/how-to/add-a-model.md +0 -92
  206. virtualmodelcontrol-0.1.0/docs/how-to/extend.md +0 -111
  207. virtualmodelcontrol-0.1.0/docs/index.md +0 -57
  208. virtualmodelcontrol-0.1.0/docs/reference/api.md +0 -9
  209. virtualmodelcontrol-0.1.0/docs/reference/conventions.md +0 -75
  210. virtualmodelcontrol-0.1.0/docs/robots/helyx.md +0 -42
  211. virtualmodelcontrol-0.1.0/docs/theory/mechanisms.md +0 -61
  212. virtualmodelcontrol-0.1.0/docs/theory/pcc.md +0 -64
  213. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/control/__init__.py +0 -5
  214. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/robots/__init__.py +0 -5
  215. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/robots/adapt.py +0 -98
  216. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/robots/helyx.py +0 -79
  217. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/sim/__init__.py +0 -7
  218. virtualmodelcontrol-0.1.0/src/virtualmodelcontrol/sim/run.py +0 -73
  219. virtualmodelcontrol-0.1.0/tests/models/test_actuation.py +0 -52
  220. virtualmodelcontrol-0.1.0/tests/sim/test_run.py +0 -59
  221. virtualmodelcontrol-0.1.0/tests/test_import.py +0 -13
  222. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/LICENSE +0 -0
  223. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/benchmarks/tick.py +0 -0
  224. {virtualmodelcontrol-0.1.0/docs/reference → virtualmodelcontrol-0.3.0/docs/development}/changelog.md +0 -0
  225. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/__init__.py +0 -0
  226. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/params.py +0 -0
  227. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/registry.py +0 -0
  228. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/signals.py +0 -0
  229. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/space.py +0 -0
  230. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/symbolic.py +0 -0
  231. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/core/units.py +0 -0
  232. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/base.py +0 -0
  233. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/components/inertance.py +0 -0
  234. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/base.py +0 -0
  235. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/frames.py +0 -0
  236. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/joints.py +0 -0
  237. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/ops.py +0 -0
  238. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/coordinates/references.py +0 -0
  239. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/mechanisms/mechanism.py +0 -0
  240. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/continuum/__init__.py +0 -0
  241. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/continuum/pcc.py +0 -0
  242. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/rigid/__init__.py +0 -0
  243. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/models/rigid/couplings.py +0 -0
  244. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/py.typed +0 -0
  245. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/src/virtualmodelcontrol/sim/plant.py +0 -0
  246. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/conftest.py +0 -0
  247. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/control/test_honesty.py +0 -0
  248. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/control/test_vmc_golden.py +0 -0
  249. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/core/test_params.py +0 -0
  250. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/core/test_registry.py +0 -0
  251. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/core/test_signals.py +0 -0
  252. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/core/test_space.py +0 -0
  253. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/core/test_symbolic.py +0 -0
  254. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/data/components.npz +0 -0
  255. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/data/dynamics.npz +0 -0
  256. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/data/finger.npz +0 -0
  257. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/data/pcc.npz +0 -0
  258. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/data/vmc.npz +0 -0
  259. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/helpers.py +0 -0
  260. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/mechanisms/test_coordinates.py +0 -0
  261. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/mechanisms/test_mechanism.py +0 -0
  262. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/models/test_assembly.py +0 -0
  263. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/models/test_pcc.py +0 -0
  264. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/models/test_poe.py +0 -0
  265. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/robots/test_helyx.py +0 -0
  266. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/test_benchmark.py +0 -0
  267. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/test_compiler.py +0 -0
  268. {virtualmodelcontrol-0.1.0 → virtualmodelcontrol-0.3.0}/tests/test_dynamics.py +0 -0
@@ -0,0 +1,39 @@
1
+ # Environments
2
+ .venv/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.egg-info/
8
+ build/
9
+ dist/
10
+
11
+ # Generated
12
+ src/virtualmodelcontrol/_version.py
13
+ docs/_build/
14
+ docs/jupyter_execute/
15
+
16
+ # Tool caches
17
+ .pytest_cache/
18
+ .mypy_cache/
19
+ .ruff_cache/
20
+ .ipynb_checkpoints/
21
+
22
+ # Papers stay out of the repository
23
+ *.pdf
24
+ docs/api/generated/
25
+ # Animations written by the docs build
26
+ docs/**/*.mp4
27
+ docs/**/*.gif
28
+ docs/**/*.webp
29
+ # Run logs and files written by the docs build
30
+ docs/**/*.npz
31
+ docs/**/*.csv
32
+ docs/tutorials/logs/
33
+ docs/tutorials/reach-stiffer.yaml
34
+ docs/tutorials/walk.yaml
35
+ docs/tutorials/again.yaml
36
+ docs/tutorials/session.yaml
37
+
38
+ # Lock file written by editor tooling; the project pins nothing
39
+ uv.lock
@@ -0,0 +1,291 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
5
+ [Semantic Versioning](https://semver.org/) (0.x: the API may still change between minor
6
+ versions, with one minor version of deprecation before a removal).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.0] - 2026-10-05
11
+
12
+ ### Added
13
+
14
+ - `vmc.config`: experiments in YAML files. `vmc.config.load` reads the robot (a template and its
15
+ arguments), named coordinates, the controller's elements (a registered component `type`, the
16
+ `coordinate` it acts on, its gains), controllers to swap to, and how to run them: a simulation
17
+ (with the robot's dynamics and simulated elements such as contacts), the rate, the duration,
18
+ output stages, schedules and the initial virtual state.
19
+ `Experiment.run` runs it, `save` writes it back with the Params' current values. Robot
20
+ templates, output stages and coordinate kinds are registry entries, so a project adds its own.
21
+ An experiment from a file gives the same run as the same experiment written in Python.
22
+ - `vmc.control.Schedule` and `ScheduledController`: live Params that follow values over time
23
+ (in straight lines or steps) and swaps at given times; a new run starts afresh. The lab's
24
+ linear ramps are two-point schedules.
25
+ - `vmc.sim.run(..., z0=...)` also takes a function of the first reading, such as
26
+ `turtle.initial_state`.
27
+ - Docs: tutorial "Experiments in files".
28
+ - Run logs. `vmc.sim.RunLog` saves a run whole or not at all (`save`: a compressed `.npz` with a
29
+ schema version and what the run was, in `meta`: the library's version, the start time, the
30
+ Params at the start, the plant's hardware profile and, from a configuration, the
31
+ configuration; written through a temporary file, and a name already taken is refused unless
32
+ `overwrite=True`), loads it back (`load`) and exports CSV (`to_csv`, one column per entry).
33
+ `step` adds one step and keeps every signal at one row per step, with NaN for what a step
34
+ did not compute.
35
+ - `vmc.sim.replay` sends a log's motor torques again to a simulated robot, each held for as long
36
+ as it was in the run, from the log's `q` and `v` or, for a real robot's log, from its first
37
+ motor reading (`ModelPlant.state_from_motors`); `vmc.sim.compare` gives the largest and the
38
+ root-mean-square difference of each signal of two runs. A replay on the true model gives the
39
+ run back.
40
+ - A run's log holds `law_torque`, the controller's torque before the output stages.
41
+ `vmc.sim.run(..., record=...)` adds the live Params (`"params"`), each element's coordinate,
42
+ rate, force and share of the motor torques (`"elements"`), and the controller's energies and
43
+ powers (`"energy"`), from `VMCController.elements()` and `balance()`.
44
+ - Configurations: `experiment.run` settings (`name`, `folder`, `overwrite`, `record`) save each
45
+ run beside the file and refuse a name already taken before the run starts.
46
+ - Docs: tutorial "Run logs".
47
+ - `vmc.interactive`: change a running controller by hand. `Controls` is a thread-safe mailbox
48
+ for new values of live Params and for swaps. `Interactive` wraps any controller and applies
49
+ what the mailbox holds just before each step, in a simulation or inside a robot's own node;
50
+ the changes act exactly as `controller.set` before the step, and it counts the energy they give
51
+ the running controller (`injected`). `Recorder` turns what was applied into `schedule` entries
52
+ with `step` interpolation and saves them into a configuration, which repeats the session
53
+ exactly. `Window` (matplotlib, no new dependency) draws the robot live, with goals to drag,
54
+ sliders, buttons to swap controllers, record and pause; `Keyboard` and `Joystick` (pygame, the
55
+ extra `virtualmodelcontrol[joystick]`) move a goal; `Session` runs a simulation in real time
56
+ in a worker thread with its window.
57
+ - `vmc.sim.SimClock(dt, speed=...)` paces a simulation to the computer's clock: with `speed`,
58
+ `run(T=None)` runs until stopped and Ctrl-C ends it with the log so far. Other simulations are
59
+ unchanged. `VMCController.live_params()` and `Experiment.z0()`.
60
+ - Docs: tutorial "Interactive control".
61
+ - Docs: tutorials "Real-time runs" (the loop on the computer's clock: measured steps, late steps
62
+ never caught up in a burst, old and missing readings, Ctrl-C, and a checklist for the first run
63
+ on a robot) and "Swaps and schedules" (the quintic blend and its continuity, a swap on the soft
64
+ arm, the schedules' interpolation).
65
+ - `vmc.ros.control`: the controller node. It runs a controller at the profile's rate on the
66
+ robot behind the driver's topics, with its live Params as ROS parameters, for a duration or
67
+ until Ctrl-C, and ends with zero torque.
68
+ - On real time (`WallClock`), `vmc.sim.run(..., T=None)` runs until Ctrl-C, and Ctrl-C ends
69
+ a real-time run with the log so far.
70
+ - CI runs the ROS tests in ROS 2 Humble and Jazzy containers, on a private domain.
71
+ - `vmc.control.SwapController` and `blend_weight`: one set of virtual elements replaces another
72
+ with a quintic blend of the two controllers' torques (continuous torque and first two
73
+ derivatives), the blend the lab's controller uses; a swap asked for during a blend waits for
74
+ it. `vmc.ros.control(..., swaps={name: controller})` swaps on a `String` message.
75
+ - `vmc.Efficiency`: the motor torque a transmission delivers, as a polynomial of the commanded
76
+ one, τ = c₁u + c₂u² + … + cₙuⁿ, each coefficient one value for every motor or one per motor.
77
+ The coefficients are `design` Params, to change, tune, keep live in a simulator or identify.
78
+ `Direct` and `TendonTransmission` take one, or a number for its linear coefficient.
79
+ - `vmc.identification`: `plateaus`, the settled end of every hold of a command in a log, and
80
+ `fit_efficiency`, a least-squares fit through the origin, motor by motor or shared, from
81
+ delivered torques or from one measured quantity with a weight per motor (a fingertip force,
82
+ say). Both agree with the lab's calibration code, and the fit gives the finger's
83
+ `adapt.MOTOR_EFFICIENCY` back from its recorded data.
84
+ - Docs: concepts pages "Transmission efficiency", "Virtual Model Control" (coordinates, forces,
85
+ the torques that realize them, virtual states), "Passivity" (the energy balances, stability,
86
+ what weakens it) and "Finger and hand kinematics" (motors to joints, joints to the
87
+ fingertip, the hand's couplings).
88
+ - The constrained elements as components of their own: `ConstrainedLinearSpring`,
89
+ `ConstrainedTanhSpring`, `ConstrainedGaussianSpring`, `ConstrainedLinearDamper` and
90
+ `ConstrainedTanhDamper` act along one direction (`normal`) only, leaving the plane normal to
91
+ it free. They give the forces of the lab's constrained elements, checked against them; the
92
+ tanh ones saturate along the normal rather than axis by axis.
93
+ - `vmc.identification.fit_stiffness_damping`: a robot's diagonal stiffness and damping from
94
+ logged runs under known motor torques, by least squares with K, D ≥ 0 in motor torques,
95
+ relative to a resting baseline, with the robot's masses and gravity known; each run can carry
96
+ its own gravity. It recovers the stiffness and damping of a simulated arm within a few percent.
97
+ - Docs: two single-arm examples, each about its own arm and its own experiments. The soft arm on
98
+ its side (`145-145-145`) reaches past an obstacle with two repulsive fields, over a sweep of
99
+ their strength, and a tanh spring limits the force on a string tied to the tip. The hanging
100
+ arm (`145-290-290`) is identified from simulated step responses with
101
+ `fit_stiffness_damping` and reaches around an obstacle with a tanh spring and two fields.
102
+ Both use the same stiffness and damping. The tutorials, the home page and the README use the
103
+ arm on its side; the Helyx geometries and the parametric template are on the soft-arm
104
+ kinematics page.
105
+
106
+ ### Changed
107
+
108
+ - Every robot's efficiency is 1 by default: models identified from the commanded torques
109
+ already include their transmission. The soft arm and the two arms take each torque as the
110
+ controller sends it again, with `helyx.SIM_STIFFNESS`, `helyx.SIM_DAMPING`,
111
+ `bimanual.STIFFNESS` and `bimanual.DAMPING` referred to the commanded torque (the identified
112
+ values divided by the 0.12 they were fitted with), as in 0.1.0. 0.2.0 applied 0.12 to every
113
+ torque with physical stiffness and damping: the same equilibria without gravity, but natural
114
+ frequencies about 2.9 times lower and a gravity compensation that cancelled only 12 % of the
115
+ weight. `helyx.EFFICIENCY`, `bimanual.EFFICIENCY`, `adapt.MOTOR_EFFICIENCY` and
116
+ `adapt.HAND_MOTOR_EFFICIENCY` stay as calibrations, never as defaults.
117
+ - A transmission's efficiency Param is now `efficiency.c1` (and `c2`, … for a polynomial);
118
+ transmissions saved by 0.2.0 still load.
119
+ - `import virtualmodelcontrol` no longer loads SciPy, which took about three quarters of its
120
+ import time; `identification.fit_stiffness_damping` loads it when called.
121
+ - Docs: the opening page has no left index (the pages of the five sections keep theirs) and
122
+ leads to the concepts and the reference. Installation: the conda recipe takes Python from
123
+ conda-forge, because conda's default channels stop a new installation until Anaconda's terms of
124
+ service are accepted, and shows how to keep ROS's `PYTHONPATH` out of a conda environment, where
125
+ pip otherwise ends with an error about ROS's packages and skips the ones ROS also ships.
126
+
127
+ ### Deprecated
128
+
129
+ - `vmc.ros` (`RosPlant`, `control`, `serve`, `LiveParams`, `JointIO`, `TOPICS`) and the direct
130
+ Dynamixel path (`hardware.DynamixelPlant`, `home`, `present_ticks`, `scan`, `latency_timer`,
131
+ `Bus`, `SdkBus`, `FakeBus`) warn when used, and leave in 0.4.0 together with the Dynamixel SDK
132
+ and pyserial dependencies and the ROS CI job. The library is communication-agnostic: it turns
133
+ measurements into torques, and how they reach the robot stays outside it. Hardware profiles
134
+ (`HardwareProfile`, `Motor`, `KT`, `MODES` and each robot's `hardware` template) stay. Python
135
+ shows a `DeprecationWarning` only for code run as a script or in a notebook; run a node with
136
+ `python -W default` to see them there.
137
+
138
+ ### Fixed
139
+
140
+ - `vmc.sim.run` needs only the plant's documented methods: when its guard trips, it sends zero
141
+ torque without reading the plant's last command `u`, which a plant of one's own may not have.
142
+ The zero command has one torque per motor rate, also on real time.
143
+ - `vmc.ros` is available after `import virtualmodelcontrol as vmc`, like `vmc.viz` and
144
+ `vmc.hardware`; it imports ROS only when a ROS class is first used.
145
+ - The hand example grasps the ball with the pads of the thumb, index and middle fingers: the
146
+ ball sits where the thumb opposes the fingers, and the grasp takes the thumb's tip at the end
147
+ of its last phalanx. Before, the thumb pressed on the ball with its side. The template's
148
+ kinematics are unchanged.
149
+ - Figure labels written as math where the figure font has no glyph (N·m on the efficiency
150
+ page); a test keeps figure text to characters the font draws.
151
+
152
+ ## [0.2.0] - 2026-10-04
153
+
154
+ ### Added
155
+
156
+ - Every dependency installs with the package: numpy, SciPy, CasADi, matplotlib, PyYAML, the
157
+ Dynamixel SDK and pyserial. CI runs on Ubuntu 22.04 and 24.04, with a clean-install job.
158
+ - Robot templates: `robots.bimanual` (two Helyx arms on one frame, with their identified
159
+ stiffness and damping and the transmission efficiency 0.12), `robots.adapt.hand` (five digits,
160
+ 13 motors, spread coupling, masses and joint limits), `robots.turtle` (two cranks and the
161
+ virtual-flywheel controller), `robots.ur5` (from DH parameters) and `ur5.with_hand()`.
162
+ - Every template is parametric in its geometry, with today's values as defaults:
163
+ `helyx.arm(lengths=..., section_radius=..., spool_radius=..., tendon_angles=..., masses=...)`
164
+ for any number of segments; `bimanual.arms(lengths=..., tendon_angles=...,
165
+ base_positions=..., efficiency=...)`, each one for both arms or by arm;
166
+ `adapt.finger(link_lengths=..., link_masses=..., link_cogs=..., joint_axes=...,
167
+ motor_radius=..., pulley_radius=..., pip_transmission=...)` and `adapt.finger_coupling`;
168
+ `adapt.hand(...)` and `ur5.with_hand(...)`, which replace any entry of the hand's geometry
169
+ tables by key (`tip_offsets={"thumb": ...}`), with the hand's mounting position on the
170
+ flange; `ur5.arm(d=..., a=..., alpha=...)`; joint-limit springs with custom ranges; output
171
+ stages and `add_dynamics` sized to the arm.
172
+ - `vmc.Kinematics`: positions, rotations, Jacobians, angular Jacobians and Hessians of any site,
173
+ from configuration or from motor angles.
174
+ - `models.JointSpace` for robots described by their joints only; `SerialChain.from_dh` and site
175
+ rotations; `Assembly` parts mounted on another part's frame.
176
+ - `TendonTransmission(efficiency=...)` and `Direct(efficiency=...)` (one value or one per
177
+ motor): the robot receives the commanded torque times the efficiency. `adapt.finger`,
178
+ `adapt.hand` and `ur5.with_hand` take `efficiency=...` and stay lossless by default: the
179
+ measured `adapt.MOTOR_EFFICIENCY` and `adapt.HAND_MOTOR_EFFICIENCY` are static calibrations for
180
+ force estimates, and unequal efficiencies on coupled motors make virtual elements
181
+ non-conservative in simulation.
182
+ - `SpeedRegulator`: drives a virtual state at a commanded speed, with a ramp.
183
+ - `control.output`, opt-in output stages for real hardware: `FrictionCompensation`,
184
+ `Pretension`, `TorqueOffset`, `TorqueLimit`; each template's own stage
185
+ (`helyx.output_stage()`, `bimanual.output_stage()`, `adapt.output_stage()`,
186
+ `adapt.hand_output_stage()`).
187
+ - `vmc.viz`: the lab figure style (`use_style`, `save` as PDF and SVG) and drawing helpers
188
+ (`draw_robot`, `draw_spring`, `draw_damper`, `draw_frame`, `draw_force`, `draw_goal`,
189
+ `label_axes`). `vmc.viz` is available after `import virtualmodelcontrol as vmc` and loads
190
+ matplotlib only when first used.
191
+ - `vmc.viz.animate`: an animation of a run (the robot, springs to fixed points, the path of a
192
+ site, anything else through a callback), saved as MP4, GIF or animated WebP. `imageio-ffmpeg`
193
+ is now a dependency, so MP4 works on every system.
194
+ - `vmc.sim.run(..., z0=...)` starts the controller from a given virtual state, and the run log
195
+ records the virtual state `z` when the controller has one.
196
+ - Contact as stiff one-sided springs: signed distances `PlaneDistance` and `SphereDistance`,
197
+ `ContactSpring` (optional smoothing for optimization) and `ContactDamper` (damps only in
198
+ contact); `adapt.add_dynamics` gives the finger and the hand their gravity for simulation.
199
+ - Documentation rebuilt for students: the Material layout (sections as tabs, the pages of each
200
+ section in the left sidebar), large type, the library's logo and navy colours;
201
+ installation and troubleshooting; tutorials (how it works, a first controller, coordinates
202
+ and components, parameters, energy, kinematics, tuning, contact, building a robot, extending
203
+ the library); an example per robot (soft arm, two arms, finger, hand and the UR5, turtle), each
204
+ opening with its robot's schematic and parameters; concepts (the library's structure, soft-arm
205
+ kinematics, conventions and glossary). Every figure, schematic, table value and animation is
206
+ computed when the documentation builds.
207
+ - `vmc.hardware.HardwareProfile`: the motors of a robot (bus ID, Dynamixel model, sign, mode,
208
+ motor constant, optional torque limit) in the library's motor order, with the bus settings;
209
+ conversions both ways between encoder ticks, raw velocities, goal currents and the published
210
+ degrees of a ROS driver and SI units, with commands clamped before the integer conversion so
211
+ they saturate instead of overflowing; saved and loaded as YAML. Each template has its
212
+ profile: `helyx.hardware()`, `bimanual.hardware()`, `adapt.finger_hardware()`,
213
+ `adapt.hand_hardware()`, `turtle.hardware()`.
214
+ - `vmc.hardware.DynamixelPlant`: a robot's Dynamixel motors as a plant through the Dynamixel
215
+ SDK, without ROS. It sets a safe goal before each motor's torque goes on, takes the start
216
+ positions as zero, reads angles and smoothed rates, writes torques as clamped goal currents,
217
+ sends zero torque when commands stop (a watchdog), and on leaving (exceptions and Ctrl-C
218
+ included) sends zero torque and switches the torque motors off; held motors keep their
219
+ position. `hardware.home` drives the motors slowly to recorded home positions and refuses a
220
+ motor that lost a turn; `hardware.scan` finds the motors and their baud rate;
221
+ `hardware.FakeBus` stands in for the bus in tests and dry runs.
222
+ - `vmc.sim.WallClock`: `vmc.sim.run` on real time, the loop of simulation unchanged. Each step
223
+ runs on the computer's clock with its measured time; a reading older than `stale` sends
224
+ zero torque; a late step starts the next one from now instead of catching up; the log
225
+ records each step's `dt`, and `log.info` the rate, the slowest step, the overruns and the
226
+ stale readings, with a warning when steps overran.
227
+ - `virtualmodelcontrol.ros` (ROS 2, any distribution; rclpy and std_msgs, loaded only when
228
+ used): `RosPlant`, the robot behind the lab driver's topics (degrees, the bus order, raw
229
+ signs, torques kept within the range of the driver's goal current); `serve`, a digital twin
230
+ that publishes a simulated robot on the same topics, with a lockstep mode in which a run over
231
+ ROS repeats the simulator's; `LiveParams`, a controller's live Params as ROS parameters,
232
+ applied between steps.
233
+
234
+ ### Changed
235
+
236
+ - The soft arm models the efficiency of its tendons: it receives η = 0.12 times the commanded
237
+ torque (`helyx.EFFICIENCY`), and `helyx.SIM_STIFFNESS` and `helyx.SIM_DAMPING` are the
238
+ identified, physical values. 0.1.0 divided them by 0.12 and delivered the full torque: the
239
+ same equilibria without gravity, but natural frequencies about 2.9 times too high and a sag
240
+ under gravity about 8 times too small. Controllers are unchanged and never divide their
241
+ torques by η, so the simulated arm receives η of every command, gravity compensation
242
+ included.
243
+ - The figure style without LaTeX uses matplotlib's own Computer Modern font (`cmr10`) instead
244
+ of DejaVu Serif, with tick labels set as math. Figures made with LaTeX are unchanged.
245
+
246
+ ### Fixed
247
+
248
+ - `RunLog` copies each row, so a signal updated in place (a controller's virtual state) is
249
+ recorded correctly at every step.
250
+ - `bimanual.add_dynamics` takes the stiffness and damping of one arm (a dict by arm, arrays
251
+ included) and keeps the other arm's identified values.
252
+ - `viz.draw_robot`: no joint markers along continuum arms mounted in an assembly; robots without
253
+ geometry (joint-space models) draw nothing instead of failing; serial chains end at their
254
+ `tool` site (the UR5 flange) as well as at a `tip`.
255
+
256
+ ## [0.1.0] - 2026-10-04
257
+
258
+ First public release.
259
+
260
+ ### Added
261
+
262
+ - Package scaffold: `pyproject.toml` (hatchling + hatch-vcs), tests, docs, CI workflows.
263
+ - `core`: `Param` and `ParamSet` with scopes (fixed, design, episode, stage) and a `Binding` that
264
+ keeps live Params symbolic and folds the rest in; spaces `Euclidean`, `SO2`, `Product`;
265
+ symbolic helpers; `Signals`; a registry with plugin entry points; unit strings.
266
+ - `mechanisms`: coordinates (`FramePoint`, `Joint`, `State`, `Ref`, `Difference`, `Slice`,
267
+ `Stack`, `Projection`, `Norm`, `Custom`), components (linear, tanh, Gaussian, sigmoid,
268
+ polynomial and limit springs; linear and tanh dampers; `PointMass`, `Inertance`; `ForceSource`,
269
+ `GravityCompensation`) and `Mechanism`. A tanh spring on a projection saturates at its maximum
270
+ force in every direction.
271
+ - `models`: parametric `PCC` with n segments, `TendonTransmission` (θ > 0 pulls), `Direct`
272
+ drive, and `SerialChain` (product of exponentials).
273
+ - `robots.helyx`: the three Helyx arm geometries with their default parameters.
274
+ - `VirtualMechanismSystem`, `compile()` and `VMCController`: about 20 µs per control step for
275
+ three springs and three dampers on a three-segment arm (`benchmarks/tick.py`).
276
+ - `compile_dynamics()`: robot dynamics assembled from the robot's components (canonical
277
+ residual, mass matrix, energy, power, linearly implicit Euler step); `Gravity` component.
278
+ - `sim`: `Plant` and `SimPlant` protocols, `ModelPlant`, `run()` with a `Guard` (zero torque on
279
+ missing or non-finite readings) and a `RunLog`.
280
+ - `models.Actuation` protocol; `helyx.add_dynamics` with the simulated arm's stiffness and
281
+ damping.
282
+ - Docs: closed-loop simulation tutorial and an "Extend the library" how-to.
283
+ - `models.LinearCoupling` (one motor driving several joints), `models.Assembly` (several models
284
+ mounted on one base) with `StackedActuation`; `FramePoint` accepts a part and an arc parameter.
285
+ - `robots.adapt`: the ADAPT finger (two motors, coupled distal joints), joint-angle coordinate
286
+ and joint-limit spring.
287
+
288
+ [Unreleased]: https://github.com/vigno0405/VirtualModelControl/compare/v0.3.0...HEAD
289
+ [0.3.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.2.0...v0.3.0
290
+ [0.2.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.1.0...v0.2.0
291
+ [0.1.0]: https://github.com/vigno0405/VirtualModelControl/releases/tag/v0.1.0
@@ -1,8 +1,8 @@
1
1
  cff-version: 1.2.0
2
2
  message: "If you use this software, please cite it as below."
3
3
  type: software
4
- version: 0.1.0
5
- date-released: "2026-10-04"
4
+ version: 0.3.0
5
+ date-released: "2026-10-05"
6
6
  title: "virtualmodelcontrol: Virtual Model Control for robots"
7
7
  authors:
8
8
  - family-names: Vignoli
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.5
2
+ Name: virtualmodelcontrol
3
+ Version: 0.3.0
4
+ Summary: Virtual Model Control: robots and controllers as mechanisms of springs, dampers and inertances, compiled with CasADi.
5
+ Project-URL: Repository, https://github.com/vigno0405/VirtualModelControl
6
+ Project-URL: Documentation, https://vigno0405.github.io/VirtualModelControl/
7
+ Author: Lorenzo Vignoli
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: casadi,control,passivity,robotics,soft robots,virtual model control
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: casadi>=3.6
24
+ Requires-Dist: dynamixel-sdk>=3.7
25
+ Requires-Dist: imageio-ffmpeg>=0.5
26
+ Requires-Dist: matplotlib>=3.8
27
+ Requires-Dist: numpy>=1.26
28
+ Requires-Dist: pyserial>=3.5
29
+ Requires-Dist: pyyaml>=6
30
+ Requires-Dist: scipy>=1.11
31
+ Provides-Extra: dev
32
+ Requires-Dist: import-linter>=2.0; extra == 'dev'
33
+ Requires-Dist: mypy>=1.10; extra == 'dev'
34
+ Requires-Dist: pre-commit>=3.5; extra == 'dev'
35
+ Requires-Dist: pytest>=8; extra == 'dev'
36
+ Requires-Dist: ruff>=0.6; extra == 'dev'
37
+ Provides-Extra: docs
38
+ Requires-Dist: myst-nb>=1.1; extra == 'docs'
39
+ Requires-Dist: sphinx-immaterial>=0.13; extra == 'docs'
40
+ Requires-Dist: sphinx>=7.2; extra == 'docs'
41
+ Provides-Extra: joystick
42
+ Requires-Dist: pygame>=2.5; extra == 'joystick'
43
+ Description-Content-Type: text/markdown
44
+
45
+ <a href="https://www.epfl.ch/labs/create/"><img align="right" height="72" src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/create-lab.png" alt="CREATE Lab, EPFL"></a>
46
+
47
+ # VirtualModelControl
48
+
49
+ `virtualmodelcontrol` is a Python library for Virtual Model Control. You build a controller by
50
+ attaching virtual springs, dampers and masses to your robot, and the library turns them into
51
+ motor torques at the control rate, in simulation and on the real robot.
52
+
53
+ <p align="center">
54
+ <a href="https://vigno0405.github.io/VirtualModelControl/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/logo-light.svg"><img src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/logo.svg" height="64" align="middle" alt="virtualmodelcontrol logo"></picture></a>
55
+ &nbsp;
56
+ <a href="https://vigno0405.github.io/VirtualModelControl/"><img src="https://img.shields.io/badge/Documentation-tutorials%20%C2%B7%20examples%20%C2%B7%20API-3c5488?style=for-the-badge&labelColor=13294b" align="middle" alt="Documentation: tutorials, examples, API"></a>
57
+ </p>
58
+
59
+ <p align="center">
60
+ <img src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/readme-hero.svg" width="820" alt="A soft arm whose tip a virtual spring pulls towards a goal, and the distance from the tip to the goal over time">
61
+ </p>
62
+
63
+ ## Install
64
+
65
+ ```bash
66
+ pip install virtualmodelcontrol
67
+ ```
68
+
69
+ The newest code, from GitHub, before it is released (the same line updates an existing install):
70
+
71
+ ```bash
72
+ pip install --upgrade "git+https://github.com/vigno0405/VirtualModelControl.git"
73
+ ```
74
+
75
+ Virtual environments, conda, ROS 2 and pinned versions are covered in [Installation][install].
76
+
77
+ ## Requirements
78
+
79
+ Python 3.10 or newer, tested with 3.10 to 3.14 on Ubuntu 22.04 and 24.04. Nothing to compile;
80
+ ROS and LaTeX are not needed.
81
+
82
+ ## Dependencies
83
+
84
+ pip installs them with the library:
85
+
86
+ | Package | Version | Used for |
87
+ | --- | --- | --- |
88
+ | [numpy](https://numpy.org) | 1.26 or newer, 2.x included | arrays |
89
+ | [CasADi](https://web.casadi.org) | 3.6 or newer | the symbolic models, their derivatives and the compiled controllers |
90
+ | [SciPy](https://scipy.org) | 1.11 or newer | rotations of chains built from DH tables; fitting stiffness and damping |
91
+ | [matplotlib](https://matplotlib.org) | 3.8 or newer | figures and animations |
92
+ | [imageio-ffmpeg](https://github.com/imageio/imageio-ffmpeg) | 0.5 or newer | MP4 videos of the animations |
93
+ | [PyYAML](https://pyyaml.org) | 6 or newer | robot and hardware files |
94
+ | [Dynamixel SDK](https://github.com/ROBOTIS-GIT/DynamixelSDK) | 3.7 or newer | Dynamixel motors (leaves in 0.4.0) |
95
+ | [pyserial](https://github.com/pyserial/pyserial) | 3.5 or newer | the serial port of the Dynamixel SDK (leaves in 0.4.0) |
96
+
97
+ ## The example in the figure
98
+
99
+ The robot and the controller are two separate mechanisms: the robot mechanism describes the
100
+ hardware, and the controller holds the virtual elements placed on it.
101
+
102
+ ```python
103
+ import numpy as np
104
+ import virtualmodelcontrol as vmc
105
+ from virtualmodelcontrol.robots import helyx
106
+
107
+ arm = helyx.arm("145-145-145") # a soft arm with nine tendon motors
108
+ tip = arm.point(s=1.0)
109
+
110
+ ctrl = vmc.Mechanism("ctrl")
111
+ ctrl.add("reach", vmc.LinearSpring(tip - [0.15, 0.0, 0.35], 600.0)) # [N/m]
112
+ ctrl.add("damp", vmc.LinearDamper(tip, 5.0)) # [N·s/m]
113
+ ctrl.add("gravity", vmc.GravityCompensation(arm))
114
+ controller = vmc.VMCController(vmc.compile(vmc.VirtualMechanismSystem(arm, ctrl)))
115
+
116
+ meas = vmc.Signals(0.0, motor_position=np.zeros(9), motor_velocity=np.zeros(9))
117
+ torques = controller.step(0.0, meas)["motor_torque"] # [N·m], one per motor
118
+ ```
119
+
120
+ The same controller runs on a simulation built from the robot's own masses, stiffness and
121
+ damping; [readme_figure.py][figure] draws the figure from this run.
122
+
123
+ ```python
124
+ arm = helyx.add_dynamics(arm)
125
+ plant = vmc.sim.ModelPlant(arm)
126
+ log = vmc.sim.run(plant, controller, vmc.sim.SimClock(dt=1 / 330), T=3.0)
127
+ ```
128
+
129
+ ## Examples
130
+
131
+ Each example builds a ready-made robot, controls it in simulation and animates the run:
132
+
133
+ - [Soft arm][soft-arm]: reach past an obstacle, and limit the force with a tanh spring.
134
+ - [Hanging soft arm][hanging-arm]: identify its stiffness and damping, and reach around an
135
+ obstacle.
136
+ - [Two arms][two-arms]: squeeze an object between the tips of two soft arms.
137
+ - [Finger][finger]: a stiff fingertip and soft joint limits.
138
+ - [Hand][hand]: grasp a ball, alone or mounted on a UR5 arm.
139
+ - [Turtle][turtle]: two cranks that follow a virtual flywheel.
140
+
141
+ ## Documentation
142
+
143
+ The [documentation][docs] holds the tutorials, the examples, the concepts and the API. What
144
+ changed is in the [changelog][changelog], what comes next in the [roadmap][roadmap], and how to
145
+ contribute in [Contributing][contributing].
146
+
147
+ ## Authors
148
+
149
+ Lorenzo Vignoli, at the [CREATE Lab][lab] of EPFL (Prof. Josie Hughes), in a collaboration
150
+ with the University of Cambridge (Prof. Fulvio Forni). To cite the library, see [CITATION.cff][cite].
151
+ The code is under the [MIT license][license].
152
+
153
+ [lab]: https://www.epfl.ch/labs/create/
154
+ [install]: https://vigno0405.github.io/VirtualModelControl/installation.html
155
+ [figure]: https://github.com/vigno0405/VirtualModelControl/blob/main/docs/scripts/readme_figure.py
156
+ [soft-arm]: https://vigno0405.github.io/VirtualModelControl/examples/soft-arm.html
157
+ [hanging-arm]: https://vigno0405.github.io/VirtualModelControl/examples/hanging-arm.html
158
+ [two-arms]: https://vigno0405.github.io/VirtualModelControl/examples/two-arms.html
159
+ [finger]: https://vigno0405.github.io/VirtualModelControl/examples/finger.html
160
+ [hand]: https://vigno0405.github.io/VirtualModelControl/examples/hand.html
161
+ [turtle]: https://vigno0405.github.io/VirtualModelControl/examples/turtle.html
162
+ [docs]: https://vigno0405.github.io/VirtualModelControl/
163
+ [changelog]: https://vigno0405.github.io/VirtualModelControl/development/changelog.html
164
+ [roadmap]: https://vigno0405.github.io/VirtualModelControl/development/roadmap.html
165
+ [contributing]: https://vigno0405.github.io/VirtualModelControl/development/contributing.html
166
+ [cite]: https://github.com/vigno0405/VirtualModelControl/blob/main/CITATION.cff
167
+ [license]: https://github.com/vigno0405/VirtualModelControl/blob/main/LICENSE
@@ -0,0 +1,123 @@
1
+ <a href="https://www.epfl.ch/labs/create/"><img align="right" height="72" src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/create-lab.png" alt="CREATE Lab, EPFL"></a>
2
+
3
+ # VirtualModelControl
4
+
5
+ `virtualmodelcontrol` is a Python library for Virtual Model Control. You build a controller by
6
+ attaching virtual springs, dampers and masses to your robot, and the library turns them into
7
+ motor torques at the control rate, in simulation and on the real robot.
8
+
9
+ <p align="center">
10
+ <a href="https://vigno0405.github.io/VirtualModelControl/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/logo-light.svg"><img src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/logo.svg" height="64" align="middle" alt="virtualmodelcontrol logo"></picture></a>
11
+ &nbsp;
12
+ <a href="https://vigno0405.github.io/VirtualModelControl/"><img src="https://img.shields.io/badge/Documentation-tutorials%20%C2%B7%20examples%20%C2%B7%20API-3c5488?style=for-the-badge&labelColor=13294b" align="middle" alt="Documentation: tutorials, examples, API"></a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <img src="https://raw.githubusercontent.com/vigno0405/VirtualModelControl/main/docs/_static/readme-hero.svg" width="820" alt="A soft arm whose tip a virtual spring pulls towards a goal, and the distance from the tip to the goal over time">
17
+ </p>
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install virtualmodelcontrol
23
+ ```
24
+
25
+ The newest code, from GitHub, before it is released (the same line updates an existing install):
26
+
27
+ ```bash
28
+ pip install --upgrade "git+https://github.com/vigno0405/VirtualModelControl.git"
29
+ ```
30
+
31
+ Virtual environments, conda, ROS 2 and pinned versions are covered in [Installation][install].
32
+
33
+ ## Requirements
34
+
35
+ Python 3.10 or newer, tested with 3.10 to 3.14 on Ubuntu 22.04 and 24.04. Nothing to compile;
36
+ ROS and LaTeX are not needed.
37
+
38
+ ## Dependencies
39
+
40
+ pip installs them with the library:
41
+
42
+ | Package | Version | Used for |
43
+ | --- | --- | --- |
44
+ | [numpy](https://numpy.org) | 1.26 or newer, 2.x included | arrays |
45
+ | [CasADi](https://web.casadi.org) | 3.6 or newer | the symbolic models, their derivatives and the compiled controllers |
46
+ | [SciPy](https://scipy.org) | 1.11 or newer | rotations of chains built from DH tables; fitting stiffness and damping |
47
+ | [matplotlib](https://matplotlib.org) | 3.8 or newer | figures and animations |
48
+ | [imageio-ffmpeg](https://github.com/imageio/imageio-ffmpeg) | 0.5 or newer | MP4 videos of the animations |
49
+ | [PyYAML](https://pyyaml.org) | 6 or newer | robot and hardware files |
50
+ | [Dynamixel SDK](https://github.com/ROBOTIS-GIT/DynamixelSDK) | 3.7 or newer | Dynamixel motors (leaves in 0.4.0) |
51
+ | [pyserial](https://github.com/pyserial/pyserial) | 3.5 or newer | the serial port of the Dynamixel SDK (leaves in 0.4.0) |
52
+
53
+ ## The example in the figure
54
+
55
+ The robot and the controller are two separate mechanisms: the robot mechanism describes the
56
+ hardware, and the controller holds the virtual elements placed on it.
57
+
58
+ ```python
59
+ import numpy as np
60
+ import virtualmodelcontrol as vmc
61
+ from virtualmodelcontrol.robots import helyx
62
+
63
+ arm = helyx.arm("145-145-145") # a soft arm with nine tendon motors
64
+ tip = arm.point(s=1.0)
65
+
66
+ ctrl = vmc.Mechanism("ctrl")
67
+ ctrl.add("reach", vmc.LinearSpring(tip - [0.15, 0.0, 0.35], 600.0)) # [N/m]
68
+ ctrl.add("damp", vmc.LinearDamper(tip, 5.0)) # [N·s/m]
69
+ ctrl.add("gravity", vmc.GravityCompensation(arm))
70
+ controller = vmc.VMCController(vmc.compile(vmc.VirtualMechanismSystem(arm, ctrl)))
71
+
72
+ meas = vmc.Signals(0.0, motor_position=np.zeros(9), motor_velocity=np.zeros(9))
73
+ torques = controller.step(0.0, meas)["motor_torque"] # [N·m], one per motor
74
+ ```
75
+
76
+ The same controller runs on a simulation built from the robot's own masses, stiffness and
77
+ damping; [readme_figure.py][figure] draws the figure from this run.
78
+
79
+ ```python
80
+ arm = helyx.add_dynamics(arm)
81
+ plant = vmc.sim.ModelPlant(arm)
82
+ log = vmc.sim.run(plant, controller, vmc.sim.SimClock(dt=1 / 330), T=3.0)
83
+ ```
84
+
85
+ ## Examples
86
+
87
+ Each example builds a ready-made robot, controls it in simulation and animates the run:
88
+
89
+ - [Soft arm][soft-arm]: reach past an obstacle, and limit the force with a tanh spring.
90
+ - [Hanging soft arm][hanging-arm]: identify its stiffness and damping, and reach around an
91
+ obstacle.
92
+ - [Two arms][two-arms]: squeeze an object between the tips of two soft arms.
93
+ - [Finger][finger]: a stiff fingertip and soft joint limits.
94
+ - [Hand][hand]: grasp a ball, alone or mounted on a UR5 arm.
95
+ - [Turtle][turtle]: two cranks that follow a virtual flywheel.
96
+
97
+ ## Documentation
98
+
99
+ The [documentation][docs] holds the tutorials, the examples, the concepts and the API. What
100
+ changed is in the [changelog][changelog], what comes next in the [roadmap][roadmap], and how to
101
+ contribute in [Contributing][contributing].
102
+
103
+ ## Authors
104
+
105
+ Lorenzo Vignoli, at the [CREATE Lab][lab] of EPFL (Prof. Josie Hughes), in a collaboration
106
+ with the University of Cambridge (Prof. Fulvio Forni). To cite the library, see [CITATION.cff][cite].
107
+ The code is under the [MIT license][license].
108
+
109
+ [lab]: https://www.epfl.ch/labs/create/
110
+ [install]: https://vigno0405.github.io/VirtualModelControl/installation.html
111
+ [figure]: https://github.com/vigno0405/VirtualModelControl/blob/main/docs/scripts/readme_figure.py
112
+ [soft-arm]: https://vigno0405.github.io/VirtualModelControl/examples/soft-arm.html
113
+ [hanging-arm]: https://vigno0405.github.io/VirtualModelControl/examples/hanging-arm.html
114
+ [two-arms]: https://vigno0405.github.io/VirtualModelControl/examples/two-arms.html
115
+ [finger]: https://vigno0405.github.io/VirtualModelControl/examples/finger.html
116
+ [hand]: https://vigno0405.github.io/VirtualModelControl/examples/hand.html
117
+ [turtle]: https://vigno0405.github.io/VirtualModelControl/examples/turtle.html
118
+ [docs]: https://vigno0405.github.io/VirtualModelControl/
119
+ [changelog]: https://vigno0405.github.io/VirtualModelControl/development/changelog.html
120
+ [roadmap]: https://vigno0405.github.io/VirtualModelControl/development/roadmap.html
121
+ [contributing]: https://vigno0405.github.io/VirtualModelControl/development/contributing.html
122
+ [cite]: https://github.com/vigno0405/VirtualModelControl/blob/main/CITATION.cff
123
+ [license]: https://github.com/vigno0405/VirtualModelControl/blob/main/LICENSE