Skip to main content

Attitude

Struct Attitude 

Source
pub struct Attitude(/* private fields */);
Expand description

Vehicle attitude: the rotation from Body to Ned.

Equation (7). Hamilton convention, crossing the API as a Quaternion, whose fields name the components. Each constructor normalizes what it is given; a zero or non-finite quaternion comes out non-finite, and Eskf::initialize_from refuses it as InitError::NotFinite.

Every constructor names the convention it takes, and there is no From<Quaternion>, for the reason the module docs give for keeping From<[f32; 3]> off the framed vectors: .into() would claim body-to-NED for a quaternion that is a stored inverse or an ENU one. A seed is where that costs most, because it is the one input with no residual to expose it: the filter runs on an attitude wrong by a frame, reports Status::Healthy if the seed covariance was confident, and nothing gates. How wrong depends on the attitude — the level case is a half turn, which is why a level bench check is the one that cannot find it.

Implementations§

Source§

impl Attitude

Source

pub fn level() -> Self

Level and pointing north.

Source

pub fn from_body_to_ned(q: Quaternion) -> Self

Wrap a quaternion that already rotates body FRD to NED. Equation (7).

The seed path from either production autopilot, and it converts nothing: PX4’s vehicle_attitude.q is the “rotation from the FRD body frame to the NED earth frame”, Hamilton and scalar-first (msg/versioned/VehicleAttitude.msg:2,10), and ArduPilot publishes AP_AHRS::get_quat_body_to_ned (libraries/AP_AHRS/AP_AHRS.h:672). from_flu_to_nwu maps fusion-ahrs’s three conventions onto these constructors, Convention::Ned included.

Read at PX4-Autopilot c4e4ef98 (v1.18.0-beta1) and ardupilot 368dc0c4.

Source

pub fn from_ned_to_body(q: Quaternion) -> Self

Invert a quaternion that rotates NED to body FRD.

Storing the inverse — the direction-cosine matrix that takes a navigation vector into the body frame — is a common convention, and it is the mistake no other check reaches. An inverted attitude is finite, is a unit quaternion, and is identity wherever the true one is, so it survives every gate and every static test; it differs only in the sign of every rotation the vehicle actually has.

Source

pub fn from_flu_to_enu(q: Quaternion) -> Self

Convert a quaternion that rotates body FLU to ENU, the ROS REP 103 pair.

Two-sided, because both frames differ: q_{NED←FRD} = r_nav ⊗ q ⊗ r_body⁻¹, where r_nav is q_{NED←ENU} and r_body is q_{FRD←FLU}. Rotating only the navigation frame is the half-applied form, and it is not obviously wrong: it reports the same heading as this one and the vehicle upside down, so a level bench check that reads a compass agrees with it.

Source

pub fn from_flu_to_nwu(q: Quaternion) -> Self

Convert a quaternion that rotates body FLU to NWU, as Madgwick-family filters report it.

fusion-ahrs is the one to hand: its quaternion rotates the sensor frame into the earth frame, its default Convention::Nwu puts north, west, up on the earth axes, and a level sensor then reads gravity on +z, which is an FLU body. Convention::Enu is from_flu_to_enu and Convention::Ned is from_body_to_ned.

Two-sided for the reason from_flu_to_enu is. Both halves are the same half turn here, so the conversion is a conjugation and a vehicle that is only rolled comes through unchanged — a second attitude that cannot tell a conversion from no conversion at all.

Source

pub fn body_to_ned(self) -> Quaternion

The quaternion that rotates body FRD to NED: the convention from_body_to_ned takes, and what PX4 and ArduPilot publish.

Source

pub fn ned_to_body(self) -> Quaternion

The quaternion that rotates NED to body FRD: the inverse of from_ned_to_body, for a consumer that stores the direction-cosine matrix taking navigation vectors into the body.

Source

pub fn flu_to_enu(self) -> Quaternion

The quaternion that rotates body FLU to ENU, for ROS (nav_msgs/Odometry, sensor_msgs/Imu): the inverse of from_flu_to_enu.

Two-sided on the way out for the reason it is on the way in, q = r_nav⁻¹ ⊗ q_{NED←FRD} ⊗ r_body; rotating the navigation frame alone publishes the right heading and the vehicle upside down.

Source

pub fn flu_to_nwu(self) -> Quaternion

The quaternion that rotates body FLU to NWU, as Madgwick-family filters report it: the inverse of from_flu_to_nwu.

Source

pub fn euler_angles(self) -> (f32, f32, f32)

Roll, pitch, yaw in radians, from the ZYX sequence R = Rz(yaw) Ry(pitch) Rx(roll).

Trait Implementations§

Source§

impl Clone for Attitude

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 Attitude

Source§

impl Debug for Attitude

Source§

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

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

impl Default for Attitude

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Format for Attitude

Available on crate feature defmt only.

The quaternion’s four components, scalar first, rather than nalgebra’s own Format, which would need its defmt feature and a second optional dependency edge to name it.

Source§

fn format(&self, f: Formatter<'_>)

Writes the defmt representation of self to fmt.
Source§

impl PartialEq for Attitude

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 Attitude

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.