pub struct LocalOrigin { /* private fields */ }Expand description
The origin of the navigation frame, and the local tangent plane about it. Equation (43).
Exact, not approximated: a geodetic position goes to Earth-centered Cartesian
coordinates, the origin’s are subtracted, and the difference is rotated onto the
origin’s north, east and down. Every step is closed-form geometry on the WGS84
ellipsoid, so there is no range at which the conversion starts to lose accuracy; the
only rounding is the final narrowing to f32, 1 mm at 10 km. The inverse is exact to
micrometers too — see to_geodetic.
What does change with range is not the conversion but the frame: a plane leaves a
curved Earth. At a horizontal distance d the plane sits d²/2R above the surface
under it — 8 cm at 1 km, 7.8 m at 10 km — so -p_D there is not height above the
origin, and down there is tilted d/R from local vertical. See
EQUATIONS.md
for what that means for the barometer.
PX4 projects with an azimuthal equidistant projection on a sphere
(MapProjection::project in src/lib/geo/geo.cpp): a map rather than a plane, with a
spherical Earth’s scale, 0.3% off at mid latitudes.
Implementations§
Source§impl LocalOrigin
impl LocalOrigin
Sourcepub fn new(origin: Geodetic) -> Option<Self>
pub fn new(origin: Geodetic) -> Option<Self>
The tangent plane about origin, or None for a point that cannot be one: a
coordinate that is not a number, or a latitude beyond ±90°.
Sourcepub fn to_ned(&self, point: Geodetic) -> Position<Ned>
pub fn to_ned(&self, point: Geodetic) -> Position<Ned>
A geodetic position as NED meters from the origin. Equation (43).
Sourcepub fn to_geodetic(&self, position: Position<Ned>) -> Geodetic
pub fn to_geodetic(&self, position: Position<Ned>) -> Geodetic
NED meters from the origin as a geodetic position: equation (43) run backwards.
The rotation inverts exactly (it is orthonormal, so its inverse is its transpose);
ECEF to geodetic is the one step with no closed form this simple, and is solved by
fixed-point iteration; see geodetic in this module.
Sourcepub fn placing(fix: Geodetic, estimate: Position<Ned>) -> Option<Self>
pub fn placing(fix: Geodetic, estimate: Position<Ned>) -> Option<Self>
The origin whose tangent plane puts fix at estimate. Equation (44).
For a filter that has been navigating before it knew where it was: it has a
position relative to its own start, and the first fix says where that start was.
The origin is placed so the two agree, rather than at the fix, which would step the
estimate by however far the vehicle had moved. PX4 does the same when its origin is
first set with aiding already active (collect_gps, _pos_ref.reproject(-pos)).
Solved by iteration, because the answer depends on itself: stepping -estimate
from the fix needs the origin’s axes, and those depend on where the origin is. Each
pass takes the axes from the previous guess, starting at the fix. Away from the
poles each pass shrinks the error by about |estimate| / R: measured at Zurich,
five passes leave 5 nm at 10 km, 20 µm at 100 km, and 13 mm at 300 km.
Near a pole the axes turn with longitude, and each pass shrinks the error only by
|estimate| over the distance to the pole — which grows it once the estimate is the
longer of the two. There the origin may not exist at all: an origin r from the
pole puts a point e due east of it √(r² + e²) from the pole, so a fix 11 m from
the pole is 100 m east of no origin. So the result is checked, not assumed: the fix
must land on the estimate to within what the f32 state resolves there — 1 mm, or
one part in 2²³ of |estimate| beyond 8 km — so a placement that passes steps
nothing the state could represent.
None if the fix cannot be an origin — see new — or no origin was
found that puts it at the estimate.
Trait Implementations§
Source§impl Clone for LocalOrigin
impl Clone for LocalOrigin
impl Copy for LocalOrigin
Source§impl Debug for LocalOrigin
impl Debug for LocalOrigin
Source§impl PartialEq for LocalOrigin
impl PartialEq for LocalOrigin
impl StructuralPartialEq for LocalOrigin
Auto Trait Implementations§
impl Freeze for LocalOrigin
impl RefUnwindSafe for LocalOrigin
impl Send for LocalOrigin
impl Sync for LocalOrigin
impl Unpin for LocalOrigin
impl UnsafeUnpin for LocalOrigin
impl UnwindSafe for LocalOrigin
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.