Skip to main content

LocalOrigin

Struct LocalOrigin 

Source
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

Source

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°.

Source

pub const fn geodetic(&self) -> Geodetic

Where the origin is.

Source

pub fn to_ned(&self, point: Geodetic) -> Position<Ned>

A geodetic position as NED meters from the origin. Equation (43).

Source

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.

Source

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

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for LocalOrigin

Source§

impl Debug for LocalOrigin

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for LocalOrigin

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for LocalOrigin

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Scalar for T
where T: 'static + Clone + PartialEq + Debug,

Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.