Skip to content

Commit 0ea19eb

Browse files
committed
Added combined position and velocity measurement model
1 parent bd1880c commit 0ea19eb

1 file changed

Lines changed: 72 additions & 17 deletions

File tree

core/src/filter.rs

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! Contained in this module is also a simple standard position measurement model for both
1515
//! the UKF and particle filter. This model is used to update the state based on position
1616
//! measurements in the local level frame (i.e. a GPS fix).
17-
use crate::earth::{METERS_TO_DEGREES, relative_barometric_altitude};
17+
use crate::earth::{expected_barometric_pressure, relative_barometric_altitude, METERS_TO_DEGREES};
1818
use crate::linalg::matrix_square_root;
1919
use crate::{IMUData, StrapdownState, forward, wrap_to_2pi};
2020

@@ -133,34 +133,89 @@ impl MeasurementModel for GPSVelocityMeasurement {
133133
measurement_sigma_points
134134
}
135135
}
136-
/// A releative barometric altitude measurement model that describes the relative altitude
137-
/// based on a pressure measurement. This is typically used in barometric altimeters to
138-
/// estimate the altitude relative to a reference pressure.
136+
137+
/// GPS Position and Velocity measurement model
138+
#[derive(Clone, Debug, Default)]
139+
pub struct GPSPositionAndVelocityMeasurement {
140+
/// latitude in degrees
141+
pub latitude: f64,
142+
/// longitude in degrees
143+
pub longitude: f64,
144+
/// altitude in meters
145+
pub altitude: f64,
146+
/// Northward velocity in m/s
147+
pub northward_velocity: f64,
148+
/// Eastward velocity in m/s
149+
pub eastward_velocity: f64,
150+
/// Downward velocity in m/s
151+
// pub downward_velocity: f64, // GPS speed measurements do not typically provide vertical velocity
152+
/// noise standard deviation in meters for position
153+
pub horizontal_noise_std: f64,
154+
/// vertical noise standard deviation in meters for position
155+
pub vertical_noise_std: f64,
156+
/// noise standard deviation in m/s for velocity
157+
pub velocity_noise_std: f64,
158+
}
159+
impl MeasurementModel for GPSPositionAndVelocityMeasurement {
160+
fn get_dimension(&self) -> usize {
161+
5 // latitude, longitude, altitude, northward velocity, eastward velocity
162+
}
163+
fn get_vector(&self) -> DVector<f64> {
164+
DVector::from_vec(vec![
165+
self.latitude.to_radians(),
166+
self.longitude.to_radians(),
167+
self.altitude,
168+
self.northward_velocity,
169+
self.eastward_velocity,
170+
])
171+
}
172+
fn get_noise(&self) -> DMatrix<f64> {
173+
DMatrix::from_diagonal(&DVector::from_vec(vec![
174+
(self.horizontal_noise_std * METERS_TO_DEGREES).powi(2),
175+
(self.horizontal_noise_std * METERS_TO_DEGREES).powi(2),
176+
self.vertical_noise_std.powi(2),
177+
self.velocity_noise_std.powi(2),
178+
self.velocity_noise_std.powi(2),
179+
]))
180+
}
181+
fn get_sigma_points(&self, state_sigma_points: &DMatrix<f64>) -> DMatrix<f64> {
182+
let mut measurement_sigma_points = DMatrix::<f64>::zeros(5, state_sigma_points.ncols());
183+
for (i, sigma_point) in state_sigma_points.column_iter().enumerate() {
184+
measurement_sigma_points[(0, i)] = sigma_point[0];
185+
measurement_sigma_points[(1, i)] = sigma_point[1];
186+
measurement_sigma_points[(2, i)] = sigma_point[2];
187+
measurement_sigma_points[(3, i)] = sigma_point[3];
188+
measurement_sigma_points[(4, i)] = sigma_point[4];
189+
}
190+
measurement_sigma_points
191+
}
192+
}
193+
194+
/// A releative relative altitude measurement derived from barometric pressure.
195+
/// Note that this measurement model is an altitude measurement derived from
196+
/// a barometric altimeter and not a direct calculation of altitude from the
197+
/// barometric pressure.
139198
#[derive(Clone, Debug, Default)]
140-
pub struct RelativeBarometricAltitudeMeasurement {
141-
/// Measured pressure in Pa
142-
pub pressure: f64,
199+
pub struct RelativeAltitudeMeasurement {
200+
/// Measured relative altitude in meters
201+
pub relative_altitude: f64,
143202
/// Reference pressure in Pa
144-
pub reference_pressure: f64,
203+
pub reference_altitude: f64,
145204
}
146-
impl MeasurementModel for RelativeBarometricAltitudeMeasurement {
205+
impl MeasurementModel for RelativeAltitudeMeasurement {
147206
fn get_dimension(&self) -> usize {
148207
1 // relative altitude
149208
}
150209
fn get_vector(&self) -> DVector<f64> {
151-
DVector::from_vec(vec![relative_barometric_altitude(
152-
self.pressure, self.reference_pressure,
153-
)])
210+
DVector::from_vec(vec![self.relative_altitude + self.reference_altitude])
154211
}
155212
fn get_noise(&self) -> DMatrix<f64> {
156-
DMatrix::from_diagonal(&DVector::from_vec(vec![1e-3])) // 1 mm noise
213+
DMatrix::from_diagonal(&DVector::from_vec(vec![5.0])) // 1 mm noise
157214
}
158215
fn get_sigma_points(&self, state_sigma_points: &DMatrix<f64>) -> DMatrix<f64> {
159-
let mut measurement_sigma_points = DMatrix::<f64>::zeros(1, state_sigma_points.ncols());
216+
let mut measurement_sigma_points = DMatrix::<f64>::zeros(self.get_dimension(), state_sigma_points.ncols());
160217
for (i, sigma_point) in state_sigma_points.column_iter().enumerate() {
161-
measurement_sigma_points[(0, i)] = relative_barometric_altitude(
162-
sigma_point[2], self.reference_pressure,
163-
);
218+
measurement_sigma_points[(0, i)] = sigma_point[2];
164219
}
165220
measurement_sigma_points
166221
}

0 commit comments

Comments
 (0)