@@ -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