This documentation was generated with the assistance of AI. Please report any inaccuracies.
The com.irurueta.navigation.indoor.radiosource package solves the inverse problem of
position estimation: given RSSI and/or ranging readings taken at multiple known
locations, estimate an unknown radio source’s own position, transmitted power, and path-loss exponent.
Overview
RSSI-based position estimation assumes the access point’s position and
transmitted power are known, and solves for the device’s unknown position. Radio source estimation runs the
same physics in reverse: now it’s the receivers' positions that are known — several of them, placed around the
area — and it’s the source’s position (plus its transmitted power, and optionally its
path-loss exponent) that’s unknown.
Since the source radiates its signal equally in all directions, and that signal weakens with distance in the same
predictable way, a receiver that reports a strong signal must be relatively close to the source, and one that
reports a weak signal must be relatively far. Combining several such readings — each pulling the estimate toward
or away from a receiver depending on how strong the signal was there — is enough to solve for where the source
must be for all of them to make sense at once, along with how powerful it must be transmitting to produce exactly
those readings.
classDiagram
class RadioSourceEstimator~P~ {
<<abstract>>
}
class RssiRadioSourceEstimator~P~ {
<<abstract>>
+positionEstimationEnabled
+transmittedPowerEstimationEnabled
+pathLossEstimationEnabled
}
class RangingRadioSourceEstimator~P~ {
<<abstract>>
}
class RangingAndRssiRadioSourceEstimator~P~ {
<<abstract>>
}
class MixedRadioSourceEstimator~P~ {
<<abstract>>
}
note for RangingRadioSourceEstimator "position only, pure lateration"
note for RangingAndRssiRadioSourceEstimator "ranging -> position, rssi -> power/path-loss"
note for MixedRadioSourceEstimator "heterogeneous, falls back to RSSI position"
RadioSourceEstimator <|-- RssiRadioSourceEstimator
RadioSourceEstimator <|-- RangingRadioSourceEstimator
RadioSourceEstimator <|-- RangingAndRssiRadioSourceEstimator
RadioSourceEstimator <|-- MixedRadioSourceEstimator
class RobustRadioSourceEstimator~P~ {
<<abstract>>
}
class RobustRssiRadioSourceEstimator~P~ {
<<abstract>>
}
class RobustRangingRadioSourceEstimator~P~ {
<<abstract>>
}
class RobustRangingAndRssiRadioSourceEstimator~P~ {
<<abstract>>
}
RobustRadioSourceEstimator <|-- RobustRssiRadioSourceEstimator
RobustRadioSourceEstimator <|-- RobustRangingRadioSourceEstimator
RobustRadioSourceEstimator <|-- RobustRangingAndRssiRadioSourceEstimator
RobustRssiRadioSourceEstimator <|-- RANSACRobustRssiRadioSourceEstimator2D
RobustRssiRadioSourceEstimator <|-- LMedSRobustRssiRadioSourceEstimator2D
RobustRssiRadioSourceEstimator <|-- MSACRobustRssiRadioSourceEstimator2D
RobustRssiRadioSourceEstimator <|-- PROSACRobustRssiRadioSourceEstimator2D
RobustRssiRadioSourceEstimator <|-- PROMedSRobustRssiRadioSourceEstimator2D
class SequentialRobustRangingAndRssiRadioSourceEstimator~P~
class SequentialRobustMixedRadioSourceEstimator~P~
note for SequentialRobustRangingAndRssiRadioSourceEstimator "stage 1: robust ranging -> position<br/>stage 2: robust rssi -> power/path-loss"
note for SequentialRobustMixedRadioSourceEstimator "same, tolerant of scarce reading types"
Every non-robust and robust class has 2D and 3D forms; robust classes have RANSAC/LMedS/MSAC/PROSAC/PROMedS
concrete variants (5 per measurement type per dimension). There is no non-sequential robust Mixed estimator
— robustly estimating from a heterogeneous, unpaired reading set is only available through
SequentialRobustMixedRadioSourceEstimator. The Sequential* classes stand outside the RobustRadioSourceEstimator
hierarchy; they compose two other robust estimators internally (see
Sequential two-stage estimation).
RSSI-based estimation
RssiRadioSourceEstimator fits the log-distance path-loss model directly via Levenberg-Marquardt — there is no
closed-form solution here, unlike position estimation, because the source position, its equivalent transmitted
power (antenna gains folded in, since they’re unknown for third-party sources), and the
path-loss exponent are all potentially unknown at once:
Three independent flags control what’s actually solved for: positionEstimationEnabled (default true),
transmittedPowerEstimationEnabled (default true), pathLossEstimationEnabled (default false —
is fixed at 2.0 unless explicitly enabled). The class documentation warns that enabling all three at once
"usually achieves inaccurate results" — at most two of the three should be estimated simultaneously, with an
initial value supplied for the third. Seven separate fitter/Jacobian setups exist internally, one per
enabled/fixed combination.
Defaults for initial values: initialTransmittedPowerdBm falls back to the average RSSI across all readings if
unset; initialPosition falls back to the centroid of all reading positions. The minimum number of readings is
— one more than the number of unknowns.
Ranging-based estimation
RangingRadioSourceEstimator is simpler: since ranging gives distance directly, there’s no path-loss model to
invert, and only position is ever estimated (no power, no path-loss exponent) — this is the same trilateration
problem as ranging position estimation, just with the roles of "known" and "unknown"
swapped. It runs a linear lateration solve first (homogeneous or inhomogeneous, useHomogeneousLinearSolver
default true) and then, by default (nonLinearSolverEnabled = true), refines the result with the same
Levenberg-Marquardt lateration solver used elsewhere in this library. The minimum reading count is
— the classic trilateration minimum.
Combining ranging and RSSI
RangingAndRssi (paired readings)
RangingAndRssiRadioSourceEstimator requires every reading to carry both a ranging distance and an RSSI value for
the same source. Rather than a single joint model, it orchestrates two inner estimators:
flowchart LR
A[Paired reading] --> B[Split into ranging half<br/>and RSSI half]
B --> C[Inner RangingRadioSourceEstimator<br/>estimates position]
C --> D{Power or path-loss<br/>estimation enabled?}
D -->|yes| E["Inner RssiRadioSourceEstimator<br/>(position fixed to C's result)<br/>estimates Pte / n"]
D -->|no| F[Done: position only]
E --> G[Combine covariances block-diagonally]
C --> G
Position always comes from the ranging half — the library’s own documentation states implementations "should be
preferred [over RSSI-only estimation] as they can provide greater accuracy." RSSI data is only ever used to solve
for /, never to re-estimate position. The two inner estimators' covariance matrices
are combined block-diagonally, assuming zero cross-correlation between position and power/path-loss terms.
Mixed (heterogeneous readings)
MixedRadioSourceEstimator accepts an unpaired mixture of ranging-only, RSSI-only, and paired readings for the
same source, using the same two-inner-estimator machinery as RangingAndRssi — with one added fallback: if there
aren’t enough ranging-capable readings (fewer than ), it estimates position directly from
RSSI data instead (enabling position estimation in the inner RSSI estimator), degrading gracefully to a pure RSSI
joint fit — "in a less reliable way," per the source comments — rather than failing outright.
Robust estimation
All three measurement types share the same RANSAC-family scoring machinery, implemented once in
RobustRadioSourceEstimator and its concrete subclasses. The residual differs only by measurement type:
flowchart TD
A[All readings] --> B["Draw subset of size preliminarySubsetSize<br/>(random, or quality-guided for PROSAC/PROMedS)"]
B --> C[Solve candidate with the matching<br/>non-robust inner estimator]
C --> D[Score every reading against<br/>the candidate's residual]
D --> E{RANSAC / MSAC / LMedS / PROSAC / PROMedS}
E --> F{More iterations<br/>or converged?}
F -->|yes| B
F -->|no| G[Best candidate + inlier set]
G --> H[Refine: re-run inner estimator<br/>over inliers only]
H --> I[Final position + Pte + n + covariance]
Variant
Scoring
Threshold (default)
Quality scores
RANSAC
Maximizes inlier count (hard threshold)
threshold = 0.1 (dB for RSSI, meters for ranging)
no
MSAC
Truncated/bounded residual cost, same hard threshold
threshold = 0.1
no
LMedS
Minimizes the median of squared residuals
stopThreshold = 1e-4 (early-stop only)
no
PROSAC
Same as RANSAC, but samples highest-quality readings first
threshold = 0.1
required
PROMedS (default)
LMedS’s median scoring + PROSAC’s quality-guided sampling
stopThreshold = 1e-4
required
If refineResult (default true), the winning candidate is always re-solved with the non-robust inner estimator
restricted to its inlier subset, and keepCovariance (default true) retains the resulting covariance. The
library-wide default robust method is PROMedS, not RANSAC.
=== Sequential two-stage estimation
SequentialRobustRangingAndRssiRadioSourceEstimator and SequentialRobustMixedRadioSourceEstimator stand outside
the RobustRadioSourceEstimator hierarchy and instead run two independently configured robust estimators in
sequence — mirroring the two-stage approach used by
the position-side Sequential estimators, but here
both stages target the same radio source’s unknowns rather than a device position:
Stage 1 (position via ranging): a RobustRangingRadioSourceEstimator (own rangingRobustMethod, default
PROMedS; own confidence, threshold, max iterations) robustly estimates position from ranging-capable readings.
Stage 2 (power/path-loss via RSSI): a RobustRssiRadioSourceEstimator (own rssiRobustMethod, default
PROMedS) robustly estimates / using stage 1’s position as a fixed initial
position — position is only re-estimated here if stage 1 was skipped for lack of ranging data (same
rssiPositionEnabled fallback as the non-robust Mixed estimator).
The class documentation notes this two-stage approach "might produce more stable positions… than
[the joint, single-pass] RobustRangingAndRssiRadioSourceEstimator," since ranging-only lateration is a
better-conditioned problem to robustify on its own before it anchors the RSSI fit. Quality scores supplied to the
sequential estimator are split and forwarded to whichever inner stage uses PROSAC/PROMedS.
Usage parameters
readings (located, at known positions), listener — common to all estimators.
Static create(…) factories exist on the 2D/3D robust classes for each measurement type, building any variant
from a RobustEstimatorMethod enum (default PROMedS).
API reference
Main classes used on this page, linked to their source code and Javadoc:
Fingerprint-based position estimators — positioning without known source locations at all; its joint
position-and-radio-source estimator also refines source positions, using a related first-order log-distance
model.