Simulation
Index
RigidBodyDynamics.OdeIntegrators.ButcherTableau
RigidBodyDynamics.OdeIntegrators.ExpandingStorage
RigidBodyDynamics.OdeIntegrators.MuntheKaasIntegrator
RigidBodyDynamics.OdeIntegrators.MuntheKaasIntegrator
RigidBodyDynamics.OdeIntegrators.OdeResultsSink
RigidBodyDynamics.OdeIntegrators.RingBufferStorage
RigidBodyDynamics.OdeIntegrators.integrate
RigidBodyDynamics.OdeIntegrators.runge_kutta_4
RigidBodyDynamics.OdeIntegrators.step
RigidBodyDynamics.simulate
Basic simulation
RigidBodyDynamics.simulate
— Function.simulate(state0, final_time)
simulate(state0, final_time, control!; Δt, stabilization_gains)
Basic Mechanism
simulation: integrate the state from time $0$ to final_time
starting from the initial state state0
. Return a Vector
of times, as well as Vector
s of configuration vectors and velocity vectors at these times.
Optionally, a function (or other callable) can be passed in as the third argument (control!
). control!
will be called at each time step of the simulation and allows you to specify joint torques given the time and the state of the Mechanism
. It should look like this:
function control!(torques::AbstractVector, t, state::MechanismState)
rand!(torques) # for example
end
The integration time step can be specified using the Δt
keyword argument (defaults to 1e-4
).
The stabilization_gains
keyword argument can be used to set PD gains for Baumgarte stabilization, which can be used to prevent separation of non-tree (loop) joints. See Featherstone (2008), section 8.3 for more information. There are several options for specifying gains:
nothing
can be used to completely disable Baumgarte stabilization.- Gains can be specifed on a per-joint basis using any
AbstractDict{JointID, <:RigidBodyDynamics.PDControl.SE3PDGains}
, which maps theJointID
for the non-tree joints of the mechanism to the gains for that joint. - As a special case of the second option, the same gains can be used for all joints by passing in a
RigidBodyDynamics.CustomCollections.ConstDict{JointID}
.
The default_constraint_stabilization_gains
function is called to produce the default gains, which use the last option.
Uses MuntheKaasIntegrator
. See RigidBodyDynamics.OdeIntegrators.MuntheKaasIntegrator
for a lower level interface with more options.
Lower level ODE integration interface
struct MuntheKaasIntegrator{N, T, F, S<:OdeResultsSink, X, L, M<:(RigidBodyDynamics.OdeIntegrators.MuntheKaasStageCache{N,T,Q,V,S} where S<:(AbstractArray{T,1} where T) where V<:(AbstractArray{T,1} where T) where Q<:(AbstractArray{T,1} where T))}
A Lie-group-aware ODE integrator.
MuntheKaasIntegrator
is used to properly integrate the dynamics of globally parameterized rigid joints (Duindam, Port-Based Modeling and Control for Efficient Bipedal Walking Robots, 2006, Definition 2.9). Global parameterizations of e.g. $SO(3)$ are needed to avoid singularities, but this leads to the problem that the tangent space no longer has the same dimension as the ambient space of the global parameterization. A Munthe-Kaas integrator solves this problem by converting back and forth between local and global coordinates at every integration time step.
The idea is to do the dynamics and compute the stages of the integration scheme in terms of local coordinates centered around the global parameterization of the configuration at the end of the previous time step (e.g. exponential coordinates), combine the stages into a new set of local coordinates as usual for Runge-Kutta methods, and then convert the local coordinates back to global coordinates.
From Iserles et al., 'Lie-group methods' (2000).
Another useful reference is Park and Chung, 'Geometric Integration on Euclidean Group with Application to Articulated Multibody Systems' (2005).
MuntheKaasIntegrator(state, dynamics!, tableau, sink)
Create a MuntheKaasIntegrator
given:
- a callable
dynamics!(vd, t, state)
that updates the joint acceleration vectorvd
at timet
and in statestate
; - a
ButcherTableau
tableau
, specifying the integrator coefficients; - an
OdeResultsSink
sink
which processes the results of the integration procedure at each time step.
state
must be of a type for which the following functions are defined:
configuration(state)
, returns the configuration vector in global coordinates;velocity(state)
, returns the velocity vector;additional_state(state)
, returns the vector of additional states;set_velocity!(state, v)
, sets velocity vector tov
;set_additional_state!(state, s)
, sets vector of additional states tos
;global_coordinates!(state, q0, ϕ)
, sets global coordinates in state based on local coordinatesϕ
centered around global coordinatesq0
;local_coordinates!(ϕ, ϕd, state, q0)
, converts state's global configurationq
and velocityv
to local coordinates centered around global coordinatesq0
.
struct ButcherTableau{N, T, L}
abstract type OdeResultsSink
Does 'something' with the results of an ODE integration (e.g. storing results, visualizing, etc.). Subtypes must implement:
initialize(sink, state)
: called with the initial state when integration begins.process(sink, t, state)
: called at every integration time step with the current state and time.
mutable struct RingBufferStorage{T, Q<:(AbstractArray{T,1} where T), V<:(AbstractArray{T,1} where T)} <: OdeResultsSink
An OdeResultsSink
that stores the state at each integration time step in a ring buffer.
mutable struct ExpandingStorage{T, Q<:(AbstractArray{T,1} where T), V<:(AbstractArray{T,1} where T)} <: OdeResultsSink
An OdeResultsSink
that stores the state at each integration time step in Vectors
that may expand.
integrate(integrator, final_time, Δt; max_realtime_rate)
Integrate dynamics from the initial state at time $0$ to final_time
using step size Δt
.
Return the Butcher tableau for the standard fourth order Runge-Kutta integrator.
RigidBodyDynamics.OdeIntegrators.step
— Method.step(integrator, t, Δt)
Take a single integration step.