Imagine a robot arm with a single input: a voltage from 0–10V that controls how hard it grips. Now imagine a bug in your grip detection firmware causes it to request 15V. The gripper crushes the object.
Now imagine a slightly different design: your control software requests a grip strength (1–10), which it sends to a separate hardware module that translates this into voltage. The hardware module refuses any request outside 1–10. Your bug requests strength 15, but the hardware says "invalid"—and the gripper grips at the maximum safe level, not beyond it.
This is the governed actuator pattern. It separates the act of requesting motion from the act of deciding whether that motion is allowed. One system does the thinking. A different system (hardware-backed, independent) decides whether to permit it.
The Problem with Monolithic Control
Traditional robotic control is monolithic: your central controller (a CPU running ROS, custom firmware, etc.) holds all authority. It generates motion commands, applies safety checks, manages state, and validates inputs—all in one process.
This architecture has a critical flaw: it gives the application CPU absolute authority. If your code is buggy, compromised, or corrupted, the safety checks go with it.
Scenario: A collaborative robot's collision detection code has a memory leak. After 72 hours, a pointer corruption causes the force sensor reading to be ignored. The robot doesn't know it's pushing into a human chest. No emergency stop is triggered because the safety check is code-based and it's running the corrupted logic.
The monolithic model cannot separate your good code from your bad code.
Governed Actuators: Two-System Architecture
A governed actuator splits the system:
System A: Application Controller
- Generates motion requests
- Decides what the robot should do
- Can be complex, adaptive, learning-based
- Can be buggy, may be compromised
- Does NOT have final authority
System B: Actuator Governor
- Receives motion requests from System A
- Evaluates each request against a fixed policy
- Has final authority (YES or NO)
- Simple, deterministic, verified
- Cannot be overridden by System A
System B is independent. It might run on a separate microcontroller, an FPGA gate, or an analog circuit. It is not patched by the same deployment pipeline as System A. It does not execute code loaded from the same source.
When System A requests motion, System B asks: "Is this request consistent with my policy?" If yes, the actuator moves. If no, it doesn't.
What the Governor Checks
A governor's policy is straightforward. Examples:
Velocity limit: "Motor speed shall not exceed 100 RPM. Deny any request above 100 RPM."
Torque limit: "Output torque shall not exceed 20 Nm. Any request mapping to higher torque is denied."
Position boundary: "Joint angle must stay between 0 and 90 degrees. Any request outside this range is denied."
Safe state: "If the safety button is not pressed, all motion is denied."
Rate limit: "No more than 10 position changes per second. Requests exceeding this frequency are denied or queued."
The policy is static. It doesn't change at runtime based on sensor readings or learned behavior. This is intentional. A static policy is auditable, verifiable, and cannot be exploited by indirect attacks on the decision logic.
Implementation Choices
Hardware FPGA gate (highest assurance):
- Policy compiled into Verilog
- Bitstream verified and burned to FPGA
- Runs independently, no operating system
- Request path: Application → FPGA gate → Motor driver
- Latency: microseconds
- Auditability: Verilog can be inspected by third parties
Hardened microcontroller (good balance):
- Policy runs on a separate ARM M4 or similar
- Code is verified, signed, and write-protected
- Talks to main CPU via a narrow UART or CAN interface
- Latency: milliseconds
- Auditability: Code can be reviewed, but execution is less transparent than FPGA
Software (lowest assurance) (for non-safety applications):
- Governor runs as a separate thread or process
- Uses enforced isolation (containers, memory protection)
- Useful for development and simulation, not production
- Does not guarantee safety if the OS is compromised
Most production systems use a hardware-backed governor. The cost is modest (a $5 microcontroller or small FPGA), and the gain in safety is substantial.
Request and Denial Patterns
The interface between application and governor is minimal:
``` Application -> Governor: "Set motor to 500 PWM" Governor evaluates policy Governor -> Application: "GRANTED" or "DENIED" Governor -> Driver: (sends or blocks the signal) ```
The application learns the outcome, but it cannot change the governor's mind by sending the same request again. It must either:
- Reduce the requested value (e.g., "Set motor to 300 PWM")
- Change the state of the system (e.g., "Press the safety button to enable motion")
- Halt and report an error (recommended)
Persistent denial is a signal that something is wrong. Log it, alert the operator, and stop.
Audit and Diagnostics
A governed system creates an audit trail:
``` Timestamp | Request | Decision | Reason ----------|---------|----------|-------- 12:00:01 | motor_A=600 | DENIED | exceeds_limit_500 12:00:02 | motor_A=300 | GRANTED | within_limit 12:00:03 | motor_A=700 | DENIED | exceeds_limit_500 12:00:04 | motor_B=100 | GRANTED | within_limit 12:00:05 | motor_A=700 | DENIED | exceeds_limit_500 ```
If the application keeps requesting 700 when the limit is 500, you have data. Either:
- The application is buggy (wrong request logic)
- The limit is too conservative (policy needs adjustment)
- An adversary is trying to fuzzy the system (security issue)
This clarity is valuable for debugging, compliance, and forensics.
Design Principles
1. Deny by default. If a request doesn't match the policy, say no. Don't try to be clever and "correct" the request.
2. Static policy. The governor's rules don't adapt based on sensor readings, ML models, or learned behavior. Simplicity over cleverness.
3. Fast denial. The governor makes its decision quickly (microseconds or low milliseconds). Slow denial is a vulnerability.
4. Visible denial. The application knows when a request was denied. Silent failures hide bugs.
5. Independent verification. The governor's code/logic should be verifiable by someone other than the team that built the application.
When Governance Matters
- Collaborative robots: Work near humans; absolute limits prevent injury.
- Shared resources: Multiple controllers competing for the same actuator; governors ensure fair access.
- Mission-critical systems: Surgical, rescue, infrastructure; a single bug can be catastrophic.
- Adversarial environments: Systems deployed where the application code might be modified or attacked.
For simple, isolated applications (a single-motor hobby robot running in a controlled lab), a governed architecture might be over-engineering. But the moment you have safety constraints, shared resources, or deployment in the real world, governance is the rational choice.
---
Werner Santos is founder of Werner Harmonic Labs and an expert in governed systems architecture. He has designed and deployed governance layers across distributed systems, robotics, and AI platforms.