Skip to content

Commit 6d88980

Browse files
committed
refactored position update
1 parent bf991c6 commit 6d88980

1 file changed

Lines changed: 48 additions & 35 deletions

File tree

core/src/strapdown.rs

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -462,48 +462,27 @@ impl StrapdownState {
462462
/// let dt = 0.1; // Example time step in seconds
463463
/// state = forward(&imu_data, dt);
464464
/// ```
465-
pub fn forward(state: StrapdownState, imu_data: IMUData, dt: f64) {
465+
pub fn forward(mut state: StrapdownState, imu_data: IMUData, dt: f64) {
466466
// Extract the attitude matrix from the current state
467-
let c_0: Rotation3<f64> = self.attitude;
467+
let c_0: Rotation3<f64> = state.attitude;
468468
// Attitude update; Equation 5.46
469-
let c_1: Matrix3<f64> = self.attitude_update(&imu_data.gyro, dt);
469+
let c_1: Matrix3<f64> = attitude_update(&state, imu_data.gyro, dt.clone());
470470
// Specific force transformation; Equation 5.47
471471
let f: Vector3<f64> = 0.5 * (c_0.matrix() + c_1) * imu_data.accel;
472472
// Velocity update; Equation 5.54
473-
//let v_0: Vector3<f64> = self.get_velocity();
474-
let v_n_0 = self.velocity_north;
475-
let v_e_0 = self.velocity_east;
476-
let v_d_0 = self.velocity_down;
477-
//let v_1: Vector3<f64> = self.velocity_update(&f, dt);
478-
let v = self.velocity_update(&f, dt);
479-
let v_n_1 = v[0];
480-
let v_e_1 = v[1];
481-
let v_d_1 = v[2];
473+
let velocity = velocity_update(&state, f, dt.clone());
482474
// Position update; Equation 5.56
483-
let (r_n, r_e_0, _) = earth::principal_radii(&self.latitude, &self.altitude);
484-
let lat_0 = self.latitude;
485-
let alt_0 = self.altitude;
486-
// Altitude update
487-
self.altitude += 0.5 * (v_d_0 + v_d_1) * dt;
488-
// Latitude update
489-
let lat_1: f64 =
490-
self.latitude + 0.5 * (v_n_0 / (r_n + alt_0) + v_n_1 / (r_n + self.altitude)) * dt;
491-
// Longitude update
492-
let (_, r_e_1, _) = earth::principal_radii(&lat_1, &self.altitude);
493-
let lon_1: f64 = self.longitude
494-
+ 0.5
495-
* (v_e_0 / ((r_e_0 + alt_0) * lat_0.cos())
496-
+ v_e_1 / ((r_e_1 + self.altitude) * lat_1.cos()))
497-
* dt;
498-
// Save updated position
499-
self.latitude = wrap_latitude(lat_1.to_degrees()).to_radians();
500-
self.longitude = lon_1;
475+
let (lat_1, lon_1, alt_1) = position_update(&state, velocity, dt.clone());
501476
// Save updated attitude as rotation
502-
self.attitude = Rotation3::from_matrix(&c_1);
477+
state.attitude = Rotation3::from_matrix(&c_1);
503478
// Save update velocity
504-
self.velocity_north = v_n_1;
505-
self.velocity_east = v_e_1;
506-
self.velocity_down = v_d_1;
479+
state.velocity_north = velocity[0];
480+
state.velocity_east = velocity[1];
481+
state.velocity_down = velocity[2];
482+
// Save updated position
483+
state.latitude = lat_1;
484+
state.longitude = lon_1;
485+
state.altitude = alt_1;
507486
}
508487
/// NED Attitude update equation
509488
///
@@ -568,7 +547,41 @@ fn velocity_update(state: &StrapdownState, specific_force: Vector3<f64>, dt: f64
568547
);
569548
velocity + (specific_force - gravity - r * (transport_rate + 2.0 * rotation_rate) * velocity) * dt
570549
}
571-
550+
/// Position update in NED
551+
///
552+
/// This function implements the position update equation for the strapdown navigation system. It takes the current state,
553+
/// the velocity vector, and the time step as inputs and returns the updated position (latitude, longitude, altitude).
554+
///
555+
/// # Arguments
556+
/// * `state` - A reference to the current StrapdownState containing the position and velocity.
557+
/// * `velocity` - A Vector3 representing the velocity vector in m/s in the NED frame.
558+
/// * `dt` - A f64 representing the time step in seconds.
559+
///
560+
/// # Returns
561+
/// * A tuple (latitude, longitude, altitude) representing the updated position in radians and meters.
562+
pub fn position_update(state: &StrapdownState, velocity: Vector3<f64>, dt: f64) -> (f64, f64, f64) {
563+
let (r_n, r_e_0, _) = earth::principal_radii(&state.latitude, &state.altitude);
564+
let lat_0 = state.latitude;
565+
let alt_0 = state.altitude;
566+
// Altitude update
567+
let alt_1 = alt_0 + 0.5 * (state.velocity_down + velocity[2]) * dt;
568+
// Latitude update
569+
let lat_1: f64 =
570+
state.latitude + 0.5 * (state.velocity_north / (r_n + alt_0) + velocity[1] / (r_n + state.altitude)) * dt;
571+
// Longitude update
572+
let (_, r_e_1, _) = earth::principal_radii(&lat_1, &state.altitude);
573+
let lon_1: f64 = state.longitude
574+
+ 0.5
575+
* (state.velocity_east / ((r_e_0 + alt_0) * lat_0.cos())
576+
+ velocity[1] / ((r_e_1 + state.altitude) * lat_1.cos()))
577+
* dt;
578+
// Save updated position
579+
(
580+
wrap_latitude(lat_1.to_degrees()).to_radians(),
581+
wrap_to_pi(lon_1),
582+
alt_1
583+
)
584+
}
572585

573586

574587
// --- Miscellaneous functions for wrapping angles ---

0 commit comments

Comments
 (0)