Skip to content

Robot, Dynamics, and Simulation

Robot

The Robot struct is the digital twin of the physical system. It stores all static properties and dynamic history of the robot.

Its core components include:

  • structure — maintains the multibody topology (see Structure), containing all rigid bodies, joints, and apparatuses.

  • hub — manages control-related actuators and error gauges in one place (see Control Hub).

  • Trajectory containers — persist all data generated during simulation, including traj (state trajectory), contacts_traj (contact-related trajectory), and control_traj (control-related trajectory).


Dynamics and Simulation

Rible provides a extensible dynamics simulation framework supporting multiple integration algorithms, contact mechanics, and control strategies.

Core Architecture: In Rible, the physical model (DynamicsProblem) and the solution strategy (DynamicsSolver) are decoupled. You can seamlessly swap between different solver algorithms for the same physical system without modifying any model definition.

Core Components

DynamicsProblem

DynamicsProblem is the data container for simulation tasks. It is an immutable struct that binds all static properties of the physical system and its environment, providing clear computation boundaries for the solver.

It contains:

  • Robot — the mechanical system's topology, mass distribution, and runtime state (see Robot).

  • Objective — the cost function for adjoint analysis, typically built from ErrorGauge instances.

  • Environment — provides spatial context (Geometry) and passive external forcing (Field), avoiding hard-coding global forces into the robot. Default to (EmptyEnv).

    • Field — provides global external forces, e.g., gravity field (Gravity).

    • Geometry — provides surfaces or mesh terrain for collision detection.

  • Policy — maps the current system state to active control forces u. Encapsulating it separately enables free switching between open-loop and closed-loop control. Default to NoPolicy.

    • Open-loop: e.g., time-based curves.

    • Closed-loop feedback: e.g., proportional-derivative (DiscretePD) or neural network policies.

  • Models — constrains the mathematical form of physical interactions, e.g., contact models (subtypes of AbstractContactModel).

DynamicsSolver

If DynamicsProblem defines "what to compute," then DynamicsSolver handles "how to compute." Due to the complexity of rigid-flexible coupled systems, it is designed as a pluggable dispatch center. It does not store physical state itself — instead, it composes different numerical integrators and sub-solvers to specify the behavior of the system's evolution.

  • Integrator — To specify the scheme which computes the next system state at discrete time steps, handling stiffness and algebraic constraints.

  • Sub-Solvers — includes the body solver, apparatus solver, and contact solver. For contact-intensive scenarios, advanced nonlinear complementarity solvers can be configured independently.


Configuring Integrators

Integrators are the numerical engines of the DynamicsSolver. Selecting the right integrator is crucial for simulation stability and accuracy.

Zhong 06

The default recommended integrator for most constrained multibody systems, originally proposed by Prof. Wanxie Zhong, and has been modified and developed for non-smooth contact dynamics [1]. It is a second-order, constraint-preserving, and symplectic-like scheme that maintains energy conservation and constraint manifold consistency over long durations.

julia
# Construct with default settings
integrator = Zhong06()
solver = DynamicsSolver(integrator)
DynamicsSolver{Zhong06, Rible.NoBodySolver, Rible.NoApparatusSolver, Rible.NoContactSolver, @NamedTuple{}}(Zhong06(), Rible.NoBodySolver(), Rible.NoApparatusSolver(), Rible.NoContactSolver(), NamedTuple())

Runge-Kutta (RK) Family

Supports various generic implicit Runge-Kutta tableaus, like Gauss-Legendre (GL), via the RungeKutta.jl package. It is excellent for high-accuracy requirements in smooth systems.

julia
using RungeKutta
# Construct a 2-stage Gauss-Legendre (implicit) integrator
integrator = RKIntegrator(RungeKutta.TableauGauss(2))
solver = DynamicsSolver(integrator)
DynamicsSolver{RKIntegrator{RungeKutta.Tableau{Float64, 2, Int64, 4}}, Rible.NoBodySolver, Rible.NoApparatusSolver, Rible.NoContactSolver, @NamedTuple{}}(RKIntegrator{RungeKutta.Tableau{Float64, 2, Int64, 4}}(
Runge-Kutta Tableau Gauss with 2 stages and order 4:
 0.211325 │     0.25  -0.0386751
 0.788675 │ 0.538675        0.25
──────────┼──────────────────────
          │      0.5         0.5
), Rible.NoBodySolver(), Rible.NoApparatusSolver(), Rible.NoContactSolver(), NamedTuple())

Extra Integrators (Generalized-α, Moreau-Jean)

For specialized needs in comparison and evaluation, Rible provides additional integrators in the RibleExtraIntegrators package.


Typical Simulation Workflow

Rible provides a two-level interface that balances out-of-the-box convenience with deep customization.

1. Convenient API: solve!

For most standard scenarios, use the solve! method directly. It handles memory allocation and runs the main loop internally.

The following example reuses the repository's spinning-top model. The top starts with high angular velocity, touches a planar ground, and produces a trajectory that we can inspect at the end of the page.

julia
include(joinpath(pathof(Rible), "../../examples/robots/spinningtop.jl"))

origin_position = [0.0, 0.0, 0.5]
R = RotX(0.0)
origin_velocity = [1.0, 0.0, 0.0]
Ω = [0.0, 0.0, 200.0]

top = make_top(origin_position, R, origin_velocity, Ω, :NCF; μ = 0.95, e = 0.5, loadmesh = false)
top.structure.connectivity.num_of_bodies
1

The model already bundles its Structure and ControlHub, so the next step is to define the contact surface and interaction law.

julia
planes = StaticContactSurfaces([
    HalfSpace([0.0, 0.0, 1.0], [0.0, 0.0, 0.0]),
])

contact_model = RestitutionFrictionCombined(
    NewtonRestitution(),
    CoulombFriction(),
)

prob = DynamicsProblem(top; env=planes, contact_model)
DynamicsProblem{Robot{Structure{TypeSortedCollections.TypeSortedCollection{Tuple{Vector{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}}, 1}, Vector{Int64}, Connectivity{Vector{Vector{Int64}}}, Rible.StructureState{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, Vector{CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}}}, @NamedTuple{activated_bits::BitVector, persistent_bits::BitVector, friction_coefficients::Vector{Float64}, restitution_coefficients::Vector{Float64}, gaps::Vector{Float64}}, Rible.StructureCache{InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseVector{Float64, Int64}}}}, ControlHub{Vector{Int64}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}}}, 1}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}}}, 1}, Coalition, @NamedTuple{c::Vector{Float64}, e::Vector{Float64}, u::Vector{Float64}}}, StructArrays.StructVector{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, @NamedTuple{t::Vector{Float64}, q::Vector{Vector{Float64}}, q̇::Vector{Vector{Float64}}, q̈::Vector{Vector{Float64}}, F::Vector{Vector{Float64}}, λ::Vector{Vector{Float64}}, s::Vector{Vector{Float64}}, p::Vector{Vector{Float64}}, c::Vector{Vector{Float64}}}, Int64}, Vector{Vector{Rible.Contact{Float64}}}, Vector{@NamedTuple{na::Int64, bodyid2act_idx::Vector{Vector{Int64}}, persistent_idx::Vector{Int64}, activated_bits::BitVector, H::LinearAlgebra.Diagonal{Float64, Vector{Float64}}, activated_restitution_coefficients::Vector{Float64}, D::Matrix{Float64}, Dper::Matrix{Float64}, Dimp::Matrix{Float64}, ∂Dq̇∂q::Matrix{Float64}, ∂DᵀΛ∂q::Matrix{Float64}, ŕ::Vector{Float64}, L::Matrix{Float64}, Lv::Matrix{Float64}, Λ::Vector{Float64}, Γ::Vector{Float64}}}, StructArrays.StructVector{@NamedTuple{c::Vector{Float64}, e::Vector{Float64}, u::Vector{Float64}}, @NamedTuple{c::Vector{Vector{Float64}}, e::Vector{Vector{Float64}}, u::Vector{Vector{Float64}}}, Int64}}, Rible.NoPolicy, Rible.StaticEnvironment{Vector{HalfSpace{Float64, 3}}, Rible.Gravity{Float64}}, Objective{Vector{Int64}, Rible.var"#default_objective##0#default_objective##1"}, RestitutionFrictionCombined{NewtonRestitution, CoulombFriction}, Rible.Naive, @NamedTuple{}}(Robot{Structure{TypeSortedCollections.TypeSortedCollection{Tuple{Vector{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}}, 1}, Vector{Int64}, Connectivity{Vector{Vector{Int64}}}, Rible.StructureState{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, Vector{CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}}}, @NamedTuple{activated_bits::BitVector, persistent_bits::BitVector, friction_coefficients::Vector{Float64}, restitution_coefficients::Vector{Float64}, gaps::Vector{Float64}}, Rible.StructureCache{InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseVector{Float64, Int64}}}}, ControlHub{Vector{Int64}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}}}, 1}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}}}, 1}, Coalition, @NamedTuple{c::Vector{Float64}, e::Vector{Float64}, u::Vector{Float64}}}, StructArrays.StructVector{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, @NamedTuple{t::Vector{Float64}, q::Vector{Vector{Float64}}, q̇::Vector{Vector{Float64}}, q̈::Vector{Vector{Float64}}, F::Vector{Vector{Float64}}, λ::Vector{Vector{Float64}}, s::Vector{Vector{Float64}}, p::Vector{Vector{Float64}}, c::Vector{Vector{Float64}}}, Int64}, Vector{Vector{Rible.Contact{Float64}}}, Vector{@NamedTuple{na::Int64, bodyid2act_idx::Vector{Vector{Int64}}, persistent_idx::Vector{Int64}, activated_bits::BitVector, H::LinearAlgebra.Diagonal{Float64, Vector{Float64}}, activated_restitution_coefficients::Vector{Float64}, D::Matrix{Float64}, Dper::Matrix{Float64}, Dimp::Matrix{Float64}, ∂Dq̇∂q::Matrix{Float64}, ∂DᵀΛ∂q::Matrix{Float64}, ŕ::Vector{Float64}, L::Matrix{Float64}, Lv::Matrix{Float64}, Λ::Vector{Float64}, Γ::Vector{Float64}}}, StructArrays.StructVector{@NamedTuple{c::Vector{Float64}, e::Vector{Float64}, u::Vector{Float64}}, @NamedTuple{c::Vector{Vector{Float64}}, e::Vector{Vector{Float64}}, u::Vector{Vector{Float64}}}, Int64}}(Structure{TypeSortedCollections.TypeSortedCollection{Tuple{Vector{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}}, 1}, Vector{Int64}, Connectivity{Vector{Vector{Int64}}}, Rible.StructureState{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, Vector{CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}}}, @NamedTuple{activated_bits::BitVector, persistent_bits::BitVector, friction_coefficients::Vector{Float64}, restitution_coefficients::Vector{Float64}, gaps::Vector{Float64}}, Rible.StructureCache{InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseVector{Float64, Int64}}}}(3, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}}, 1}((RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}[RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}(RigidBodyProperty{3, Float64, 9}(true, true, 1, :generic, 0.5838707, [0.00022129 0.0 0.0; 0.0 0.00022129 0.0; 0.0 0.0 0.00030207], Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.0, 0.0), Locus{3, Float64, 9}[Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, -0.03795882], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5)]), RigidBodyState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 200.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}[Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.46204118], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0])]), NC{3, 3, Float64, 9, 12, 144}(1, 3, LNCData{3, 3, Float64, 9}([0.0, 0.0, 0.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [1 0 … 0 0; 0 1 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], LinearAlgebra.Symmetric{Int64, SparseArrays.SparseMatrixCSC{Int64, Int64}}[[0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 2 0; 0 0 … 0 2], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0]], 6, [1, 2, 3, 4, 5, 6]), RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}([1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], StaticArraysCore.SMatrix{3, 12, Float64, 36}[[1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … -0.03795882 0.0; 0.0 0.0 … 0.0 -0.03795882], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]], InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}(sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [0.5838707, 0.5838707, 0.5838707, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 7.025499999999997e-5, 7.025499999999997e-5, 7.025499999999997e-5], 12, 12), sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1.7127079677058636, 1.7127079677058636, 1.7127079677058636, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 14233.862358551, 14233.862358551, 14233.862358551], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], false), [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]), Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}}(...))],), ([1],)), Int64[], Connectivity{Vector{Vector{Int64}}}(1, 0, 0, 0, 12, 6, 0, 6, 6, 6, 0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]], [[1, 2, 3, 4, 5, 6]], [[1, 2, 3, 4, 5, 6]], Vector{Int64}[], Vector{Int64}[], [[1, 2, 3, 4, 5, 6]], Signifier{Int64}[Signifier{Int64}(1, 1), Signifier{Int64}(1, 2), Signifier{Int64}(1, 3), Signifier{Int64}(1, 4), Signifier{Int64}(1, 5), Signifier{Int64}(1, 6)], [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]], 7, 18, 18, 0, 18, Vector{Int64}[], Vector{Int64}[]), Rible.StructureState{CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}, Vector{CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}}}(CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}(0.0, [0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 200.0, 0.0, -200.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], Float64[], [0.5838707, 0.0, 0.0, 0.0, 0.030206999999999994, 0.0, -0.030206999999999994, 0.0, 0.0, 0.0, 0.0, 0.0], [0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.0, 0.0, -0.03795882, 0.0, 0.0, 0.0]), CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}[CoordinatesState{Float64, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}, Vector{Float64}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}(0.0, [0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 200.0, 0.0, -200.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], Float64[], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.0, 0.0, -0.03795882, 0.0, 0.0, 0.0])]), (activated_bits = Bool[0, 0, 0, 0, 0, 0], persistent_bits = Bool[0, 0, 0, 0, 0, 0], friction_coefficients = [0.95, 0.95, 0.95, 0.95, 0.95, 0.95], restitution_coefficients = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5], gaps = [Inf, Inf, Inf, Inf, Inf, Inf]), Rible.StructureCache{InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseVector{Float64, Int64}}}(InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseVector{Float64, Int64}}(sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [0.5838707, 0.5838707, 0.5838707, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 7.025499999999997e-5, 7.025499999999997e-5, 7.025499999999997e-5], 12, 12), sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1.7127079677058636, 1.7127079677058636, 1.7127079677058636, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 14233.862358551, 14233.862358551, 14233.862358551], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), sparsevec(Int64[], Float64[], 12), sparsevec(Int64[], Float64[], 12), true))), ControlHub{Vector{Int64}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}}}, 1}, TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}}}, 1}, Coalition, @NamedTuple{c::Vector{Float64}, e::Vector{Float64}, u::Vector{Float64}}}(Int64[], TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}}}, 1}((ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}[ErrorGauge{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, PositionCaptum, Vector{Float64}}(1, Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}(RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}(RigidBodyProperty{3, Float64, 9}(true, true, 1, :generic, 0.5838707, [0.00022129 0.0 0.0; 0.0 0.00022129 0.0; 0.0 0.0 0.00030207], Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.0, 0.0), Locus{3, Float64, 9}[Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, -0.03795882], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5)]), RigidBodyState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 200.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}[Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.46204118], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0])]), NC{3, 3, Float64, 9, 12, 144}(1, 3, LNCData{3, 3, Float64, 9}([0.0, 0.0, 0.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [1 0 … 0 0; 0 1 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], LinearAlgebra.Symmetric{Int64, SparseArrays.SparseMatrixCSC{Int64, Int64}}[[0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 2 0; 0 0 … 0 2], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0]], 6, [1, 2, 3, 4, 5, 6]), RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}([1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], StaticArraysCore.SMatrix{3, 12, Float64, 36}[[1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … -0.03795882 0.0; 0.0 0.0 … 0.0 -0.03795882], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]], InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}(sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [0.5838707, 0.5838707, 0.5838707, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 7.025499999999997e-5, 7.025499999999997e-5, 7.025499999999997e-5], 12, 12), sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1.7127079677058636, 1.7127079677058636, 1.7127079677058636, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 14233.862358551, 14233.862358551, 14233.862358551], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], false), [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]), Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}}(...)), 6), PositionCaptum(), [0.5, 0.0, 0.2])],), ([1],)), TypeSortedCollections.TypeSortedCollection{Tuple{Vector{ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}}}, 1}((ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}[ExternalForceActuator{Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}, NaiveOperator, Vector{Float64}, Float64}(1, Signifier{RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}}(RigidBody{3, 3, Float64, 9, NC{3, 3, Float64, 9, 12, 144}, RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}, GeometryBasics.Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}, (:position, :normal), Tuple{Vector{GeometryBasics.Point{3, Float64}}, Vector{GeometryBasics.Vec{3, Float64}}}, Vector{GeometryBasics.TriangleFace{Int64}}}}(RigidBodyProperty{3, Float64, 9}(true, true, 1, :generic, 0.5838707, [0.00022129 0.0 0.0; 0.0 0.00022129 0.0; 0.0 0.0 0.00030207], Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.0, 0.0), Locus{3, Float64, 9}[Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, -0.03795882], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5), Locus{3, Float64, 9}([0.0, 0.0, 0.0], Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), 0.95, 0.5)]), RigidBodyState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 200.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}[Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.03111269837220809, 0.03111269837220809, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.46204118], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0]), Rible.LocusState{3, 3, Float64, 9}(Rible.CartesianFrame{3, 3, Float64, 9}([0.0, 0.0, 0.5], Rible.Axes{3, Float64, 9}([0.0 0.0 1.0; 1.0 -0.0 0.0; 0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 200.0], [0.0, 200.0, 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Rible.ContactState{3, Float64, 9}(false, true, Inf, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]), [1.0, 0.0, 0.0])]), NC{3, 3, Float64, 9, 12, 144}(1, 3, LNCData{3, 3, Float64, 9}([0.0, 0.0, 0.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0]), [1 0 … 0 0; 0 1 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 1 0; 0 0 … 0 1], LinearAlgebra.Symmetric{Int64, SparseArrays.SparseMatrixCSC{Int64, Int64}}[[0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 2 0; 0 0 … 0 2], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0], [0 0 … 0 0; 0 0 … 0 0; … ; 0 0 … 0 0; 0 0 … 0 0]], 6, [1, 2, 3, 4, 5, 6]), RigidBodyCache{StaticArraysCore.SMatrix{3, 12, Float64, 36}, InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}, StaticArraysCore.MMatrix{6, 12, Float64, 72}}([1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], StaticArraysCore.SMatrix{3, 12, Float64, 36}[[1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … -0.03795882 0.0; 0.0 0.0 … 0.0 -0.03795882], [1.0 0.0 … 0.0 0.0; 0.0 1.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]], InertiaCache{SparseArrays.SparseMatrixCSC{Float64, Int64}, SparseArrays.SparseMatrixCSC{Float64, Int64}, StaticArraysCore.MVector{12, Float64}}(sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [0.5838707, 0.5838707, 0.5838707, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 0.00015103499999999997, 7.025499999999997e-5, 7.025499999999997e-5, 7.025499999999997e-5], 12, 12), sparse([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1.7127079677058636, 1.7127079677058636, 1.7127079677058636, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 6620.981891614528, 14233.862358551, 14233.862358551, 14233.862358551], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), sparse(Int64[], Int64[], Float64[], 12, 12), [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], false), [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]), Mesh{3, Float64, GeometryBasics.TriangleFace{Int64}}(...)), 5), NaiveOperator(1), [0.0, 1.0, 0.0], [0.0])],), ([1],)), Coalition(1, 0, 1, 0, 1, Vector{Int64}[], [[1]], 1, [[1]]), (c = Float64[], e = [0.16999999999999998], u = [0.0])), CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}[CoordinatesState{Float64, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}}(0.0, [0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 200.0, 0.0, -200.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], Float64[], [0.5838707, 0.0, 0.0, 0.0, 0.030206999999999994, 0.0, -0.030206999999999994, 0.0, 0.0, 0.0, 0.0, 0.0], [0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.03111269837220809, 0.03111269837220809, 0.0, 0.0, 0.0, -0.03795882, 0.0, 0.0, 0.0])], Vector{Rible.Contact{Float64}}[[Rible.Contact{Float64}(1, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), Rible.Contact{Float64}(2, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), Rible.Contact{Float64}(3, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), Rible.Contact{Float64}(4, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), Rible.Contact{Float64}(5, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), Rible.Contact{Float64}(6, 0.95, 0.5, Rible.ContactState{3, Float64, 9}(false, true, 1.0, Rible.Axes{3, Float64, 9}([-0.0 -0.0 1.0; 1.0 -0.0 0.0; -0.0 1.0 0.0]), [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]))]], @NamedTuple{na::Int64, bodyid2act_idx::Vector{Vector{Int64}}, persistent_idx::Vector{Int64}, activated_bits::BitVector, H::LinearAlgebra.Diagonal{Float64, Vector{Float64}}, activated_restitution_coefficients::Vector{Float64}, D::Matrix{Float64}, Dper::Matrix{Float64}, Dimp::Matrix{Float64}, ∂Dq̇∂q::Matrix{Float64}, ∂DᵀΛ∂q::Matrix{Float64}, ŕ::Vector{Float64}, L::Matrix{Float64}, Lv::Matrix{Float64}, Λ::Vector{Float64}, Γ::Vector{Float64}}[(na = 0, bodyid2act_idx = [[0, 0, 0, 0, 0, 0]], persistent_idx = [], activated_bits = [0, 0, 0, 0, 0, 0], H = Diagonal(Float64[]), activated_restitution_coefficients = [], D = Matrix{Float64}(undef, 0, 12), Dper = Matrix{Float64}(undef, 0, 12), Dimp = Matrix{Float64}(undef, 0, 12), ∂Dq̇∂q = Matrix{Float64}(undef, 0, 12), ∂DᵀΛ∂q = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], ŕ = [], L = Matrix{Float64}(undef, 0, 0), Lv = Matrix{Float64}(undef, 0, 0), Λ = [], Γ = [])], [(c = Float64[], e = [0.16999999999999998], u = [0.0])]), Rible.NoPolicy(), Rible.StaticEnvironment{Vector{HalfSpace{Float64, 3}}, Rible.Gravity{Float64}}(HalfSpace{Float64, 3}[HalfSpace{Float64, 3}([0.0, 0.0, 1.0], -0.0, [0.0, 0.0, 0.0])], Rible.Gravity{Float64}(9.81)), Objective{Vector{Int64}, Rible.var"#default_objective##0#default_objective##1"}([0], [0], [0], [0], Rible.var"#default_objective##0#default_objective##1"()), RestitutionFrictionCombined{NewtonRestitution, CoulombFriction}(NewtonRestitution(), CoulombFriction()), Rible.Naive(), NamedTuple())

With the setup complete, define a contact-aware solver and run a short simulation.

julia
solver = DynamicsSolver(
    Zhong06(),
    InnerLayerContactSolver(InteriorPointMethod()),
)

sim_result = solve!(
    prob,
    solver;
    tspan = (0.0, 0.2),
    dt = 5e-4,
    ftol = 1e-14,
    maxiters = 50,
    exception = false,
)

tip_position = get_trajectory!(top, 1, 1).u[end]
tip_velocity = get_velocity!(top, 1, 1).u[end]
tip_position, tip_velocity
([0.15600299208285673, -0.0005131221482334511, 0.3038000000022407], [1.1026244296463368, -8.799401583428741, -1.9619999999775923])

2. Simulation Container — Simulator

Simulator is the execution container responsible for maintaining runtime state.

When you need fine-grained control over the main loop (e.g., integrating with an external reinforcement learning framework, adding runtime controllers, or implementing hot-restart from exceptions), explicitly create a Simulator and step through manually:

julia
top_restart = make_top(origin_position, R, origin_velocity, Ω, :NCF; μ = 0.95, e = 0.5, loadmesh = false)
prob_restart = DynamicsProblem(top_restart; env=planes, contact_model)

sim = Simulator(prob_restart, solver; tspan = (0.0, 0.02), dt = 5e-4, restart = true)
solve!(sim, solver; dt = 5e-4)
traj_len_sim = length(top_restart.traj)
t_end_sim = top_restart.traj.t[end]
traj_len_sim, t_end_sim
(41, 0.02)

After integration, extract post-processing metrics directly from the top's trajectory containers.

julia
E = mechanical_energy!(top)
E[begin], E[end]
((T = 6.333335349999999, V = 0.0, E = 6.333335349999999), (T = 7.45712413142055, V = 0.0, E = 7.45712413142055))

To visualize the path directly, extract one point trajectory from the recorded simulation and draw it with Makie.lines.

julia
tip_traj = get_trajectory!(top, 1, 1).u
tip_points = Point3.(tip_traj)

fig_traj = Figure()
ax_traj = Axis3(fig_traj[1, 1], aspect = :data)
Makie.lines!(ax_traj, tip_points, linewidth = 2)
fig_traj

Additionally, trajectory data can be fed into the Visualization workflows for further plotting and animation.


Core Mechanisms and Performance

Rible achieves high performance through zero-overhead abstractions enabled by multiple dispatch and the traits system.

  1. Trajectory memory pre-allocation (prepare_traj!) Called automatically when initializing a Simulator. Pre-allocates a contiguous memory block for the state sequence over the entire time span.

  2. Automatic workspace generation (generate_cache) Before simulation starts, generates a type-specific Workspace at compile time based on the concrete problem and solver types, to allow algorithm safely owns its cache matrices (e.g., Jacobians).

  3. Trait-based dispatch optimization Uses static analysis of physical traits, like has_constant_mass_matrix(bot), to check whether the mass matrix is constant. If so, the compiler automatically skips mass matrix recomputation.

References

  1. J. Luo, X. Xu, X. Liu and Z. Wu. A Nonsmooth Modified Symplectic Integration Scheme for Frictional Contact Dynamics of Rigid–Flexible Multibody Systems. Computer Methods in Applied Mechanics and Engineering 420, 116726 (2024). Accessed on Jan 18, 2024.