Master Pendulum (MultiComponent)#

Motivation: why multiple models for one pendulum?#

In bio-mechatronic system simulation (e.g., prostheses and exoskeletons), the system-level behavior is shaped by coupled subsystems that are often best modeled with different tools:

  • Rigid-body dynamics (fast, robust, good for control design and early integration)

  • Musculoskeletal dynamics (to capture human–device interaction and physiology-driven constraints)

  • Deformable-body mechanics / FEM (to resolve local stresses, contact, and compliance that cannot be captured by rigid models)

This naturally leads to heterogeneous submodels of the same physical thing depending on your question:

  • For controller development and system wiring, a rigid-body pendulum can be sufficient and cheap.

  • For human-in-the-loop studies, an OpenSim model enables physiology-inspired modeling while still supporting rigid-body motion.

  • For contact phases (impact with a wall, compliant interaction, local stress), FEM provides the detail needed to study loads and material response.

The key challenge is that these models live at different fidelity levels and often have different internal states. A multi-model component provides a pragmatic workflow: use the simplest model that is “good enough” most of the time, and switch to a more detailed model only when needed (e.g., around contact).

What is a MultiComponent?#

syssimx.core.multi_comp.MultiComponent wraps multiple syssimx.core.base.CoSimComponent instances behind a single, unified port interface.

Conceptually:

  • The system connects to one component (here: MasterPendulum).

  • Internally, MasterPendulum contains several interchangeable models (modes), e.g. "FMU", "OpenSim", "FEM".

  • A mode selector decides which internal model is active.

  • On every switch, the wrapper translates and synchronizes state so the new model continues from a consistent configuration.

  • Optional hysteresis prevents rapid chattering near switching thresholds.

See the API docs for details: syssimx.core.multi_comp.MultiComponent and syssimx.core.multi_comp.Hysteresis.

MasterPendulum: one interface, three implementations#

In this repository, the Master Pendulum is implemented as a multi-model component that bundles three pendulum implementations:

  • Modelica / FMU pendulum (rigid-body mechanics, exported as FMU)

  • OpenSim pendulum (rigid-body mechanics with OpenSim tooling)

  • FEM pendulum (deformable mechanics and optional contact)

The wrapper exposes a consistent set of ports (inputs/outputs) so it can be dropped into a larger system without re-wiring when the internal model changes.

Typical minimal ports are:

  • input: torque (and optionally event inputs such as omega_invert)

  • outputs: theta, omega, alpha (and optionally contact diagnostics)

Workflow: building your own multi-model component#

  1. Implement each submodel as a syssimx.core.base.CoSimComponent (or reuse existing ones) with the same external ports (inputs/outputs).

  2. Create a wrapper class that inherits from syssimx.core.multi_comp.MultiComponent.

  3. Register models in self.models (e.g. {"FMU": ..., "OpenSim": ..., "FEM": ...}) and pick an initial_mode.

  4. Unify ports so the wrapper exposes one consistent interface.

  5. Implement _adapt_state(...) to translate between state conventions.

  6. Define a switching rule via mode_selector and stabilize it with syssimx.core.multi_comp.Hysteresis.

  7. Use the wrapper as a single plant component inside a syssimx.system.system.System, connected to sensors, a controller, and an actuator/drive.

Why switch models at runtime?#

Runtime switching is useful when different phases of the motion require different physics:

  • Free swing / control tracking: rigid-body models are usually sufficient to capture kinematics and sensor/controller dynamics at low cost.

  • Contact / impact: FEM can resolve penetration, local compliance, and stress peaks that rigid models approximate poorly.

In practice, switching rules can be:

  • State-based (e.g., switch to FEM when a contact gap becomes small or a threshold angle is approached),

  • Event-based (e.g., use FEM during a wall-hit window),

  • Time-based (useful for debugging and verification),

  • Hybrid (combine state thresholds with dwell-time hysteresis).

State synchronization: the “hard part”#

Switching is only meaningful if the target model starts from a consistent state. For a pendulum, a common “shared state” is:

  • angle theta

  • angular velocity omega

  • applied torque torque

However, some models may require different state/parameter names. For example, the FMU pendulum may use initial condition parameters q0 and omega0 instead of direct state overwrite. The multi-model wrapper handles this via an adaptation hook:

def _adapt_state(self, state, target_mode):
    if target_mode == "FMU":
        return {"q0": state["q"], "omega0": state["omega"], "torque": state["torque"]}
    return state

In SysSimX, these state entries are typically structured dictionaries (e.g., {"q": {"value": ..., "unit": "rad"}}), not raw floats. State adaptation therefore usually maps named entries between models (and sometimes converts units or sign conventions).

Important modeling note: switching between FEM and rigid-body dynamics is a projection. FEM contains internal deformation/strain energy states that are not representable in a rigid model. Decide deliberately what is conserved or discarded at the switch (energy, momentum, contact impulses), and use hysteresis to avoid excessive switching artifacts.

Practical guidelines (what to verify early)#

  • Interface consistency: confirm the same sign conventions, units, and reference frames across FMU/OpenSim/FEM (especially torque direction and angle definition).

  • Switch variable robustness: base switching on signals that are stable and physically meaningful (e.g., contact gap or angle thresholds), and add syssimx.core.multi_comp.Hysteresis to prevent chattering.

  • Internal state mismatch: explicitly decide how you “collapse” deformable states (FEM) into rigid states (and how you re-introduce deformation when switching back).

  • Numerical transients: expect discontinuities at switches; validate continuity of the shared outputs (theta, omega) and monitor energy where applicable.

  • System-level validation: validate each pendulum model standalone first, then validate the closed-loop system with and without switching.

Tutorials#