pub struct ImuSample {
pub time: Timestamp,
pub delta_angle: DeltaAngle<Body>,
pub angle_interval: Seconds,
pub delta_velocity: DeltaVelocity<Body>,
pub velocity_interval: Seconds,
}Expand description
One IMU measurement, uncorrected: the rotation and the velocity increments over the intervals each was integrated across, and when they end. The filter subtracts its own bias estimates, equations (9) and (10).
PX4’s imuSample (src/modules/ekf2/EKF/common.h:182-189 at c4e4ef98), and
ArduPilot’s imu_elements (libraries/AP_NavEKF3/AP_NavEKF3_core.h:598-604 at
368dc0c4). Increments rather than rates, because an integrating driver produces
increments and (13)–(15) consume them: a rate between the two is a division by the
interval that the next line multiplies back. A rate source is the one that converts,
through from_rates.
Three times, where a single dt would collapse them. The two intervals are what each
increment integrated, kept apart as both estimators keep them, since a driver may close
the gyroscope’s and the accelerometer’s integrals at different moments. time is when
the sample ends, and the step Eskf::predict takes is the time
since the previous sample’s, which is neither interval: a logger that drops samples
leaves an increment integrated over 2.5 ms arriving a second after the one before it, and
only the timestamps see the second. Such a sample integrates what it measured and the rest
of the step goes unintegrated: a gap longer than
Config::max_predict_dt is coasted whole, and a shorter
one is not priced, so a driver that drops samples should hand over the integral across the
drop, as an integrating one does.
Default is a placeholder for struct-update syntax, not a sample: its intervals are zero,
which Eskf::predict and
Eskf::initialize both refuse as an invalid interval.
Fields§
§time: TimestampWhen both integration intervals end, on the clock every measurement is timed on.
delta_angle: DeltaAngle<Body>Rotation over angle_interval, body frame.
angle_interval: SecondsThe interval delta_angle integrates.
delta_velocity: DeltaVelocity<Body>Specific force integrated over velocity_interval, body
frame. A level, stationary vehicle gains (0, 0, −γ Δt).
velocity_interval: SecondsThe interval delta_velocity integrates.
Implementations§
Source§impl ImuSample
impl ImuSample
Sourcepub fn from_rates(
time: Timestamp,
gyro: AngularRate<Body>,
accel: Acceleration<Body>,
interval: Seconds,
) -> Self
pub fn from_rates( time: Timestamp, gyro: AngularRate<Body>, accel: Acceleration<Body>, interval: Seconds, ) -> Self
From a rate gyroscope and an accelerometer read at time, each reading standing for
the interval since the previous one.
Multiplies, which is the conversion a rate source owes and the only one: ekf2 does the
same with sensor_combined (src/modules/ekf2/EKF2.cpp:703-707 at c4e4ef98).
Sourcepub fn accumulate(self, later: ImuSample) -> ImuSample
pub fn accumulate(self, later: ImuSample) -> ImuSample
self and the later sample after it as one sample: increments and intervals summed,
timed at later’s end. What a driver reading a FIFO in batches, or running the filter
slower than its IMU, hands over.
Summed rather than composed, which is exact for a vehicle that does not rotate across
the pair and first order for one that does. PX4’s ImuDownSampler composes the
rotations as quaternions and rotates the velocity increment into the frame the batch
ends in (src/modules/ekf2/EKF/imu_down_sampler/imu_down_sampler.cpp:25-37 at
c4e4ef98e9); summing leaves out ½ Δθ₁ × Δθ₂, the coning term, and its sculling
counterpart in velocity. It is nonzero only while the rotation axis moves, and at most
3e-6 rad at 1 rad/s across two 2.5 ms samples; an integrating driver that already
corrects for it should hand its own sum over instead.
The times are not checked: Eskf::predict refuses a sample
that is not after the last, and a pair out of order is that sample.
Trait Implementations§
impl Copy for ImuSample
impl StructuralPartialEq for ImuSample
Auto Trait Implementations§
impl Freeze for ImuSample
impl RefUnwindSafe for ImuSample
impl Send for ImuSample
impl Sync for ImuSample
impl Unpin for ImuSample
impl UnsafeUnpin for ImuSample
impl UnwindSafe for ImuSample
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.