pub struct Accuracy {
pub tilt: Radians,
pub heading: Radians,
pub position: Meters,
pub velocity: MetersPerSecond,
pub horizon: Seconds,
}Expand description
How good an estimate has to be before the filter calls it valid.
The one group of numbers here that is meant to be supplied rather than derived: a
survey platform and a racing quadrotor disagree about what “good enough” means, and no
amount of flight data settles it. Everything else in Config is a property of the
hardware or the mathematics; this is a property of the mission.
Each is a standard deviation, compared against the covariance the filter carries. For
limits that differ between axes, read Eskf::covariance
directly — these are the coarse per-quantity bar.
Nothing here moves Status. Whether the start has been resolved is
ALIGNED_TILT and ALIGNED_HEADING’s question, so a survey platform can ask for 1° of
roll without also waiting for 1° before the filter stops reporting
Aligning.
A bar tighter than the prior Initialization starts from is accepted and never met: that
quantity is invalid from the first epoch, while the filter aligns and reports
Healthy as usual. On a replay it reads attitude_lost=0.00 —
out of service the moment the start resolved — beside an aligned_at= that has not moved.
Fields§
§tilt: RadiansTilt, per axis: the attitude’s σ about north and about east, each held to this. See
AttitudeVariance.
heading: RadiansHeading.
position: MetersPosition, horizontally and vertically.
velocity: MetersPerSecondVelocity, horizontally and vertically.
horizon: SecondsHow far ahead Eskf::predicted_validity asks:
how long after arming the vehicle needs the estimate to still be good.
The one number in this crate that no data could settle. Every other default here was measured or could be, by replaying what real vehicles do; this one is a statement about the mission ahead rather than about any sensor, and a multirotor that will be under a GNSS fix within a second disagrees completely with a fixed-wing hand-launched into a minute of dead reckoning.
Read as a duration of unaided flight: the covariance is propagated this far with
nothing fusing and each quantity tested at the far end. A value that is not a positive
duration projects nothing, which leaves predicted_validity its other clause — the
current answer widened by whatever source is being accepted — rather than reducing it
to validity.
The projection is (22′), exact at any horizon under its assumption of a vehicle that stays put, and one step: a horizon of minutes costs what one of a second does.
Trait Implementations§
impl Copy for Accuracy
Source§impl Default for Accuracy
impl Default for Accuracy
Source§fn default() -> Self
fn default() -> Self
Attitude clears the prior a static alignment starts from, by the margin an unaided
filter takes to drift through. All four are placeholders for a mission nobody has
named: tilt and heading are ALIGNED_TILT and ALIGNED_HEADING because a bar
some estimator uses is a better starting point than none, and position and velocity
are loose enough to admit a 1 Hz GNSS solution.
Exactly those, not rounded near them. A mission bar a hair under the alignment bar opens a sliver where a start aligns and is out of service at the same epoch, for a reason nobody chose: 0.052 rad against 3°’s 0.0524 did exactly that.
A bar equal to the prior it is compared against is no bar at all: with
tilt at Initialization::sigma_tilt
exactly and heading at
Initialization::sigma_yaw exactly, compared with <=, a
static start passes by zero margin and the first Q of equation (21) takes it away
again. On every static log in data/manifest.txt that read as a valid attitude for
exactly one sample.
What these buy, measured on a static start at ImuNoise’s defaults: 10.3 s of unaided
propagation before tilt leaves the bar and 274 s before heading does, from a window that
measured its gyroscope, and 4.84 s and 51.4 s from one whose gyroscope never scattered
(an_unaided_start_holds_its_attitude_for_the_margin_the_defaults_buy). The window sets
them: the gyroscope-bias prior enters attitude through equation (20)’s −I Δt and grows
as σ_βg² t², and only a window that measured the bias makes that prior small (see
Initialization::sigma_gyro_bias). They are the schedule with Config::hold off. The
position hold engages at the same 3° and pulls tilt back toward the bar each fusion, so
with it on tilt stays valid until one fusion every 0.2 s is no longer enough: 16.28 s on
f16771dd rather than 9.83, which is not a better attitude.
What those two times move is Validity, and nothing else.
Status is already answering on the aiding timers by then — an unaided
filter reports DeadReckoning from
Timeouts::dead_reckoning_after without horizontal aiding, or from its first step if
none was ever accepted — and Aligning reads the alignment
bars rather than these.
So these are a claim about which outputs a controller may still use, which is the
question Accuracy exists to answer. Supply your own numbers.
horizon is 1 s, and it is a placeholder in a stronger sense
than the other four: they are bars some estimator uses, while no estimator publishes
this one at all. A second is the shortest horizon that is not simply
validity asked twice — long enough that (20) has started to
tell on tilt, short enough that a vehicle expecting a
GNSS fix on takeoff is not failed for the gap before it.
impl StructuralPartialEq for Accuracy
Auto Trait Implementations§
impl Freeze for Accuracy
impl RefUnwindSafe for Accuracy
impl Send for Accuracy
impl Sync for Accuracy
impl Unpin for Accuracy
impl UnsafeUnpin for Accuracy
impl UnwindSafe for Accuracy
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.