virtualmodelcontrol 1.2.0__tar.gz → 1.2.2__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.
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/CHANGELOG.md +42 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/CITATION.cff +2 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/PKG-INFO +1 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/api/index.md +7 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/conventions.md +30 -6
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/efficiency.md +11 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/finger.md +8 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/library.md +15 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/passivity.md +8 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/pcc.md +19 -16
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/concepts/vmc.md +7 -7
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/conf.py +2 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/development/contributing.md +5 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/development/support.md +5 -3
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/finger.md +6 -3
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/hand.md +14 -7
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/hanging-arm.md +5 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/soft-arm.md +3 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/two-arms.md +14 -11
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/index.md +11 -4
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/installation.md +24 -5
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/_draw.py +1 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/finger.py +2 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/four_steps.py +1 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/turtle.py +1 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/troubleshooting.md +2 -2
- virtualmodelcontrol-1.2.2/docs/tutorials/build-a-robot.md +166 -0
- virtualmodelcontrol-1.2.2/docs/tutorials/components.md +181 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/configurations.md +10 -4
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/contact.md +56 -40
- virtualmodelcontrol-1.2.2/docs/tutorials/coordinates-and-components.md +11 -0
- virtualmodelcontrol-1.2.2/docs/tutorials/coordinates.md +162 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/crawl.md +60 -32
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/energy.md +37 -18
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/estimation.md +63 -29
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/extend.md +56 -17
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/first-controller.md +21 -6
- virtualmodelcontrol-1.2.2/docs/tutorials/fit.md +141 -0
- virtualmodelcontrol-1.2.2/docs/tutorials/force-estimates.md +295 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/force.md +34 -241
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/friction.md +28 -18
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/introduction.md +4 -4
- virtualmodelcontrol-1.2.2/docs/tutorials/joints.md +246 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/kinematics.md +27 -11
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/mpc.md +31 -15
- virtualmodelcontrol-1.2.2/docs/tutorials/optimize-obstacles.md +237 -0
- virtualmodelcontrol-1.2.2/docs/tutorials/optimize-periodic.md +306 -0
- virtualmodelcontrol-1.2.2/docs/tutorials/optimize.md +382 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/outside.md +15 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/parameters.md +12 -6
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/real-time.md +19 -6
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/run-logs.md +15 -10
- virtualmodelcontrol-1.2.2/docs/tutorials/soft-and-assemblies.md +135 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/stiffness.md +27 -17
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/swaps.md +12 -8
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/tuning.md +58 -17
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/underactuated.md +42 -21
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/_version.py +2 -2
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/state.py +3 -3
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/params.py +39 -4
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/helyx.py +11 -3
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/run.py +66 -32
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_state_layout.py +3 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_fit_params.py +65 -7
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_helyx.py +3 -1
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_wallclock.py +76 -0
- virtualmodelcontrol-1.2.2/tests/test_python_versions.py +49 -0
- virtualmodelcontrol-1.2.0/docs/tutorials/build-a-robot.md +0 -470
- virtualmodelcontrol-1.2.0/docs/tutorials/coordinates-and-components.md +0 -292
- virtualmodelcontrol-1.2.0/docs/tutorials/fit.md +0 -92
- virtualmodelcontrol-1.2.0/docs/tutorials/optimize.md +0 -823
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/.gitignore +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/LICENSE +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/README.md +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/benchmarks/tick.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_ext/video.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/create-lab.png +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/custom.css +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/favicon.svg +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/logo-light.svg +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/logo.svg +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_static/readme-hero.svg +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_templates/autosummary/module.rst +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/_templates/partials/toc.html +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/development/changelog.md +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/development/roadmap.md +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/docs_setup.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/examples/turtle.md +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/bimanual.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/control_loop.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/energy_flow.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/hand.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/helyx.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/library_map.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/mechanism.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/params.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/pcc.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/schematics/ur5.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/scripts/readme_figure.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/reach.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/docs/tutorials/run-settings.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/pyproject.toml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/force.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/limits.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/position.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/scalar.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/seeking.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/adaptation/stiffness.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/compiler.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/controllers.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/coordinates.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/experiment.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/files.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/config/spec.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/blending.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/controller.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/output.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/projection.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/schedule.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/tank.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/control/underactuated.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/backends.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/params.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/registry.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/signals.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/space.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/symbolic.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/core/units.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/dynamics.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/balance.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/compliance.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/contact.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/imu.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/inversion.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/kalman.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/measurement.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/momentum.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/sensors.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/stiffness.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/estimation/velocity.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/hardware/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/hardware/profile.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/efficiency.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/plateaus.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/steps.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/stiffness.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/identification/transmission.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/math.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/base.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/constrained.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/dissipation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/gated.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/inertance.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/locomotion.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/sources.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/components/storage.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/base.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/frames.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/geometry.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/joints.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/ops.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/coordinates/references.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/mechanisms/mechanism.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/actuation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/assembly.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/continuum/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/continuum/pcc.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/efficiency.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/equations.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/friction.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/function.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/joint_space.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/kinematic.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/kinematics.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/rigid/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/rigid/couplings.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/rigid/poe.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/models/rigid/spline.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/asktell.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/builder.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/collocation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/equilibrium.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/horizon.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/mpc.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/nlp.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/problem.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/result.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/search.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/shooting.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/solver.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/tank.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/terms.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/trajectory.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/variables.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/optimization/virtual.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/py.typed +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/adapt.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/bimanual.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/planar.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/turtle.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/robots/ur5.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/balance.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/model_plant.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/plant.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/replay.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/rollout.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/sim/runlog.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/system.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/testing.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/viz/__init__.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/viz/animation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/viz/draw.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/src/virtualmodelcontrol/viz/style.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_fingertip.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_force.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_grasp.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_holding.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_loop.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_position.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_scalar.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_seeking.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_stiffness_tracking.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/adaptation/test_virtual_state.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/backend_helpers.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/config/test_config.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/conftest.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_blending.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_honesty.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_inputs.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_output.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_projection.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_schedule.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_tank.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_underactuated.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_underactuated_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/control/test_vmc_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_backends.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_backends_torch.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_params.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_registry.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_signals.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_space.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/core/test_symbolic.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/adaptation.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/compliance.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/components.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/finger.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/hand.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/soft-arm.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/turtle.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/two-arms.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/configs/ur5-hand.yaml +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/derivatives.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/dynamics.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/efficiency.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/estimation.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/finger.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/fingertip.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/hand.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/heuristics.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/imu.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/kalman.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/mocap.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/optimization.json +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/optimization.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/pcc.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/transmission.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/turtle.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/underactuated.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/data/vmc.npz +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_compliance_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_contact.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_imu.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_inversion.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_kalman.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_kalman_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_kalman_unscented.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_mocap_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_momentum.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_sensors.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_unmeasured.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/estimation/test_velocity.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/hardware/test_profile.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/hardware/test_templates.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/helpers.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_efficiency_fit.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_fit_friction.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_friction.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_steps.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_stiffness_fit.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/identification/test_transmission.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/lab_optimization.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_components.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_components_golden.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_contact.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_coordinates.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_distances.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_frames.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_friction.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_gated.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_mechanism.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_more_components.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_pair_contact.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_phase_spring.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/mechanisms/test_virtual_model.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_actuation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_assembly.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_contact_map.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_efficiency.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_equations.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_floating.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_floating_base.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_function.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_kinematics.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_pcc.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_poe.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_rail.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_static_friction.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/models/test_underactuated.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_asktell.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_collocation.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_equilibrium.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_horizon.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_lab.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_mpc.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_periodic.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_plant.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_problem.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_search.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_shooting.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_solvers.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_structure.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_swap.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_tank.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_terms.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_variables.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/optimization/test_virtual.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_adapt.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_bimanual.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_crawler.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_hand.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_parametric.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_planar.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_turtle.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/robots/test_ur5.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_balance.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_record.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_replay.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_rollout.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_run.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/sim/test_runlog.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/small_plan.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/soft_arm_plan.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_benchmark.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_compiler.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_docs.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_dynamics.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_import.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_math.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_readme.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/test_testing.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/underactuated_lab.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/viz/test_animate.py +0 -0
- {virtualmodelcontrol-1.2.0 → virtualmodelcontrol-1.2.2}/tests/viz/test_viz.py +0 -0
|
@@ -4,6 +4,41 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/) (0.x: the API may change between minor versions).
|
|
6
6
|
|
|
7
|
+
## [1.2.2] - 2026-10-11
|
|
8
|
+
|
|
9
|
+
A patch: a fit says when its data do not determine a Param, and gives the same values on every machine; two
|
|
10
|
+
error messages say what to do instead. Nothing else changes.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `fit_params`: a Param that the data do not determine (a run that never excites it, or an entry of a matrix
|
|
15
|
+
that only appears in a sum with another, such as the two off-diagonal entries of a spring's stiffness) has
|
|
16
|
+
`std` `inf`. It was `0.0`, which read as certainty. Along such a direction the fit used to end wherever the
|
|
17
|
+
rounding of the machine left it (the difference of those two entries came out as 4.06, 3.67 or -2.31 on
|
|
18
|
+
different CPUs); it now stays at the start, inside the bounds and only if the fit stays as good. The values
|
|
19
|
+
and the standard errors of the Params that the data do determine are the same as before.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- An unknown geometry in `helyx.arm`, `helyx.model` or `helyx.hardware` raises a `KeyError` that names it and
|
|
24
|
+
lists the known geometries (it was the bare name).
|
|
25
|
+
- The `ValueError` that a law or an estimator raises for a `StateController` now says what to use instead:
|
|
26
|
+
`underactuated.controller(compiled, "frozen")` without `gravity=True` (that one reads the motors), or
|
|
27
|
+
`DirectionalForce` for a force. It used to say "the plain frozen controller", which a `gravity=True`
|
|
28
|
+
controller is not.
|
|
29
|
+
|
|
30
|
+
## [1.2.1] - 2026-10-10
|
|
31
|
+
|
|
32
|
+
A patch: a Ctrl-C can no longer lose the log of a real-time run. Nothing else changes.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- A Ctrl-C (or `_thread.interrupt_main()`) that arrived in the middle of a real-time step could land
|
|
37
|
+
inside a call into CasADi or numpy, come out as a `SystemError` and lose the log. On the main thread,
|
|
38
|
+
with Python's own handler on SIGINT, `sim.run` now only raises a flag, reads it between two steps and
|
|
39
|
+
returns the log; a second Ctrl-C raises at once, for a run that is stuck. A handler of your own, and
|
|
40
|
+
any other thread, are left alone.
|
|
41
|
+
|
|
7
42
|
## [1.2.0] - 2026-10-09
|
|
8
43
|
|
|
9
44
|
A robot that runs for hours: the log of a real-time run can keep only its last seconds. Nothing that
|
|
@@ -819,7 +854,13 @@ First public release.
|
|
|
819
854
|
- `robots.adapt`: the ADAPT finger (two motors, coupled distal joints), joint-angle coordinate
|
|
820
855
|
and joint-limit spring.
|
|
821
856
|
|
|
822
|
-
[Unreleased]: https://github.com/vigno0405/VirtualModelControl/compare/
|
|
857
|
+
[Unreleased]: https://github.com/vigno0405/VirtualModelControl/compare/v1.2.2...HEAD
|
|
858
|
+
[1.2.2]: https://github.com/vigno0405/VirtualModelControl/compare/v1.2.1...v1.2.2
|
|
859
|
+
[1.2.1]: https://github.com/vigno0405/VirtualModelControl/compare/v1.2.0...v1.2.1
|
|
860
|
+
[1.2.0]: https://github.com/vigno0405/VirtualModelControl/compare/v1.1.0...v1.2.0
|
|
861
|
+
[1.1.0]: https://github.com/vigno0405/VirtualModelControl/compare/v1.0.0...v1.1.0
|
|
862
|
+
[1.0.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.5.0...v1.0.0
|
|
863
|
+
[0.5.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.3.0...v0.5.0
|
|
823
864
|
[0.3.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.2.0...v0.3.0
|
|
824
865
|
[0.2.0]: https://github.com/vigno0405/VirtualModelControl/compare/v0.1.0...v0.2.0
|
|
825
866
|
[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:
|
|
5
|
-
date-released: "2026-10-
|
|
4
|
+
version: 1.2.2
|
|
5
|
+
date-released: "2026-10-11"
|
|
6
6
|
title: "virtualmodelcontrol: Virtual Model Control for robots"
|
|
7
7
|
authors:
|
|
8
8
|
- family-names: Vignoli
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: virtualmodelcontrol
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Virtual Model Control: robots and controllers as mechanisms of springs, dampers and inertances, compiled with CasADi.
|
|
5
5
|
Project-URL: Repository, https://github.com/vigno0405/VirtualModelControl
|
|
6
6
|
Project-URL: Documentation, https://vigno0405.github.io/VirtualModelControl/
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# API
|
|
2
2
|
|
|
3
|
-
Scripts
|
|
4
|
-
tutorials
|
|
3
|
+
Scripts start with `import virtualmodelcontrol as vmc`: the classes and functions of the
|
|
4
|
+
tutorials, and the modules `vmc.sim`, `vmc.viz` and the others below, are available from there.
|
|
5
|
+
The robot templates are the one exception: import them as
|
|
6
|
+
`from virtualmodelcontrol.robots import helyx` (or `adapt`, `bimanual`, `turtle`). The modules, from
|
|
7
|
+
the bottom layer up:
|
|
5
8
|
|
|
6
9
|
```{eval-rst}
|
|
7
10
|
.. autosummary::
|
|
@@ -24,4 +27,6 @@ tutorials are available from there. The modules, from the bottom layer up:
|
|
|
24
27
|
~virtualmodelcontrol.hardware
|
|
25
28
|
~virtualmodelcontrol.viz
|
|
26
29
|
~virtualmodelcontrol.robots
|
|
30
|
+
~virtualmodelcontrol.config
|
|
31
|
+
~virtualmodelcontrol.testing
|
|
27
32
|
```
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# Conventions and glossary
|
|
2
2
|
|
|
3
|
+
The rules that every part of the library follows, and the words it uses. Read it once, and come back when a sign or a unit surprises you.
|
|
4
|
+
|
|
3
5
|
## Units and signs
|
|
4
6
|
|
|
5
7
|
- SI everywhere: m, rad, s, N, N·m, kg. Degrees stay at the boundary with the hardware, in the
|
|
6
8
|
robot's hardware profile. A driver's raw units (encoder ticks, motor currents) never enter
|
|
7
9
|
the library.
|
|
8
10
|
- A positive motor angle pulls its tendon. Each template states the sign of its robot's
|
|
9
|
-
encoders against this convention (`helyx.ENCODER_SIGN`,
|
|
10
|
-
`turtle.MOTOR_SIGNS
|
|
11
|
+
encoders against this convention (`helyx.ENCODER_SIGN`, one sign for each geometry,
|
|
12
|
+
`bimanual.ENCODER_SIGN`, one sign, and `turtle.MOTOR_SIGNS`, one sign per motor). The robot's
|
|
13
|
+
hardware profile applies it for you; if you convert by hand, multiply raw readings and commands
|
|
14
|
+
by it.
|
|
11
15
|
- Controllers send their torques as computed, never divided by an efficiency. A robot's
|
|
12
16
|
efficiency maps the commanded motor torques to the delivered ones. It is 1 by default,
|
|
13
17
|
because the templates' stiffness and damping were identified from the commanded torques
|
|
@@ -17,7 +21,10 @@
|
|
|
17
21
|
|
|
18
22
|
- The configuration `q` lives on a space, and the velocity `v` in its tangent space. So `q` and
|
|
19
23
|
`v` may differ in size (a floating body, for example).
|
|
20
|
-
-
|
|
24
|
+
- A generalized force is `τ`, actuator commands are `u`. Symbols are local to a page, and each page
|
|
25
|
+
says what it uses. The one to watch is `θ`: a motor angle in the robot's signals
|
|
26
|
+
(`motor_position`); a joint angle in the finger and hand pages, where the motors are `q`; the
|
|
27
|
+
bend of a segment in the PCC page.
|
|
21
28
|
- A spring's deflection is `y = x − x_ref`, so it pulls `x` towards `x_ref`. Storage gives
|
|
22
29
|
`f = −∂V/∂y`, a damper `f = −D ẏ`, and every force reaches the robot as `τ = Jᵀ f`.
|
|
23
30
|
- Arrays in, arrays out: inputs accept anything array-like; outputs are numpy arrays (torch
|
|
@@ -25,7 +32,8 @@
|
|
|
25
32
|
|
|
26
33
|
## Continuum robots
|
|
27
34
|
|
|
28
|
-
- The arc parameter `s ∈ [0, 1]` runs from the base to the tip, uniformly in
|
|
35
|
+
- The arc parameter `s ∈ [0, 1]` runs from the base to the tip, uniformly in rest length (the arc
|
|
36
|
+
length while no segment stretches).
|
|
29
37
|
- A segment's configuration is `Δ = (Dx, Dy, Dl)` [m]. The base frame's `z` axis runs along
|
|
30
38
|
the straight body. See [soft-arm kinematics](pcc.md).
|
|
31
39
|
|
|
@@ -56,13 +64,29 @@ virtual state
|
|
|
56
64
|
A degree of freedom of the controller itself, such as the turtle's flywheel; it needs an
|
|
57
65
|
inertance.
|
|
58
66
|
|
|
67
|
+
inertance
|
|
68
|
+
A mass or an inertia on a coordinate, and the component that gives it. A virtual state needs
|
|
69
|
+
one; a robot has its own.
|
|
70
|
+
|
|
71
|
+
live Param
|
|
72
|
+
A Param that may change while the controller runs (scope `stage`), for example with
|
|
73
|
+
`controller.set`; the others are folded in when the controller is compiled
|
|
74
|
+
([parameters](../tutorials/parameters.md)).
|
|
75
|
+
|
|
76
|
+
law
|
|
77
|
+
A rule that changes a controller's live Params at every step, such as `ForceTracking`.
|
|
78
|
+
|
|
79
|
+
guard
|
|
80
|
+
The check of a run that sends zero torque when a reading is missing, not a number, or too old.
|
|
81
|
+
|
|
59
82
|
site
|
|
60
83
|
A named point of a kinematic model, such as `"tip"`; continuum models also accept an arc
|
|
61
84
|
parameter `s`.
|
|
62
85
|
|
|
63
86
|
plant
|
|
64
|
-
What the controller drives: a simulator such as `ModelPlant`, or the real robot.
|
|
65
|
-
plant
|
|
87
|
+
What the controller drives: a simulator such as `ModelPlant`, or the real robot. In a plan,
|
|
88
|
+
`Problem(system, plant=robot)` plans the motion of a larger `robot` than the controller's own
|
|
89
|
+
(see [Optimize](../tutorials/optimize.md)).
|
|
66
90
|
|
|
67
91
|
tank
|
|
68
92
|
An energy budget for changing a running controller: a change is applied as far as the tank
|
|
@@ -54,21 +54,24 @@ $$
|
|
|
54
54
|
$$
|
|
55
55
|
|
|
56
56
|
with each coefficient one value for every motor or one per motor. A number passed as
|
|
57
|
-
`efficiency=` is the linear coefficient $c_1$. `vmc.Efficiency(1.0)` is the default
|
|
58
|
-
|
|
57
|
+
`efficiency=` is the linear coefficient $c_1$. `vmc.Efficiency(1.0)` is the default, and
|
|
58
|
+
`Efficiency(..., friction=...)` adds the static friction of the motors
|
|
59
|
+
([Static friction](../tutorials/friction.md)). The coefficients are Params, to change, tune or
|
|
60
|
+
identify:
|
|
59
61
|
|
|
60
62
|
```{code-cell} python
|
|
61
63
|
import numpy as np
|
|
62
64
|
import virtualmodelcontrol as vmc
|
|
63
65
|
from virtualmodelcontrol.robots import helyx
|
|
64
66
|
|
|
65
|
-
cubic = vmc.Efficiency(0.10, 0.0, 0.40) #
|
|
67
|
+
cubic = vmc.Efficiency(0.10, 0.0, 0.40) # made-up numbers, for all motors
|
|
66
68
|
arm = helyx.arm(efficiency=cubic)
|
|
67
69
|
arm.params["efficiency.c3"]
|
|
68
70
|
```
|
|
69
71
|
|
|
70
72
|
A robot with an efficiency other than 1 receives the delivered torques, so its stiffness,
|
|
71
|
-
damping and masses must be the physical ones, referred to the delivered torque
|
|
73
|
+
damping and masses must be the physical ones, referred to the delivered torque: the values
|
|
74
|
+
identified from the commanded torques, times $\eta$, as above. In a
|
|
72
75
|
simulator, `vmc.sim.ModelPlant(robot, runtime=["*efficiency*"])` keeps the coefficients live.
|
|
73
76
|
|
|
74
77
|
## Identify it from static measurements
|
|
@@ -96,7 +99,7 @@ holds = plateaus(t, command, tolerance=1e-6) # settled half of each hold
|
|
|
96
99
|
u = np.array([command[h].mean() for h in holds])
|
|
97
100
|
y = np.array([measured[h].mean() for h in holds])
|
|
98
101
|
linear = fit_efficiency(u, y)
|
|
99
|
-
|
|
102
|
+
cubic_fit = fit_efficiency(u, y, degree=3)
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
```{code-cell} python
|
|
@@ -108,7 +111,7 @@ grid = np.linspace(0.0, 1.05, 100)
|
|
|
108
111
|
fig, ax = plt.subplots()
|
|
109
112
|
ax.plot(u, y, "o", color=viz.PALETTE[0], label="plateaus")
|
|
110
113
|
ax.plot(grid, linear(grid), "--", color=viz.PALETTE[1], label="linear fit")
|
|
111
|
-
ax.plot(grid,
|
|
114
|
+
ax.plot(grid, cubic_fit(grid), color=viz.PALETTE[2], label="cubic fit")
|
|
112
115
|
ax.set_xlabel(r"commanded torque [N$\cdot$m]")
|
|
113
116
|
ax.set_ylabel(r"delivered torque [N$\cdot$m]")
|
|
114
117
|
ax.legend();
|
|
@@ -125,8 +128,8 @@ def r2(fit):
|
|
|
125
128
|
|
|
126
129
|
glue("eta_linear", float(linear.params["c1"].value[0]), display=False)
|
|
127
130
|
glue("r2_linear", float(r2(linear)), display=False)
|
|
128
|
-
glue("r2_cubic", float(r2(
|
|
129
|
-
glue("c3", float(
|
|
131
|
+
glue("r2_cubic", float(r2(cubic_fit)), display=False)
|
|
132
|
+
glue("c3", float(cubic_fit.params["c3"].value[0]), display=False)
|
|
130
133
|
```
|
|
131
134
|
|
|
132
135
|
The linear fit gives a constant efficiency of {glue:text}`eta_linear:.3f` ($R^2$ =
|
|
@@ -8,7 +8,7 @@ kernelspec:
|
|
|
8
8
|
|
|
9
9
|
The ADAPT finger and hand are rigid chains of phalanges driven through tendons and cables, with
|
|
10
10
|
fewer motors than joints. This page gives the equations of `robots.adapt`: how motor angles set
|
|
11
|
-
joint angles, and how joint angles place the fingertip.
|
|
11
|
+
joint angles, and how joint angles place the fingertip, and then how the hand's motors drive its joints.
|
|
12
12
|
|
|
13
13
|
```{code-cell} python
|
|
14
14
|
:tags: [remove-cell]
|
|
@@ -33,7 +33,8 @@ glue("pip", float(adapt.COUPLING[1, 1]), display=False)
|
|
|
33
33
|
|
|
34
34
|
The finger has three phalanges, proximal, middle and distal, of {glue:text}`a:.1f`,
|
|
35
35
|
{glue:text}`b:.1f` and {glue:text}`c:.1f` mm, joined by three revolute joints, MCP, PIP and
|
|
36
|
-
DIP
|
|
36
|
+
DIP (the metacarpophalangeal, proximal interphalangeal and distal interphalangeal joints), all
|
|
37
|
+
turning about $x$. Straight, it points along $y$. Bending it turns the tip towards $z$.
|
|
37
38
|
|
|
38
39
|
```{code-cell} python
|
|
39
40
|
:tags: [remove-input]
|
|
@@ -45,11 +46,11 @@ schematic.figure();
|
|
|
45
46
|
|
|
46
47
|
Two motors drive the three joints. The first pulls a cable on a pulley of the MCP joint. The
|
|
47
48
|
second drives the PIP joint through a cable, and the DIP joint follows the PIP joint. With
|
|
48
|
-
motor angles $
|
|
49
|
+
motor angles $q_0, q_1$,
|
|
49
50
|
|
|
50
51
|
$$
|
|
51
|
-
\theta_\text{MCP} = \frac{r_p}{r_m}\,
|
|
52
|
-
\theta_\text{PIP} = \theta_\text{DIP} = \frac{r_m}{c_p}\,
|
|
52
|
+
\theta_\text{MCP} = \frac{r_p}{r_m}\,q_0, \qquad
|
|
53
|
+
\theta_\text{PIP} = \theta_\text{DIP} = \frac{r_m}{c_p}\,q_1,
|
|
53
54
|
$$
|
|
54
55
|
|
|
55
56
|
with $r_m$ the motor pulley's radius, $r_p$ that of the MCP pulley and $c_p$ the cable constant
|
|
@@ -100,9 +101,8 @@ glue("spread", ", ".join(coefficients[:3]) + " and " + coefficients[3], display=
|
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
The hand has a thumb and four fingers, each a chain of revolute joints from the hand's base.
|
|
103
|
-
The thumb has the joints CMC1, CMC2, MCP and IP, and each
|
|
104
|
-
PIP and DIP. The origins and axes of the joints
|
|
105
|
-
of the module.
|
|
104
|
+
The thumb has the joints CMC1, CMC2 (carpometacarpal), MCP and IP (interphalangeal), and each
|
|
105
|
+
finger has the joints spread, MCP, PIP and DIP. The origins and axes of the joints are tables in `robots.adapt` (`HAND_JOINTS`, `HAND_FINGER_BASES`).
|
|
106
106
|
{glue:text}`motors:.0f` motors drive its {glue:text}`joints:.0f` joints, $\theta = C\,q$:
|
|
107
107
|
|
|
108
108
|
- each thumb joint has a motor of its own;
|
|
@@ -6,8 +6,9 @@ kernelspec:
|
|
|
6
6
|
|
|
7
7
|
# How the library is organized
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
This page is a map: what each part of the library does, and which names to look for. The library
|
|
10
|
+
is a stack of layers. Each layer uses only the layers below it. The ready-made robots and the
|
|
11
|
+
figures sit at the edges. They may use every layer, and no layer uses them.
|
|
11
12
|
|
|
12
13
|
```{code-cell} python
|
|
13
14
|
:tags: [remove-cell]
|
|
@@ -20,11 +21,15 @@ from schematics import library_map
|
|
|
20
21
|
library_map.figure();
|
|
21
22
|
```
|
|
22
23
|
|
|
24
|
+
From the bottom, the layers are `core` (Params and signals), `math`, `mechanisms`, `models`,
|
|
25
|
+
`system`, `compiler` and `dynamics`, `control`, `sim`, `estimation` and `identification`, and
|
|
26
|
+
`adaptation` and `optimization`. The edges are `robots`, `hardware`, `viz`, `config` and `testing`.
|
|
27
|
+
|
|
23
28
|
A controller needs only the layers up to `control`: describe the robot with `models`, place
|
|
24
29
|
virtual elements with `mechanisms`, pair them in a `VirtualMechanismSystem`, `compile` it and
|
|
25
30
|
run it with `VMCController`. Simulation, figures and the robot templates are optional.
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
The order is checked automatically on every change, and so is that nothing in the library imports
|
|
32
|
+
a robot middleware such as ROS: signals come in and go out as arrays.
|
|
28
33
|
|
|
29
34
|
## Where things are
|
|
30
35
|
|
|
@@ -46,7 +51,7 @@ change, including that nothing in the library imports ROS.
|
|
|
46
51
|
| describe an experiment in a file | `vmc.config`: `load`, `Experiment` |
|
|
47
52
|
| draw and animate | `vmc.viz` |
|
|
48
53
|
| run a model without CasADi | `backend="numpy"` or `"torch"`, `Dynamics.export`, `Compiled.export` |
|
|
49
|
-
| parameters, units, scopes | `vmc.Param`, `vmc.ParamSet` |
|
|
54
|
+
| parameters, units, scopes | `vmc.Param`, `vmc.ParamSet` ([Parameters](../tutorials/parameters.md)) |
|
|
50
55
|
|
|
51
56
|
## One symbolic source
|
|
52
57
|
|
|
@@ -61,9 +66,11 @@ $$
|
|
|
61
66
|
\end{aligned}
|
|
62
67
|
$$
|
|
63
68
|
|
|
64
|
-
with $M$ the mass matrix, $h$ the velocity
|
|
65
|
-
|
|
66
|
-
respect to the velocity. A model whose dynamics are not made of such components (a black box)
|
|
69
|
+
with $M$ the mass matrix, $h$ the velocity terms of the kinetic energy (Coriolis and centrifugal),
|
|
70
|
+
$B$ the actuation map, $f_k$ the forces of the robot's own components (springs, dampers, gravity)
|
|
71
|
+
and $J_k$ the Jacobian of each one's coordinate with respect to the velocity. A model whose dynamics are not made of such components (a black box)
|
|
67
72
|
gives the residual itself, as a function. The numpy and PyTorch versions of a model are not
|
|
68
73
|
written again: they are generated from the same graph ([Use a model outside
|
|
69
74
|
CasADi](../tutorials/outside.md)).
|
|
75
|
+
|
|
76
|
+
To use these parts, start with [your first controller](../tutorials/first-controller.md).
|
|
@@ -24,13 +24,13 @@ energy_flow.figure();
|
|
|
24
24
|
|
|
25
25
|
## The controller's energy balance
|
|
26
26
|
|
|
27
|
-
The controller stores $E_c = V + T$: $V$ in its springs,
|
|
28
|
-
states. Three powers change it. The port, $P = \tau^\top v$, is the power its torques give the
|
|
29
|
-
robot. The dissipation is $
|
|
30
|
-
$
|
|
27
|
+
The controller stores $E_c = V + T$: $V$ in its springs, measured from its lowest value so that
|
|
28
|
+
$E_c \ge 0$, and $T$ in the inertances of its virtual states. Three powers change it. The port, $P = \tau^\top v$, is the power its torques give the
|
|
29
|
+
robot. The dissipation power is $P_D = \sum f \cdot \dot y \le 0$ over its dampers. The source power is
|
|
30
|
+
$P_S = \sum f \cdot \dot y$ over its sources. With the [VMC equations](vmc.md),
|
|
31
31
|
|
|
32
32
|
$$
|
|
33
|
-
\dot E_c = -P +
|
|
33
|
+
\dot E_c = -P + P_D + P_S .
|
|
34
34
|
$$
|
|
35
35
|
|
|
36
36
|
The compiled controller computes each term (`compiled.energy`, `compiled.power`), so the balance can be
|
|
@@ -41,10 +41,10 @@ checked on any run.
|
|
|
41
41
|
Without sources, integrating the balance gives
|
|
42
42
|
|
|
43
43
|
$$
|
|
44
|
-
\int_0^t P\,\mathrm{d}t = E_c(0) - E_c(t) + \int_0^t
|
|
44
|
+
\int_0^t P\,\mathrm{d}t = E_c(0) - E_c(t) + \int_0^t P_D\,\mathrm{d}t \;\le\; E_c(0),
|
|
45
45
|
$$
|
|
46
46
|
|
|
47
|
-
since $E_c(t) \ge 0$ and $
|
|
47
|
+
since $E_c(t) \ge 0$ and $P_D \le 0$. Whatever the robot does, the controller gives it at most the
|
|
48
48
|
energy it stored at the start: it is passive.
|
|
49
49
|
|
|
50
50
|
## The robot and its controller together
|
|
@@ -54,7 +54,7 @@ by its input power and its own dissipation. With the default [efficiency](effici
|
|
|
54
54
|
and no output stage, its input power is the controller's port $P$, so the two balances add up:
|
|
55
55
|
|
|
56
56
|
$$
|
|
57
|
-
\dot E_r + \dot E_c =
|
|
57
|
+
\dot E_r + \dot E_c = P_{D,r} + P_D + P_S .
|
|
58
58
|
$$
|
|
59
59
|
|
|
60
60
|
Without sources the total energy can only fall. It is bounded by its value at the start. Where
|
|
@@ -24,44 +24,45 @@ pcc.figure();
|
|
|
24
24
|
|
|
25
25
|
Segment $i$ has the coordinates $\Delta_i = (D_x, D_y, D_l)$ [m]: $D_x$ and $D_y$ bend it
|
|
26
26
|
towards $(D_x, D_y)$, and $D_l$ lengthens it. With rest length $L_0$, section radius $d$ and
|
|
27
|
-
local arc fraction $s \in [0, 1]$,
|
|
27
|
+
local arc fraction $s \in [0, 1]$, the size of the bend is $\rho$ and its angle at $s$ is $\theta$:
|
|
28
28
|
|
|
29
29
|
$$
|
|
30
30
|
\begin{gathered}
|
|
31
|
-
|
|
32
|
-
\theta(s) = s
|
|
31
|
+
\rho = \sqrt{D_x^2 + D_y^2 + \varepsilon}, \\
|
|
32
|
+
\theta(s) = s\,\rho/d .
|
|
33
33
|
\end{gathered}
|
|
34
34
|
$$
|
|
35
35
|
|
|
36
|
-
The frame at $s$ is turned by $\theta$ about the axis $(-D_y, D_x, 0)
|
|
36
|
+
The frame at $s$ is turned by $\theta$ about the axis $(-D_y, D_x, 0)/\rho$, and its origin is
|
|
37
37
|
|
|
38
38
|
$$
|
|
39
|
-
t(s) = \frac{d\,(L_0 + D_l)}{
|
|
40
|
-
\begin{bmatrix} D_x (1 - \cos\theta) \\ D_y (1 - \cos\theta) \\
|
|
39
|
+
t(s) = \frac{d\,(L_0 + D_l)}{\rho^2}
|
|
40
|
+
\begin{bmatrix} D_x (1 - \cos\theta) \\ D_y (1 - \cos\theta) \\ \rho \sin\theta \end{bmatrix},
|
|
41
41
|
$$
|
|
42
42
|
|
|
43
|
-
the point at arc length $s\,(L_0 + D_l)$ on an arc of radius $d\,(L_0 + D_l)
|
|
43
|
+
the point at arc length $s\,(L_0 + D_l)$ on an arc of radius $d\,(L_0 + D_l)/\rho$. The tangent
|
|
44
44
|
is the frame's $z$ axis. The small $\varepsilon$ ($10^{-12}$ m²) keeps the straight pose
|
|
45
45
|
smooth.
|
|
46
46
|
|
|
47
47
|
## The whole arm
|
|
48
48
|
|
|
49
49
|
The configuration stacks the segments, base to tip: $q = (\Delta_1, \dots, \Delta_n)$. The arc
|
|
50
|
-
parameter $s \in [0, 1]$ of the whole arm is uniform in arc length
|
|
50
|
+
parameter $s \in [0, 1]$ of the whole arm is uniform in rest length (it is the arc length while no segment stretches), so
|
|
51
|
+
segment $i$ spans
|
|
51
52
|
$[b_{i-1}, b_i]$ with $b_i = \sum_{j \le i} L_{0,j} / \sum_j L_{0,j}$. Each segment's frame
|
|
52
53
|
starts where the previous one ends. `arm.point(s=...)` accepts a symbolic $s$ as well, so an
|
|
53
54
|
attachment point can itself be optimized.
|
|
54
55
|
|
|
55
56
|
## Tendons
|
|
56
57
|
|
|
57
|
-
A tendon at angle $\delta$ around the section
|
|
58
|
-
length by
|
|
58
|
+
A tendon at angle $\delta$ around the section changes length by
|
|
59
59
|
|
|
60
60
|
$$
|
|
61
61
|
\Delta L = D_l - D_x \cos\delta - D_y \sin\delta ,
|
|
62
62
|
$$
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
(the distance $d$ of the tendon from the backbone is already inside $D_x$ and $D_y$), and its motor,
|
|
65
|
+
with spool radius $r$, turns by $\theta_m = -\Delta L / r$: a positive motor
|
|
65
66
|
angle pulls the tendon. With three tendons per segment this map is invertible, so the measured
|
|
66
67
|
motor angles give $\Delta$ exactly. The motor torques that realize a generalized force $\tau$
|
|
67
68
|
solve $B u = \tau$ with $B = (\partial\theta_m/\partial\Delta)^\top$. The transmission's
|
|
@@ -70,7 +71,7 @@ ones.
|
|
|
70
71
|
|
|
71
72
|
## The templates
|
|
72
73
|
|
|
73
|
-
`robots.helyx` builds Helyx arms from these equations. Three geometries are ready: the soft
|
|
74
|
+
`robots.helyx` builds Helyx arms from these equations. Three geometries are ready, named by their segment lengths in mm: the soft
|
|
74
75
|
arm of the [soft-arm example](../examples/soft-arm.md) (on its side), the
|
|
75
76
|
[hanging soft arm](../examples/hanging-arm.md) and the arms of the
|
|
76
77
|
[two-arm example](../examples/two-arms.md). Their segment lengths, their mounting and the sign
|
|
@@ -81,12 +82,14 @@ of their encoders against the convention above are:
|
|
|
81
82
|
from IPython.display import Markdown
|
|
82
83
|
from virtualmodelcontrol.robots import helyx
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
used = {"145-145-145": "soft arm", "145-290-290": "hanging arm", "290-145-145": "two arms"}
|
|
86
|
+
rows = ["| Geometry | Used in | Segments, base to tip | Gravity in the base frame | Encoder sign |",
|
|
87
|
+
"|---|---|---|---|---|"]
|
|
86
88
|
for name, spec in helyx.GEOMETRIES.items():
|
|
87
89
|
lengths = ", ".join(f"{1000 * L:.0f}" for L in spec["L0"]) + " mm"
|
|
88
90
|
gravity = "[" + ", ".join(f"{g:g}" for g in spec["gravity"]) + "] m/s²"
|
|
89
|
-
rows.append(f"| `{name}` | {
|
|
91
|
+
rows.append(f"| `{name}` | {used[name]} | {lengths} | {gravity} "
|
|
92
|
+
f"| {helyx.ENCODER_SIGN[name]:+.0f} |")
|
|
90
93
|
Markdown("\n".join(rows))
|
|
91
94
|
```
|
|
92
95
|
|
|
@@ -101,5 +104,5 @@ short = helyx.arm(
|
|
|
101
104
|
lengths=(0.2, 0.2), # [m], two segments
|
|
102
105
|
tendon_angles=np.radians([[0, 120, -120], [60, 180, -60]]),
|
|
103
106
|
)
|
|
104
|
-
short.actuation.motor_sizes(short.space) # motor angles and rates
|
|
107
|
+
short.actuation.motor_sizes(short.space) # 6 motor angles and 6 rates
|
|
105
108
|
```
|
|
@@ -46,15 +46,15 @@ $J_z$ need no hand derivation.
|
|
|
46
46
|
## Elements and their forces
|
|
47
47
|
|
|
48
48
|
Each element gives a force $f$ on its coordinate. Springs store energy, $f = -\partial V/\partial y$
|
|
49
|
-
with $V
|
|
49
|
+
with $V$ bounded below. A linear spring of stiffness $K$ on $y = x - x_\text{ref}$ pulls $x$ towards
|
|
50
50
|
$x_\text{ref}$ with $f = -K y$. Dampers dissipate, $f \cdot \dot y \le 0$, as $f = -D \dot y$.
|
|
51
|
-
Inertances give
|
|
52
|
-
compensation, $f = -m g$ on each of the robot's masses.
|
|
51
|
+
Inertances give mass to a virtual state of the controller, or to a coordinate of the robot. Sources add forces of their own, such as gravity
|
|
52
|
+
compensation, $f = -m g$ on each of the robot's masses $m$, with $g$ the gravity vector.
|
|
53
53
|
|
|
54
54
|
## From forces to motor torques
|
|
55
55
|
|
|
56
|
-
The torque that a force $f$ on $y$ exerts on the robot follows from
|
|
57
|
-
$f \cdot \
|
|
56
|
+
The torque that a force $f$ on $y$ exerts on the robot follows from power:
|
|
57
|
+
$f \cdot \dot y = \tau^\top v$ for every velocity $v$, so
|
|
58
58
|
|
|
59
59
|
$$
|
|
60
60
|
\tau = \sum_k J_{q,k}^\top f_k ,
|
|
@@ -70,8 +70,8 @@ with $B$ the robot's actuation map. For a tendon arm $B = (\partial\theta/\parti
|
|
|
70
70
|
with $\theta$ the motor angles. With one motor per joint $B$ is the identity. The controller
|
|
71
71
|
never divides $u$ by an [efficiency](efficiency.md). A robot with fewer motors than joints has
|
|
72
72
|
no $u$ that solves it for every $\tau$: the motors give the least-squares
|
|
73
|
-
$u = B^+\tau$, and
|
|
74
|
-
[the underactuated tutorial](../tutorials/underactuated.md)
|
|
73
|
+
$u = B^+\tau$, and the part of $\tau$ outside the range of $B$, which they cannot give, is the
|
|
74
|
+
torque defect of [the underactuated tutorial](../tutorials/underactuated.md).
|
|
75
75
|
|
|
76
76
|
## Virtual states
|
|
77
77
|
|
|
@@ -52,7 +52,7 @@ intersphinx_mapping = {
|
|
|
52
52
|
|
|
53
53
|
html_theme = "sphinx_immaterial"
|
|
54
54
|
html_title = "virtualmodelcontrol"
|
|
55
|
-
html_logo = "_static/logo-light.svg" # the header is navy in both
|
|
55
|
+
html_logo = "_static/logo-light.svg" # the header is navy in both color schemes
|
|
56
56
|
html_favicon = "_static/favicon.svg"
|
|
57
57
|
# Tooltips of API objects without their synopsis, which the theme joins with an em dash.
|
|
58
58
|
object_description_options = [("py:.*", {"generate_synopses": None})]
|
|
@@ -77,7 +77,7 @@ html_theme_options = {
|
|
|
77
77
|
{
|
|
78
78
|
"media": "(prefers-color-scheme: light)",
|
|
79
79
|
"scheme": "default",
|
|
80
|
-
"primary": "custom", #
|
|
80
|
+
"primary": "custom", # colors in _static/custom.css
|
|
81
81
|
"accent": "custom",
|
|
82
82
|
"toggle": {"icon": "material/weather-night", "name": "Dark mode"},
|
|
83
83
|
},
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
+
How to set up a working copy, run the checks, and send a change.
|
|
4
|
+
|
|
3
5
|
## Set up
|
|
4
6
|
|
|
5
7
|
From a clone of the repository, on Linux or macOS:
|
|
@@ -72,7 +74,9 @@ Pages are MyST notebooks: every code cell runs at each build, and an error fails
|
|
|
72
74
|
|
|
73
75
|
Versions follow semantic versioning and come from git tags. To release:
|
|
74
76
|
|
|
75
|
-
1. In `CHANGELOG.md`, rename "Unreleased" to the new version and date
|
|
77
|
+
1. In `CHANGELOG.md`, rename "Unreleased" to the new version and date, and add the version's
|
|
78
|
+
comparison link at the end of the file. Give `CITATION.cff` the same version and date, and the
|
|
79
|
+
pin example of `docs/installation.md` the new version.
|
|
76
80
|
2. Push `main`, then tag and push the tag:
|
|
77
81
|
|
|
78
82
|
```bash
|
|
@@ -5,9 +5,11 @@ What you can rely on from version 1.0.0 on.
|
|
|
5
5
|
## Versions of Python and of the packages
|
|
6
6
|
|
|
7
7
|
The library runs on Python 3.10 to 3.14, with numpy 1.26 or any 2.x. Every push runs the tests
|
|
8
|
-
on Ubuntu 22.04 and 24.04 with Python 3.
|
|
9
|
-
|
|
10
|
-
1.11, CasADi 3.6 and matplotlib 3.8.
|
|
8
|
+
on Ubuntu 22.04 with Python 3.10 and on Ubuntu 24.04 with Python 3.12 and 3.14, with numpy 1.26
|
|
9
|
+
and with 2.x (3.14 with 2.x only). One more job runs them on Python 3.10 with the oldest versions
|
|
10
|
+
the library allows: numpy 1.26, SciPy 1.11, CasADi 3.6 and matplotlib 3.8. Before a release the
|
|
11
|
+
tests also run on macOS and Windows, and we have run them from a fresh clone on 3.11 and 3.13.
|
|
12
|
+
PyTorch, which only the models exported as PyTorch code
|
|
11
13
|
need, is tried with its newest release.
|
|
12
14
|
|
|
13
15
|
A Python version is dropped, in a minor release and with a line in the
|
|
@@ -18,7 +18,7 @@ import docs_setup
|
|
|
18
18
|
|
|
19
19
|
The ADAPT finger has three phalanges and two motors: motor 0 turns the first joint (MCP)
|
|
20
20
|
through a pulley, and motor 1 turns the other two (PIP and DIP) together through a cable. Its
|
|
21
|
-
configuration is the two motor angles
|
|
21
|
+
configuration is the two motor angles $q_0, q_1$.
|
|
22
22
|
|
|
23
23
|
```{code-cell} python
|
|
24
24
|
:tags: [remove-input]
|
|
@@ -69,7 +69,9 @@ simulated finger can start to vibrate. `adapt.finger(efficiency=adapt.MOTOR_EFFI
|
|
|
69
69
|
includes the efficiencies.
|
|
70
70
|
|
|
71
71
|
The template takes its geometry and transmission as arguments. A longer finger with a larger
|
|
72
|
-
pulley on the MCP joint, for example, has a new first coupling ratio:
|
|
72
|
+
pulley on the MCP joint, for example, has a new first coupling ratio: the MCP joint turns by the
|
|
73
|
+
pulley's radius over the motor pulley's per motor angle, $3 / 5 = 0.6$ in place of the default
|
|
74
|
+
2.23 / 5 = 0.446:
|
|
73
75
|
|
|
74
76
|
```{code-cell} python
|
|
75
77
|
import numpy as np
|
|
@@ -78,7 +80,8 @@ from virtualmodelcontrol.robots import adapt
|
|
|
78
80
|
|
|
79
81
|
longer = adapt.finger(link_lengths=(0.045, 0.035, 0.02), # [m]
|
|
80
82
|
pulley_radius=0.003) # [m], on the MCP joint
|
|
81
|
-
|
|
83
|
+
default = adapt.finger().params["coupling"].value.round(3)
|
|
84
|
+
default, longer.params["coupling"].value.round(3) # before and after
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
A new pulley comes with a new ratio, which a sweep measures: set the MCP joint to known angles,
|