Control Architecture
Robot control code tends to calcify into one monolithic class per robot, with every controller, every estimator, and every simulator branch wired together by hand. Adding a new robot means touching every controller. Adding a new controller means understanding every robot’s internals. Shinro’s control architecture decomposes the control stack into five small, swappable abstract base classes (ABCs) so that controllers, plants, estimators, trajectory generators, and physics backends can each change independently.
This page covers the philosophy — language- and robot-agnostic. For the hands-on, Python-specific implementation of this architecture, see Python Modules.
The five ABCs
Controller # computes control inputs from current + target statePlant # models a robot's dynamics, kinematics, and constraintsStateEstimator # estimates state from noisy measurementsTrajectoryGenerator # produces the reference path a Controller tracksPhysicsEngine # decouples a Plant from a specific simulator backendEach ABC is a minimal interface — a handful of methods, no more. A new robot implements Plant. A new control strategy implements Controller. Nothing else needs to change.
Data flow
A TrajectoryGenerator produces a reference path. A StateEstimator turns raw measurements into a state estimate. The Controller takes both — current state estimate and target state from the trajectory — and computes a control input. That input goes to the Plant, which advances its own state by one timestep, talking to a PhysicsEngine (in simulation) or real hardware I/O underneath.
TrajectoryGenerator ──target state──▶ Controller ◀──state estimate── StateEstimator │ ▲ │ control input │ measurement ▼ │ Plant ───────────────────────▶ PhysicsEngineRegistry + config-driven composition
Every concrete implementation of every ABC self-registers under a name. A generic factory looks up a class by name and constructs it from config — swapping a controller from LQR to MPC, or a trajectory from a straight line to a triangle, is a config change, not a code change. This is the mechanism, not just an aspiration: the same factory shape applies uniformly across all five ABCs.
Physics engine separation
The PhysicsEngine ABC is what makes a Plant implementation simulator-agnostic. A Plant talks to the physics engine through a small protocol (read joint state, write joint control) rather than importing a specific simulator directly. MuJoCo is the physics engine implemented today; the protocol is designed so PyBullet, Drake, or Isaac Sim could implement it without touching Plant code. Control code shouldn’t hardcode which simulator it runs against, any more than it should hardcode which robot it controls.
Simulation vs hardware parity
A Controller and a StateEstimator never talk to the physics engine or the robot directly — they only see state and measurements passed as arguments. That means the same controller and estimator instances can run unmodified in simulation and on real hardware; only the Plant’s underlying I/O changes (simulated physics vs. actual motor commands). Nonlinearity — inverse kinematics, joint limits, actuator constraints — is encapsulated inside the Plant, so a Controller can stay linear even when the robot it drives is not.
Relationship to Shinro modules
This is a control architecture, not a Shinro module descriptor. A library module can wrap this architecture — acquire it, expose its capabilities through a descriptor, and let the kernel compose it with the rest of a project’s module graph — but the architecture itself is a Python composition pattern that exists independently of the descriptor system. Today, using it means writing Python against these five ABCs directly; wrapping it as a library module is a future integration path, not something that exists yet.
In practice: Python Modules
Python Modules is the operational guide to this architecture as implemented today: install, run the reference demos, read the component catalog, and extend it with a new controller, plant, or physics engine.
Terminology
“Module” is used for two related but distinct things across these docs — worth being precise about:
- Shinro module — a kernel descriptor unit (TOML +
cake), composed and hot-swapped by the Backend Kernel. See The Module System. - Python modules architecture — Shinro’s registry-based Python composition pattern described on this page and in Python Modules: five ABCs, factories, TOML config. Not itself a Shinro module descriptor.
- Control component — a registered ABC implementation, e.g.
LQR,ArmRobot,MuJoCoEngine. - Control stack — the full composed loop: trajectory generator → controller ← state estimator ← plant → physics engine.
- Reference robot — LeKiwi, the mobile manipulator used in today’s demos. A current demo target, not a framework constraint.