@@ -149,8 +149,6 @@ impl SigmaPoint {
149149 /// sigma_point.forward(&imu_data, dt, None);
150150 /// ```
151151 pub fn forward ( & mut self , imu_data : & IMUData , dt : f64 , noise : Option < Vec < f64 > > ) {
152- // Subtract out the imu biases
153-
154152 // Propagate the strapdown state using the strapdown equations
155153 self . nav_state . forward ( imu_data, dt) ;
156154 let noise_vect = match noise {
@@ -272,6 +270,27 @@ impl SigmaPoint {
272270 } ;
273271 SigmaPoint :: new ( nav_state, other_states, weight)
274272 }
273+ /// Get a debugging string representation of the sigma point.
274+ pub fn get_string ( & self ) -> String {
275+ let mut state_str = String :: new ( ) ;
276+ state_str. push_str ( & format ! (
277+ "SigmaPoint: [lat: {:.4}, lon: {:.4}, alt: {:.2}, vel_n: {:.2}, vel_e: {:.2}, vel_d: {:.2}, roll: {:.2}, pitch: {:.2}, yaw: {:.2}]" ,
278+ self . nav_state. latitude. to_degrees( ) ,
279+ self . nav_state. longitude. to_degrees( ) ,
280+ self . nav_state. altitude,
281+ self . nav_state. velocity_north,
282+ self . nav_state. velocity_east,
283+ self . nav_state. velocity_down,
284+ self . nav_state. attitude. euler_angles( ) . 0 . to_degrees( ) ,
285+ self . nav_state. attitude. euler_angles( ) . 1 . to_degrees( ) ,
286+ self . nav_state. attitude. euler_angles( ) . 2 . to_degrees( )
287+ ) ) ;
288+ if !self . other_states . is_empty ( ) {
289+ state_str. push_str ( & format ! ( ", other_states: {:?}" , self . other_states) ) ;
290+ }
291+ state_str. push_str ( & format ! ( ", weight: {}" , self . weight) ) ;
292+ state_str
293+ }
275294}
276295
277296/// Basic strapdown state parameters for the UKF and particle filter initialization.
@@ -443,41 +462,28 @@ impl UKF {
443462 /// * none
444463 pub fn predict ( & mut self , imu_data : & IMUData , dt : f64 ) {
445464 // Propagate the strapdown state using the strapdown equations
446- //let mut sigma_points = self.sigma_points_as_matrix();
447- // for i in 0..sigma_points.ncols() {
448- // let mut sigma_point =
449- // SigmaPoint::from_vector(sigma_points.column(i).into(), None, false);
450- // sigma_point.forward(imu_data, dt, None);
451- // sigma_points
452- // .column_mut(i)
453- // .copy_from(&sigma_point.to_vector(false));
454- // }
455465 let mut sigma_points = self . get_sigma_points ( ) ;
456- let mut sigma_points_matrix =
457- DMatrix :: < f64 > :: zeros ( self . state_size , 2 * self . state_size + 1 ) ;
458- for ( i, sigma_point) in sigma_points. iter_mut ( ) . enumerate ( ) {
466+ for sigma_point in & mut sigma_points {
467+ println ! ( "{}" , sigma_point. get_string( ) ) ;
459468 sigma_point. forward ( imu_data, dt, None ) ;
460- sigma_points_matrix
461- . column_mut ( i)
462- . copy_from ( & sigma_point. to_vector ( false ) ) ;
463469 }
464- let mu_bar = & sigma_points_matrix * & self . weights_mean ;
465- let mut cov_bar = DMatrix :: < f64 > :: zeros ( self . state_size , self . state_size ) ;
466- // Update the covariance through a naive loop
467- // for (i, column) in sigma_points.column_iter().enumerate() {
468- // let diff = column - &mu_bar;
469- // cov_bar += self.weights_cov[i] * (&diff * &diff.transpose());
470- // }
471- //let mut diff = DMatrix::<f64>::zeros(self.state_size, 2 * self.state_size + 1);
472- for i in 0 ..( 2 * self . state_size + 1 ) {
473- //diff.column_mut(i).copy_from(&(&sigma_points.column(i) - &mu_bar));
474- let diff = & sigma_points_matrix. column ( i) - & mu_bar;
475- cov_bar += self . weights_cov [ i] * ( & diff * diff. transpose ( ) ) ;
470+ // Update the mean state as mu_bar
471+ let mut mu_bar = DVector :: < f64 > :: zeros ( self . state_size ) ;
472+ for ( i, sigma_point) in sigma_points. iter ( ) . enumerate ( ) {
473+ mu_bar += self . weights_mean [ i] * sigma_point. to_vector ( false ) ;
476474 }
477- //let cov_bar = (&diff * &diff.transpose()) * &self.weights_cov;
475+ // Update the covariance as P_bar
476+ let mut p_bar = DMatrix :: < f64 > :: zeros ( self . state_size , self . state_size ) ;
477+ for ( i, sigma_point) in sigma_points. iter ( ) . enumerate ( ) {
478+ let diff = sigma_point. to_vector ( false ) - & mu_bar;
479+ p_bar += self . weights_cov [ i] * & diff * & diff. transpose ( ) ;
480+ }
481+ // Add process noise to the covariance
482+ p_bar += & self . process_noise ;
483+ // Update the mean state and covariance
478484 self . mean_state = mu_bar;
479- self . covariance = & cov_bar + & self . process_noise ;
480- }
485+ self . covariance = p_bar ;
486+ }
481487 /// Perform the Kalman measurement update step.
482488 ///
483489 /// This method updates the state and covariance based on the measurement and measurement
@@ -901,6 +907,8 @@ impl GPS for UKF {
901907/// Tests
902908#[ cfg( test) ]
903909mod tests {
910+ use std:: os:: unix:: process;
911+
904912 use crate :: earth;
905913
906914 use super :: * ;
@@ -1081,66 +1089,53 @@ mod tests {
10811089 }
10821090 #[ test]
10831091 fn ukf_propagate ( ) {
1084- let position = [ 0.0 , 0.0 , 0.0 ] ;
1085- let velocity = [ 0.0 , 0.0 , 0.0 ] ;
1086- let attitude = [ 0.0 , 0.0 , 0.0 ] ;
1087- let imu_biases = vec ! [ 0.0 ; 6 ] ;
1088- //let measurement_bias = vec![1.0, 1.0, 1.0];
1089- let n = 9 + imu_biases. len ( ) ; // + measurement_bias.len();
1090- let covariance_diagonal = vec ! [ 1e-9 ; n] ;
1091- let process_noise_diagonal = vec ! [ 1e-6 ; n] ;
1092- let alpha = 1e-3 ;
1093- let beta = 2.0 ;
1094- let kappa = 0.0 ;
1092+ let n = 15 ;
1093+ let process_noise_diagonal = vec ! [ 1e-3 ; n] ;
10951094 let ukf_params = StrapdownParams {
1096- latitude : position [ 0 ] ,
1097- longitude : position [ 1 ] ,
1098- altitude : position [ 2 ] ,
1099- northward_velocity : velocity [ 0 ] ,
1100- eastward_velocity : velocity [ 1 ] ,
1101- downward_velocity : velocity [ 2 ] ,
1102- roll : attitude [ 0 ] ,
1103- pitch : attitude [ 1 ] ,
1104- yaw : attitude [ 2 ] ,
1095+ latitude : 0.0 ,
1096+ longitude : 0.0 ,
1097+ altitude : 0.0 ,
1098+ northward_velocity : 0.0 ,
1099+ eastward_velocity : 0.0 ,
1100+ downward_velocity : 0.0 ,
1101+ roll : 0.0 ,
1102+ pitch : 0.0 ,
1103+ yaw : 0.0 ,
11051104 in_degrees : false ,
11061105 } ;
11071106 let mut ukf = UKF :: new (
11081107 ukf_params,
1109- imu_biases . clone ( ) ,
1108+ vec ! [ 0.0 ; 6 ] ,
11101109 None , //Some(measurement_bias.clone()),
1111- covariance_diagonal ,
1110+ vec ! [ 0.0 ; n ] , // Absolute certainty use for testing the process
11121111 DMatrix :: from_diagonal ( & DVector :: from_vec ( process_noise_diagonal) ) ,
1113- alpha ,
1114- beta ,
1115- kappa ,
1112+ 1e-3 ,
1113+ 2.0 ,
1114+ 0.0 ,
11161115 ) ;
11171116 let dt = 1.0 ;
11181117 let imu_data = IMUData :: new_from_vector (
11191118 Vector3 :: new ( 0.0 , 0.0 , earth:: gravity ( & 0.0 , & 0.0 ) ) ,
11201119 Vector3 :: new ( 0.0 , 0.0 , 0.0 ) , // No rotation
11211120 ) ;
1122- println ! ( "mean_state: {}" , ukf. mean_state) ;
1123- println ! ( "covariance: {}" , ukf. covariance) ;
1124- println ! ( "sigmas: {:.2e}" , ukf. sigma_points_as_matrix( ) ) ;
11251121 ukf. predict ( & imu_data, dt) ;
11261122 assert ! (
11271123 ukf. mean_state. len( )
1128- == position . len ( ) + velocity . len ( ) + attitude . len ( ) + imu_biases . len ( ) //+ measurement_bias.len()
1124+ == 15 //+ measurement_bias.len()
11291125 ) ;
1130- println ! ( "mean_state: {:.4e}" , ukf. mean_state) ;
1131- println ! ( "covariance: {:.2e}" , ukf. covariance) ;
1126+ let measurement = DVector :: from_vec ( vec ! [ 0.0 ; 3 ] ) ;
11321127 ukf. update (
1133- & DVector :: from_vec ( position . to_vec ( ) ) ,
1128+ & measurement ,
11341129 & ukf. position_measurement_model ( true ) ,
11351130 & ukf. position_measurement_noise ( true ) ,
11361131 ) ;
11371132 // Check that the state has not changed
1138- assert_approx_eq ! ( ukf. mean_state[ 0 ] , position [ 0 ] , 1e-3 ) ;
1139- assert_approx_eq ! ( ukf. mean_state[ 1 ] , position [ 1 ] , 1e-3 ) ;
1140- assert_approx_eq ! ( ukf. mean_state[ 2 ] , position [ 2 ] , 0.1 ) ;
1141- assert_approx_eq ! ( ukf. mean_state[ 3 ] , velocity [ 0 ] , 0.1 ) ;
1142- assert_approx_eq ! ( ukf. mean_state[ 4 ] , velocity [ 1 ] , 0.1 ) ;
1143- assert_approx_eq ! ( ukf. mean_state[ 5 ] , velocity [ 2 ] , 0.1 ) ;
1133+ assert_approx_eq ! ( ukf. mean_state[ 0 ] , 0.0 , 1e-3 ) ;
1134+ assert_approx_eq ! ( ukf. mean_state[ 1 ] , 0.0 , 1e-3 ) ;
1135+ assert_approx_eq ! ( ukf. mean_state[ 2 ] , 0.0 , 0.1 ) ;
1136+ assert_approx_eq ! ( ukf. mean_state[ 3 ] , 0.0 , 0.1 ) ;
1137+ assert_approx_eq ! ( ukf. mean_state[ 4 ] , 0.0 , 0.1 ) ;
1138+ assert_approx_eq ! ( ukf. mean_state[ 5 ] , 0.0 , 0.1 ) ;
11441139 }
11451140 #[ test]
11461141 fn ukf_debug ( ) {
0 commit comments