Supervisor subsystem - #16
Merged
Merged
Conversation
The previous commits moved these commands to the supervisor subsystem and kept deprecated copies under platform and localization.emergency with runtime warnings. There is no released version of this library yet, so nobody depends on the old locations - remove them instead of carrying deprecation shims from the first release onward.
The example is correct, but it is a fairly involved flight scenario - arming, takeoff, in-flight state monitoring, landing - which makes it more of a demo than a focused API example. reading_supervisor.py already shows the supervisor API without flying; move this one to the demos repo instead.
Fix the crash recovery description: it claimed recovery depends on the crash type, but the firmware only has a single crashed state. Use the crazyflie-lib wording instead. Also use "The Crazyflie" consistently instead of mixing it with "the system", and drop the cache duration from read_bitfield's docstring — it hardcoded a crazyflie-lib internal constant that can change without this binding noticing. Regenerate the type stubs accordingly.
Each state query method independently awaited a bitfield read, so two consecutive checks could decode different radio reads and report mutually inconsistent flags - exactly what supervisor-based safety logic must not do. Replace them with a single read() returning a SupervisorState snapshot: all flags on one snapshot decode the same bitfield, so they are consistent by construction, and compound checks need one await instead of several. This also mirrors the crazyflie-lib design, where read_bitfield() returns a SupervisorInfo value that is queried synchronously. The raw bitfield is available as SupervisorState.raw.
There was a problem hiding this comment.
Pull request overview
This PR introduces a dedicated Supervisor subsystem to expose Crazyflie safety/state functionality (arming, crash recovery, emergency stop, and supervisor state snapshot) via the Rust PyO3 bindings, and migrates the previously scattered APIs (Platform arming + Localization emergency control) to the new subsystem.
Changes:
- Added
Supervisor+SupervisorStateRust/Python API, including a cached bitfield snapshot read and safety control commands. - Removed deprecated/misplaced APIs: arming + crash recovery from
Platform, and emergency stop fromLocalization. - Updated examples and Python type exports/stubs to use
cf.supervisor().
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| rust/src/subsystems/supervisor.rs | New Supervisor subsystem wrapper + SupervisorState snapshot exposed to Python. |
| rust/src/subsystems/platform.rs | Removes arming/crash-recovery methods from Platform wrapper. |
| rust/src/subsystems/mod.rs | Registers and re-exports the new supervisor module; removes EmergencyControl re-export. |
| rust/src/subsystems/localization.rs | Removes emergency control interface from Localization subsystem. |
| rust/src/lib.rs | Exposes Supervisor and SupervisorState to the Python module. |
| rust/src/crazyflie.rs | Adds Crazyflie.supervisor() accessor returning the Supervisor subsystem. |
| examples/trajectory.py | Updates arming call site to use cf.supervisor(). |
| examples/reading_supervisor.py | New example demonstrating supervisor state polling via Supervisor.read(). |
| examples/emergency_watchdog.py | Migrates watchdog and arming usage to Supervisor subsystem. |
| examples/emergency_stop.py | Migrates emergency stop and arming usage to Supervisor subsystem. |
| examples/arming.py | Migrates arming/disarming example to Supervisor subsystem. |
| cflib2/supervisor.py | New Python module exporting Supervisor types from the Rust extension. |
| cflib2/localization.py | Removes EmergencyControl from Python-level localization exports. |
| cflib2/_rust.pyi | Updates generated stubs: adds Supervisor API, removes EmergencyControl and removed Platform methods. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a dedicated
Supervisorsubsystem, reachable viacf.supervisor(), and consolidates all supervisor-related commands there. Previously these were scattered acrossPlatform(arming, crash recovery) andLocalization(emergency stop), which didn't match the firmware's supervisor concept or the structure of the underlyingcrazyflie-lib-rs.The new subsystem also exposes the supervisor state:
Supervisor.read()returns aSupervisorStatesnapshot decoded from a single bitfield read, so all flags (is_armed,can_fly,is_tumbled, …) are from the same moment and mutually consistent. Reads are cached briefly by the underlying lib to avoid flooding the link. A newexamples/reading_supervisor.pydemonstrates polling the state.Breaking changes
The old locations are removed without a deprecation path:
cf.platform().send_arming_request(do_arm)cf.supervisor().send_arming_request(do_arm)cf.platform().send_crash_recovery_request()cf.supervisor().send_crash_recovery_request()cf.localization().emergency().send_emergency_stop()cf.supervisor().send_emergency_stop()cf.localization().emergency().send_emergency_stop_watchdog()cf.supervisor().send_emergency_stop_watchdog()The
EmergencyControlclass is removed entirely. All examples have been migrated.