Using Valve Index Base Station for Indoor Positioning

Hi everyone,

We are a team at LuminousBees working on indoor drone choreography. Our entire fleet relies on ArduPilot, ranging from 5" outdoor RTK quads down to our sub-100-gram Mini Bee designed for safe, close-proximity indoor flights.

We are currently working on bringing SteamVR Lighthouse v2 tracking to ArduPilot to achieve millimeter indoor precision for large swarms. Our goal with this thread is not just to present a project, but to involve the ArduPilot dev community. We want to discuss the best approaches, hypotheses, and architectural decisions to ensure this is implemented into the ArduPilot core the right way.

The Challenge

Finding a low-cost, reliable solution for indoor positioning is notoriously difficult. Approaches like VIO and LIO require expensive embedded sensors and heavy compute on each drone, making swarms financially unfeasible. Motion Capture (MoCap) solves the per-drone cost issue, but the initial facility cost keeps it confined to well-funded labs.

We need a system where the infrastructure is a low, one-time cost, and the per-drone cost remains negligible.

The Hardware Approach: SteamVR Lighthouse V2

Coming from the VR world, the Lighthouse V2 tracking system inverts the perception problem: base stations sweep the room with infrared laser planes, and each drone only needs a cheap array of photodiode sensors to detect them. The intelligence lives in the geometry, not in the onboard hardware.

Each base station uses a single fast-spinning rotor that produces two angled “V”-shaped sweeps per rotation. Our receiver board uses the TS4231 light-to-digital converter paired with compatible photodiodes. Because Lighthouse v2 modulates its laser with a unique identifying code (no optical sync flash required), the receiver can recognize which base station it is seeing and recover timing from the sweeps alone.

By measuring the interval between the two sweep crossings, the system computes the azimuth and elevation of the sensor relative to the base station. With four sensors rigidly mounted on the drone and known base station poses, the full 6-DoF pose (position and orientation) becomes observable.

Prior Art

This approach is well-validated. Bitcraze uses this actively with their Crazyflie “Lighthouse positioning deck,” computing full pose entirely onboard with 2–4 cm Euclidean errors compared to MoCap. Independent robotics literature has also validated this down to RMS errors of ~7-11 mm using a self-calibration algorithm.

Adding a drone to this system means adding only a small sensor PCB and a microcontroller (tens of dollars), while the base stations are a one-time cost in the low hundreds.

How to best implement this in ArduPilot?

This is where we are looking for community guidance. To make this a robust, native integration, we have a few key architectural questions:

1. Visual Odometry Inspired Solution: The first idea that comes to mind when implementing this new position estimator is sending the calculated position to ArduPilot using VISION_POSITION_ESTIMATE. This MAVLink message is chosen instead of the preferred ODOMETRY because the Lighthouse localization doesn’t give us speed information. However, for the first implementation we expected to send blank rotation information and relying on the compass for Yaw estimate. Is this a problem? Should we use another MAVLink message?

2. Kalman Measurement Model VS Crossing Beams: On the Bitcrazy publication they evaluate a Kalman measurement model (lighthouse + IMU) based method for processing lighthouse information versus a purely algebraic method. Both work great in the experiments. Their final implementation is the EKF one. Since we hope to make the lighthouse positioning open and useful for as many people as we can, we want to hear what is the best implementation for the ArduPilot firmware. Should we send algebraic position information to the EK3 via ExternalNav or process the lighthouse information close to the AP firmware, merging it with IMU data at the core? Who in the community can help us understand the best development path to take?

Please provide us with your insights. Our aim is making this as community friendly as it can be!!

Also, we’lll come here with more questions and updates on the development!!

9 Likes

Hi @odraudE31,

Using the VISION_POSITION_ESTIMATE message sounds OK to me. The one advantage of the ODOMETRY message is that it provides a quality which can be used to reject bad positions but as you say, it also expects a velocity to be provided - maybe sending zero is OK but I’m not sure. I suspect something similar can be done using the VISION_POSITION_ESTIMATE message’s covariance[0] value though (e.g set very high to cause the EKF to ignore the position estimate).

Another option is to write a new AP_Beacon driver. The advantage of this method is that the individual distances will be fused into the EKF. This is what AP uses for the Mavelmind, Nooploop and Pozyx indoor systems. The downside is that you’ll need to somehow pass the location of the beacon to AP.

By the way, other non-GPS experts on the team include @rishabsingh3003 and @snktshrma.

2 Likes

Randy, it’s so good to have your support on this development!!! I have performed a simple test sending VISION_POSITION_ESTIMATE to my FC and it accepted and inputted that into the EKF. I tested it with synthetic data, but the guys at the lab are testing on real hardware.

I’m hoping to use some nice math so I can obtain meaningful covariance data to send via VISION_POSITION_ESTIMATE message. I would be glad to also have the input from @rishabsingh3003 and @snktshrma or another expert on non-GPS to understand if this will be enough or it is better to use ODOMETRY.

Randy, I also have a question, the advantage of using the AP_Beacon would be to have actual distances from the drone and the signal emitters correct? I tried understanding the functionality but I couldn’t get so far.

Hi @odraudE31 . Following up on @rmackay9’s suggestions:

Use ODOMETRY if you need quality gating or VISION_POSITION_ESTIMATE, if need discrete pose-jump reset counters (rare in steady beacon/mocap tracks). With EK3_SRC* settings you can keep external vel and yaw out of the EKF, if they are not reliable/algorithm doesn’t calculate those. So either works for extnav pose, with those caveats, as Randy suggested.

For the solver itself, offboard algebraic method on the companion makes sense.. pose gets sent in and fused with IMU inside EKF3 via extnav. You could push the solver onto the FC as an internal library, but sweep timing and processing headroom might be a problem.
For the algebraic method, what I’ve seen to calculate covariance is calibration RMS from ground-truth tests(if possible) for baseline noise, plus a GDOP style multiplier to inflate covariance when geometry is weak.

Bitcraze style LH+IMU EKF offboard is also viable ig and gives you filter covariance you can map directly into the mavlink pose covariance.. For onboard bitcraze style ekf implementation would require a new sweep-angle measurement model in EKF3, which might be a bigger lift.

Re AP_Beacon, not an expert, but what Randy meant to suggest is that path fuses uwb like ranges from the vehicle to fixed anchors into the EKF. Lighthouse gives sweep angles/timing, not direct range. AP_Beacon would apply if the setup exposes real distance to each anchor measurements.

3 Likes

Hello @snktshrma, those are some amazing insights, thank you so much!!

I’m already in the process of changing the message to ODOMETRY. I did not know that these were the special use cases for each message, that’s good to know!

This covariance calculation is truly genius, we don’t have access to a MoCap system, but there were papers that published those precision statistics and I believe that can be used as baseline and then possibly use a DOP multiplier based on how many sensors are reading lighthouse data at the best rate? Since we have 4 sensors that might be a feasible idea.

One question that I have is if it would be valuable use IMU data to calculate the EKF like Bitcrazy? I ask that because I also work with ZED stereo cameras in another project and they do have that built in and as you know their result is phenomenal.

Our ultimate goal would be to input the sensor data directly into the FC. We do know it would be some tough work, but our aim is making this a cheep indoor positioning solution for swarms! Before achieving that our aim is to make everything work smoothly with “companion MCU” processing (it’s not a computer since we are using a Raspberry Pico!!).

Sweeps produce planes, they should be even easier to feed into EKF than ranges.

2 Likes

@odraudE31 If algebraic gives good pose estimates with reasonable covariance, feeding that into AP can be a good first step to test.. EKF3 will fuse it with the FC’s IMU. But without filtering, it can be steppy and noisier between fixes

So my take on this is that LH sweeping plane + IMU EKF on the companion will eventually be more robust and reliable plug and play solution (ideally with an external IMU on the deck) to any autopilot.
Later, updating the AP’s EKF3 to be able to fuse module’s data onboard, for a tight coupling with AP, will be a good idea and it would drop the companion IMU.

1 Like

@snktshrma I’m sorry for the delay, I was having a problem in the acceptance of the ODOMETRY message in the EKF. I finally solved it setting home when the EKF is healthy. Lua scripting didn’t work so I implemented that into the Raspberry Pico and it works now!!

Also, our final aim is to create a new EKF state that uses the sensor information and merges that with the IMU directly on ArduPilot firmware.

Developmet Update:

Our lab tests are going well and we have a reasonable positioning. We have a small journey until our maiden flight, but it will happen soon enough. Stuff we need to get done before that is:

  • Implement and validate covariance calculation;
  • Obtain time offset between IMU and the Lighthouse positioning;
  • Validate our positioning calibration pipeline;
  • Validate overall positioning and check for divergences (we don’t want to crash any drones);
  • We are also implementing a friendly UI, so the community can eventually easily enjoy this indoor positioning solution.
1 Like