How the library is organized

This page is a map: what each part of the library does, and which names to look for. The library is a stack of layers. Each layer uses only the layers below it. The ready-made robots and the figures sit at the edges. They may use every layer, and no layer uses them.

../_images/8614dc688503539e269d90c40dd7884862e711bce2ea1a3f8b6a0f6057143589.svg

From the bottom, the layers are core (Params and signals), math, mechanisms, models, system, compiler and dynamics, control, sim, estimation and identification, and adaptation and optimization. The edges are robots, hardware, viz, config and testing.

A controller needs only the layers up to control: describe the robot with models, place virtual elements with mechanisms, pair them in a VirtualMechanismSystem, compile it and run it with VMCController. Simulation, figures and the robot templates are optional. The order is checked automatically on every change, and so is that nothing in the library imports a robot middleware such as ROS: signals come in and go out as arrays.

Where things are

You want to

Use

start from an existing robot

virtualmodelcontrol.robots: helyx, bimanual, adapt, turtle, ur5, planar

describe a new robot

vmc.models: PCC, SerialChain, JointSpace, LinearCoupling, Assembly, TendonTransmission

place virtual elements

vmc.Mechanism, coordinates and components such as vmc.LinearSpring

compile and run a controller

vmc.VirtualMechanismSystem, vmc.compile, vmc.VMCController

correct commands for real hardware

vmc.control.output: friction compensation, pretension, a tension floor, limits

get positions, Jacobians, Hessians

vmc.Kinematics

get the robot’s equations of motion

vmc.compile_dynamics (from the components, or from a function with vmc.models.Equations)

simulate a closed loop

vmc.sim: ModelPlant, run, SimClock

estimate the state, forces and stiffness

vmc.estimation: KalmanFilter, ContactForce, TaskStiffness

change a running controller’s Params to track a goal

vmc.adaptation: ForceTracking, StiffnessTracking, DitherSeeking

fit stiffness, damping and efficiencies to data

vmc.identification

plan a motion and optimize a controller’s Params

vmc.optimization: Problem, Collocation, Shooting, MPC, Effort, Cost, Bound

record, save, replay and compare runs

vmc.sim: RunLog, replay, compare

describe an experiment in a file

vmc.config: load, Experiment

draw and animate

vmc.viz

run a model without CasADi

backend="numpy" or "torch", Dynamics.export, Compiled.export

parameters, units, scopes

vmc.Param, vmc.ParamSet (Parameters)

One symbolic source

Every model is written once with CasADi operations. Jacobians, Hessians, the control law and the robot’s dynamics all come from that one graph by automatic differentiation, so they cannot disagree. The robot’s dynamics take one form for every robot, the residual

\[\begin{split} \begin{aligned} &M(q)\,\dot v + h(q, v) \\ &\quad - B(q)\,u - \textstyle\sum_k J_k^\top f_k = 0, \end{aligned} \end{split}\]

with \(M\) the mass matrix, \(h\) the velocity terms of the kinetic energy (Coriolis and centrifugal), \(B\) the actuation map, \(f_k\) the forces of the robot’s own components (springs, dampers, gravity) 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) gives the residual itself, as a function. The numpy and PyTorch versions of a model are not written again: they are generated from the same graph (Use a model outside CasADi).

To use these parts, start with your first controller.