Skip to content
This repository was archived by the owner on Jun 28, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 359 additions & 0 deletions docs/docs/components/mobile/LOCALIZATION_CALIBRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
# Beacon-Based Localization Calibration Guide

This guide provides step-by-step instructions for calibrating the RSSI-based indoor positioning system in your specific environment.

## Overview

The localization algorithm uses two key parameters that affect accuracy:
1. **TxPower**: Reference transmitted power at 1 meter (default: -59 dBm)
2. **Path Loss Exponent (n)**: Environment-specific signal propagation factor (default: 2.0)

For best results, these should be calibrated for your specific building and environment.

## Quick Start: TxPower Calibration

TxPower calibration is the easiest and fastest way to improve accuracy.

### Step 1: Prepare Equipment
- Navign mobile app (with localization enabled)
- Tape measure or laser rangefinder (accuracy to 0.5m)
- At least 3 calibration points per beacon
- Notebook to record measurements

### Step 2: Select Calibration Beacons

Choose 2-3 beacons in different areas of your facility:
- One in an open area (hallway/corridor)
- One in a constrained area (office, stairwell)
- One with potential obstacles (near metal, water)

### Step 3: Record RSSI at Known Distances

For each beacon:

1. **Close distance (1-2 meters)**
- Stand 1 meter from beacon
- Record app RSSI reading (average of 5 readings)
- Stand 2 meters from beacon
- Record RSSI reading

2. **Medium distance (5-10 meters)**
- Stand 5 meters from beacon
- Record RSSI reading
- Stand 10 meters from beacon (if space allows)
- Record RSSI reading

3. **Far distance (20-30 meters)**
- Stand 20 meters from beacon
- Record RSSI reading
- Stand 30 meters if possible

Example table:
```
Beacon A (Hallway):
Distance (m) | RSSI (dBm) | Notes
1.0 | -58 | Clear line of sight
2.0 | -62 | Clear line of sight
5.0 | -72 | Clear line of sight
10.0 | -82 | Clear line of sight
20.0 | -92 | Clear line of sight
```

### Step 4: Calculate Reference TxPower

For each distance measurement:

```
TxPower = RSSI + 20 * n * log10(distance)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formula for calculating TxPower is incorrect. The documentation states:

TxPower = RSSI + 20 * n * log10(distance)

However, this is inconsistent with the path loss model used in the code. The correct formula should be:

TxPower = RSSI + 10 * n * log10(distance)

This can be verified by rearranging the distance formula in rssi_to_distance():

  • distance = 10^((TxPower - RSSI) / (10 * n))
  • log10(distance) = (TxPower - RSSI) / (10 * n)
  • 10 * n * log10(distance) = TxPower - RSSI
  • TxPower = RSSI + 10 * n * log10(distance)

The factor should be 10n, not 20n. Using 20*n will result in incorrect calibration values.

Copilot uses AI. Check for mistakes.

Where:
- RSSI = measured signal strength (negative, e.g., -58)
- n = 2.0 (use default for now)
- distance = meters from beacon
- log10 = logarithm base 10
```

**Example calculation:**
```
At 1 meter with RSSI -58:
TxPower = -58 + 20 * 2.0 * log10(1)
TxPower = -58 + 20 * 2.0 * 0
TxPower = -58 dBm

At 10 meters with RSSI -82:
TxPower = -82 + 20 * 2.0 * log10(10)
TxPower = -82 + 20 * 2.0 * 1.0
TxPower = -82 + 40
TxPower = -42 dBm (this seems off - indicates environment effect)
```
Comment on lines +83 to +88

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example calculations are based on the incorrect formula from line 67. With the corrected formula TxPower = RSSI + 10 * n * log10(distance), the calculations should be:

At 10 meters with RSSI -82:

  • TxPower = -82 + 10 * 2.0 * log10(10)
  • TxPower = -82 + 10 * 2.0 * 1.0
  • TxPower = -82 + 20
  • TxPower = -62 dBm

This is much closer to the expected -59 dBm and doesn't "seem off" as the incorrect calculation suggests. The note about "indicates environment effect" is misleading since the error is in the formula, not the environment.

Copilot uses AI. Check for mistakes.

### Step 5: Update TxPower Value

If your calculated TxPower differs significantly from -59 dBm:

1. Open `mobile/src-tauri/src/locate/locator.rs`
2. Find the `rssi_to_distance()` function
3. Update the TxPower value:

```rust
fn rssi_to_distance(mut rssi: f64) -> f64 {
let tx_power = -59.0; // ← Change this value
// ... rest of function
}
```

For example, if your calculations average to -55 dBm:
```rust
let tx_power = -55.0; // Adjusted for your environment
```

4. Rebuild the mobile app:
```bash
cd mobile
pnpm run tauri build
```

### Step 6: Validate Improvements

Repeat your measurements with the updated TxPower:
- Positions should now be more accurate
- Distance estimates should match your measurements better
- Document the improvement for your records

## Advanced: Path Loss Exponent Calibration

If TxPower calibration alone doesn't achieve desired accuracy, calibrate the path loss exponent `n`.

### Theory

The path loss exponent depends on environment:

| Environment | n Value | Notes |
|-------------|---------|-------|
| Free space (outdoor) | 2.0 | Ideal, rarely occurs indoors |
| Open hallway | 2.0-2.3 | Clean line of sight, few obstacles |
| Typical office | 2.5-3.0 | Some walls, furniture |
| Dense environment | 3.0-3.5 | Many obstacles, people |
| Metal/water heavy | 3.5-4.5+ | Severe signal degradation |

### Measurement Procedure

1. **Collect distance-RSSI pairs** (minimum 8-10 pairs across different distances)

Example data:
```
Distance (m) | RSSI (dBm)
1.0 | -59
2.0 | -65
5.0 | -73
10.0 | -83
15.0 | -89
20.0 | -95
```

2. **Use regression analysis** to find optimal `n`:

The path loss formula rearranges to:
```
RSSI = TxPower - 20*n*log10(distance)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path loss formula is incorrect. The documentation states:

RSSI = TxPower - 20*n*log10(distance)

However, the correct formula based on the code implementation is:

RSSI = TxPower - 10*n*log10(distance)

The coefficient should be 10n, not 20n. This is the standard free-space path loss model formula. The factor of 20 would be used in power measurements (not signal strength in dBm), and only when n=1. Using 20*n will produce incorrect regression analysis results.

Copilot uses AI. Check for mistakes.
```

Which is linear: `RSSI = a - b*log10(distance)` where `b = 20*n`

Using linear regression (or spreadsheet):
- Plot distance vs RSSI
- Fit a line
- Calculate: `n = b / 20` where `b` is the slope magnitude
Comment on lines +161 to +166

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relationship between slope and path loss exponent is incorrect. The documentation states b = 20*n, but based on the correct formula RSSI = TxPower - 10*n*log10(distance), it should be:

b = 10*n

Therefore, the regression calculation should be:

  • n = b / 10 (not n = slope / 20)

This error propagates through the regression analysis section and will cause users to calculate incorrect path loss exponent values during calibration.

Copilot uses AI. Check for mistakes.

### Using a Spreadsheet

In Excel/Google Sheets:

1. Create columns:
- A: Distance (meters)
- B: RSSI (dBm)
- C: log10(Distance) = LOG10(A1)

2. Use LINEST or SLOPE function:
```
slope = SLOPE(B:B, C:C)
n = slope / 20
```

3. Example with sample data:
- slope = -40.3
- n = 40.3 / 20 = 2.015 ≈ 2.0

Comment on lines +177 to +186

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spreadsheet calculation for path loss exponent is incorrect due to the wrong formula. With the corrected formula where b = 10*n, the calculation should be:

slope = SLOPE(B:B, C:C)
n = slope / 10

And the example would be:

  • slope = -40.3
  • n = 40.3 / 10 = 4.03

Note that this would give n ≈ 4.0 (not 2.0), which would indicate a highly obstructed environment, not free space. The current example with slope / 20 incorrectly suggests the environment is free space.

Copilot uses AI. Check for mistakes.
If your n value differs from 2.0:

```rust
fn rssi_to_distance(mut rssi: f64) -> f64 {
let tx_power = -59.0;
if rssi > 0f64 {
rssi = -rssi;
}
let n = 2.0; // ← Update this value, e.g., 2.5, 3.0, etc.
10f64.powf((tx_power - rssi) / (10.0 * n))
}
```

## Performance Validation

After calibration, measure accuracy in real-world conditions:

### Test Method 1: Fixed Position Accuracy

1. Stand at 10 known locations across your facility
2. Let the app localize for 10 seconds each (averaging multiple readings)
3. Record calculated position and actual position
4. Calculate error distance: `√((x_calc - x_actual)² + (y_calc - y_actual)²)`

**Target metrics:**
- Open space: ±1.5m (90% of measurements)
- Typical office: ±2.5m (90% of measurements)
- Dense areas: ±4m (90% of measurements)

### Test Method 2: Tracking Accuracy

1. Walk a known path (straight line, grid pattern)
2. Record GPS-like position trace from app
3. Compare against actual path
4. Calculate deviation from expected route

**Target metric:** Path deviation < 2m from actual route in typical areas

## Troubleshooting

### Problem: Positions are consistently too far from beacon

**Cause:** TxPower value is too high (too positive)

**Solution:**
- Decrease TxPower value (e.g., -59 → -62)
- This makes the algorithm think signals are weaker than they are
- Results in smaller distance estimates
Comment on lines +229 to +234

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The troubleshooting explanation contains contradictory language. The documentation states:

"Cause: TxPower value is too high (too positive)
Solution: Decrease TxPower value (e.g., -59 → -62)"

The cause says TxPower is "too high (too positive)" but the solution shows changing from -59 to -62, which is making TxPower MORE negative (lower in value, but more negative in sign). This is confusing.

The correct phrasing should be either:

  1. "Cause: TxPower value is too high (less negative than it should be)" - emphasizes the magnitude
  2. "Cause: TxPower value is insufficiently negative" - clearer phrasing

The current phrasing creates confusion because in dBm measurements, -59 is "higher" than -62 in terms of power level, but -59 is "less negative" numerically. The explanation should clarify this to avoid user confusion.

Suggested change
**Cause:** TxPower value is too high (too positive)
**Solution:**
- Decrease TxPower value (e.g., -59 → -62)
- This makes the algorithm think signals are weaker than they are
- Results in smaller distance estimates
**Cause:** TxPower value is too high (less negative than it should be)
**Solution:**
- Decrease TxPower value (e.g., -59 → -62)
- This makes the reference TxPower more negative (lower power in dBm)
- For the same RSSI, this results in smaller distance estimates

Copilot uses AI. Check for mistakes.

### Problem: Positions are consistently too close to beacon

**Cause:** TxPower value is too low (too negative)

**Solution:**
- Increase TxPower value (e.g., -59 → -56)
- This increases distance estimates
Comment on lines +238 to +242

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the previous troubleshooting entry, this explanation has contradictory language:

"Cause: TxPower value is too low (too negative)
Solution: Increase TxPower value (e.g., -59 → -56)"

The cause says "too low (too negative)" but in dBm terms, -59 is actually a HIGHER power level than -62, even though it's less negative numerically. The solution correctly shows -59 → -56 (making it less negative/higher power), but the phrasing "too low (too negative)" could confuse users.

Suggest rephrasing for clarity:
"Cause: TxPower value is too negative (lower power than actual)
Solution: Increase TxPower value (make it less negative, e.g., -59 → -56)"

Suggested change
**Cause:** TxPower value is too low (too negative)
**Solution:**
- Increase TxPower value (e.g., -59 → -56)
- This increases distance estimates
**Cause:** TxPower value is too negative (lower power than actual)
**Solution:**
- Increase TxPower value (make it less negative, e.g., -59 → -56)
- This makes the algorithm assume stronger signal at 1 m, increasing inferred distances so positions are less clustered near the beacon

Copilot uses AI. Check for mistakes.

### Problem: Accuracy varies greatly depending on direction

**Cause:** Environmental obstruction or multipath interference

**Solutions:**
- Add beacons to reduce reliance on any single beacon
- Check for metal structures, water features that block signals
- Increase path loss exponent `n` (e.g., 2.0 → 2.5)
- Deploy beacons in more locations to provide coverage from multiple directions

### Problem: Accuracy is poor in crowded areas

**Cause:** People absorb radio signals, reducing RSSI

**Solutions:**
- Increase path loss exponent `n` to 3.0-3.5
- This accounts for signal absorption
- Add additional beacons in high-traffic areas
- Consider time-of-day calibration (different `n` for peak vs off-peak)

### Problem: Positions jump around erratically

**Cause:** Insufficient beacons or multipath interference

**Solutions:**
- Verify at least 3 beacons are visible with RSSI > -100 dBm
- Check for reflective surfaces (mirrors, metal panels)
- Increase beacon density (space them 8-10m apart instead of 20m)
- In very noisy environments, consider hybrid approach using accelerometer/compass

## Environment-Specific Tuning

### Shopping Malls

- **Characteristics:** Open spaces, some obstacles (kiosks), metal structures
- **Recommended n:** 2.5-3.0
- **Beacon spacing:** 10-12m
- **TxPower:** Usually -59 to -56 dBm
- **Best location:** Center of corridors, at least 2m from walls

### Hospitals

- **Characteristics:** Many rooms with walls, metal equipment, high interference
- **Recommended n:** 3.0-3.5
- **Beacon spacing:** 8-10m (closer than usual)
- **TxPower:** -59 to -55 dBm
- **Challenges:** Elevator shafts block signals; place beacons outside elevators
- **Special case:** Operating rooms may need hardened shielding

### Airport Terminals

- **Characteristics:** Large open spaces, metal structures (gates, railings)
- **Recommended n:** 2.0-2.3
- **Beacon spacing:** 12-15m (can be larger due to open space)
- **TxPower:** Usually -59 to -56 dBm
- **Challenge:** Massive multipath due to metal; may need denser coverage

### Schools/Universities

- **Characteristics:** Mixed (classrooms + hallways), varying wall materials
- **Recommended n:** 2.5-3.0
- **Beacon spacing:** 8-10m
- **TxPower:** -59 to -56 dBm
- **Special case:** Stairwells often have poor coverage; place beacons on each floor landing

## Continuous Monitoring

### Metrics to Track

1. **Accuracy over time**: Re-test monthly to catch beacon failures
2. **RSSI distribution**: Verify beacons are still transmitting at expected power
3. **Coverage gaps**: Identify "dead zones" with no strong signals
4. **Beacon battery**: Monitor beacon power levels (indicates battery health)

### Automated Validation

Consider adding periodic validation runs:

```rust
#[test]
fn validate_calibration_accuracy() {
// Known positions and expected RSSI ranges
let test_cases = vec![
((0.0, 0.0), vec![(0.0, 0.0, -50.0)]), // At beacon
((5.0, 0.0), vec![(0.0, 0.0, -73.0)]), // 5m away
((0.0, 10.0), vec![(0.0, 0.0, -83.0)]), // 10m away
];

for (expected, beacons) in test_cases {
if let Some(actual) = locate_via_beacons(&beacons) {
let error = distance(expected, actual);
assert!(error < TOLERANCE);
}
}
}
```
Comment on lines +322 to +339

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test example references an undefined distance function and TOLERANCE constant. While this is documentation code (not meant to compile), it could be improved for clarity by either:

  1. Showing the implementation of these helpers:
fn distance(p1: (f64, f64), p2: (f64, f64)) -> f64 {
    ((p1.0 - p2.0).powi(2) + (p1.1 - p2.1).powi(2)).sqrt()
}
const TOLERANCE: f64 = 2.0; // meters
  1. Or using inline calculations instead of helper functions:
let error = ((expected.0 - actual.0).powi(2) + 
             (expected.1 - actual.1).powi(2)).sqrt();
assert!(error < 2.0); // within 2 meters

This would make the example more self-contained and educational.

Copilot uses AI. Check for mistakes.

## References

- Free Space Path Loss Model: [Friis Equation](https://en.wikipedia.org/wiki/Friis_transmission_equation)
- RSSI and Distance: [Bluetooth RSSI Blog](https://www.argenox.com/library/bluetooth-low-energy/rssi/)
- Multipath Fading: [IEEE Wireless Propagation Model](https://www.ieee802.org/)

Copilot AI Dec 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference link for "IEEE Wireless Propagation Model" points to the generic IEEE 802 homepage (https://www.ieee802.org/), which doesn't directly provide information about wireless propagation models.

Consider updating this to a more specific resource, such as:

  • IEEE 802.11 TGn Channel Models document
  • A specific IEEE paper on indoor propagation
  • An alternative educational resource that explains path loss models

Alternatively, if the intent is just to reference IEEE as an organization, the text should be updated to reflect that this is a general reference rather than a specific propagation model document.

Suggested change
- Multipath Fading: [IEEE Wireless Propagation Model](https://www.ieee802.org/)
- Multipath Fading: [Multipath Propagation (Wikipedia)](https://en.wikipedia.org/wiki/Multipath_propagation)

Copilot uses AI. Check for mistakes.

## Summary

| Step | Effort | Impact | Complexity |
|------|--------|--------|-----------|
| TxPower calibration | 30 min | ±30% accuracy improvement | Easy |
| Path loss exponent (n) | 1-2 hours | Additional ±20% improvement | Medium |
| Beacon repositioning | Varies | Can double accuracy | Hard |
| Hybrid sensors (compass, accel) | 2-3 days | Smooth trajectories | Hard |

**Recommended approach:**
1. Start with TxPower calibration (easiest, high impact)
2. If needed, calibrate path loss exponent
3. If still insufficient, add more beacons or hybrid sensors
Loading
Loading