Skip to content

Lighthouse positioning support for the real-drone env (single drone) - #106

Draft
Florian-S7 wants to merge 2 commits into
learnsyslab:mainfrom
Florian-S7:feat/lighthouse-support
Draft

Lighthouse positioning support for the real-drone env (single drone)#106
Florian-S7 wants to merge 2 commits into
learnsyslab:mainfrom
Florian-S7:feat/lighthouse-support

Conversation

@Florian-S7

Copy link
Copy Markdown

Summary

Adds an opt-in lighthouse mode to the real-drone environment so it can localize the drone
from its onboard Lighthouse state estimate instead of a motion capture system. This lets the
deployment stack run without Vicon/ROS-based tracking.

The data flow is flipped relative to mocap: instead of pushing external poses to the drone, we
read the onboard estimate back from it.

Context: we're adapting the course for a 48 h hackathon that has no mocap, only Lighthouse. This
is Phase 1 and opened as a draft — we'd really value your review, and we still need to
validate it on hardware (see below). Thanks for offering to help!

What changed (mocap path unchanged, lighthouse is opt-in & default off)

  • lsy_drone_racing/utils/lighthouse.py (new): pure, hardware-free helpers — the two log
    variable groups and decode_state(...) that turns onboard log samples into the sim observation
    (float32 pos, quat xyzw, vel, ang_vel). Pure so it's unit-testable without cflib2.
  • lsy_drone_racing/utils/crazyflie.py: lighthouse flag; verifies deck.bcLighthouse4;
    send_external_pose() becomes a no-op; estimator reset no longer seeds an external pose;
    ROS command mirroring is skipped; a background reader streams two log blocks into a snapshot
    exposed via a new get_obs().
  • lsy_drone_racing/envs/real_race_env.py: lighthouse flag; sources pos/quat/vel/ang_vel
    from drone.get_obs(); brings the drone up and checks the start pose before arming; requires
    real_track_objects=false (no tracker can measure the gates/obstacles); single-drone only.
  • scripts/deploy.py + config/level2.toml: [deploy].lighthouse flag (default false).

Design notes / decisions

  • Two log blocks. A single CRTP log block can't hold all 12 values, so we split into
    pos+vel (24 B) and orientation+gyro (24 B).
  • Background reader. deploy.py reads obs() multiple times per control loop, so a persistent
    background drainer keeps a fresh snapshot (mirroring how the mocap ROSConnector behaves) rather
    than creating a log block per call. In lighthouse mode the event loop runs on a dedicated thread;
    the mocap path keeps using run_until_complete unchanged.
  • Single-drone scope. Each process can only read its own drone's onboard estimate (no shared
    tracker), so multi-drone + lighthouse raises NotImplementedError.
  • The Lighthouse log read mirrors swarmGPT's _read_lighthouse_observation, extended with
    velocity and angular velocity.

Needs hardware verification (we can't test these without the drone yet)

  • Frames/units of vel/ang_vel vs. the sim observation — gyro.* is body-frame deg/s
    (converted to rad/s), stateEstimate.v* is world-frame m/s. This is the main risk; we'll
    bench-test by hand before flying.
  • The cflib2 log start() argument / resulting rate (we mirrored swarmGPT's usage).
  • End-to-end: estimator convergence, hover, gate passing.

Testing done

  • ruff check + ruff format --check: clean.
  • Unit tests for decode_state (values, float32, xyzw quat, deg→rad) and CRTP block sizing.
  • py_compile on all changed files. (Hardware/integration tests pending — see above.)

🤖 Generated with Claude Code

Florian-S7 and others added 2 commits June 23, 2026 01:27
Adds an opt-in lighthouse mode so the real environment can localize the drone from its onboard Lighthouse state estimate instead of a motion capture system. Instead of pushing external poses to the drone, the onboard estimate is read back via two cflib2 log blocks (pos+vel, orientation+gyro; split to respect the CRTP log packet size) by a background reader, decoded into the simulation observation (float32 pos, quat xyzw, vel, ang_vel) by the pure, unit-tested utils.lighthouse.decode_state.

The mocap path is unchanged and remains the default; lighthouse is enabled via a [deploy].lighthouse config flag plumbed through deploy.py. In lighthouse mode the deck is verified (deck.bcLighthouse4), no ROS connection is created, external poses are not pushed, the estimator converges on its own, and real_track_objects must be false (no tracker to measure the gates/obstacles). Lighthouse is single-drone only (each process can only read its own drone). Adds unit tests for decode_state and the CRTP block sizing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
scripts/lighthouse_bench.py connects a single drone in lighthouse mode and prints the onboard pos/rpy/vel/ang_vel from get_obs() so the frames/units and base-station calibration can be validated by hand. Never arms the drone and sends no setpoints.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ratheron ratheron self-assigned this Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants