Skip to content

Simulation and plugins

flapsim.core.simulation.Simulation

Own the MuJoCo model and data and step them with attached plugins.

robot is a :class:~flapsim.robot.RobotModel or anything :func:flapsim.robot.load accepts. Plugins are added with :meth:add (instances, "kind/name" strings or config mappings) and run in the order they were added inside each phase; see :mod:flapsim.core.phases.

add(*plugins)

Add plugins (instances, "kind/name" or config mappings).

advance(seconds)

Step headless for seconds of simulated time; return the step count.

run(duration=None, *, viewer=False, realtime=True, fps=60.0, on_frame=None)

Run for duration seconds, headless or in the passive viewer.

on_frame(sim, viewer_handle) is called once per rendered frame.

from_config(config, *, base=None, overrides=None) classmethod

Build a simulation from a flapsim.sim/1 YAML/JSON file or mapping.

flapsim.core.signals.SignalBus

matching(*patterns)

Signal names matching any shell-style pattern (wings/*/F_N).

flapsim.core.config

Simulation configuration files (schema: flapsim.sim/1).

::

schema: flapsim.sim/1
robot: robot.yaml            # built-in name, manifest or model file
base: fixed                  # optional override of the manifest's base
plugins:
  - type: actuator/sinusoidal_stroke
    id: stroke
    joints: [left_stroke, right_stroke]
    frequency_hz: 30.0
  - type: aero/quasi_steady
run:
  duration: 2.0
  viewer: false

SimConfigError

Bases: ValueError

Raised when a simulation configuration is malformed.

load_sim_config(path)

Read and validate a simulation config; relative paths are kept as is.

build_simulation(config, *, base=None, overrides=None)

Create a :class:~flapsim.core.Simulation from a config file or mapping.

flapsim.plugins.base

Plugin base classes.

A plugin is bound to one :class:~flapsim.core.Simulation and participates in its step phases. Subclasses override the phases they need::

class MyAero(AeroPlugin):
    name = "my_aero"
    def setup(self):            # resolve MuJoCo ids once
        ...
    def forces(self):           # write xfrc_applied / qfrc_applied
        ...

Outputs are published as signals under <id>/<name>; commands are read from cmd/<id>/<name> so controllers and actuators stay decoupled.

Plugin

setup()

Resolve MuJoCo ids and validate configuration (called by bind).

reset()

Called after the simulation state was reset.

pre_control()

Sensors: read the state.

control()

Controllers: publish commands.

actuate()

Actuators: apply joint forces or kinematic targets.

forces()

Force models: write xfrc_applied / qfrc_applied.

post_step()

After mj_step; return True if qpos was changed.

record()

Recorders: sample the signal bus.

ForcePlugin

Bases: Plugin

AeroPlugin

Bases: ForcePlugin

AtmospherePlugin

Bases: Plugin

ActuatorPlugin

Bases: Plugin

SensorPlugin

Bases: Plugin

ControllerPlugin

Bases: Plugin

RecorderPlugin

Bases: Plugin

flapsim.plugins.registry

Plugin registry and discovery.

Built-in plugins register themselves with :func:register when flapsim.plugins.builtin is imported. Third-party packages declare an entry point in the flapsim.plugins group pointing at a plugin class, a module that registers plugins on import, or a callable that does so::

[project.entry-points."flapsim.plugins"]
my_aero = "my_package.aero:MyAero"

Plugins are addressed by "kind/name", for example "aero/quasi_steady".

register(cls=None, *, kind=None, name=None)

Class decorator (or function) adding a plugin class to the registry.

get(kind, name=None)

Return the plugin class for kind, name or "kind/name".

available(kind=None)

Registered plugin names, per kind or for one kind.

build(spec, **overrides)

Instantiate a plugin from "kind/name", a config mapping or a class.

discover_entry_points(group=ENTRY_POINT_GROUP, *, force=False)

Load plugins advertised by installed packages; return what was loaded.

flapsim.testing.conformance

Plugin conformance checks that third-party authors can run.

::

from flapsim.testing import check_plugin
check_plugin(lambda: MyAero(gain=2.0))

The check builds a simulation with a built-in robot, attaches the plugin, steps, resets and steps again, and verifies the metadata contract. It raises AssertionError with a plain-language message on failure and returns a report dictionary on success.

example_plugin_factories()

Factories for every registered plugin that ships an example_config.