@@ -2066,36 +2066,49 @@ pub fn print_ukf(ukf: &UnscentedKalmanFilter, record: &TestDataRecord) {
20662066 ukf. get_certainty( ) [ ( 14 , 14 ) ]
20672067 ) ;
20682068}
2069+
2070+ /// Configuration parameters for UKF initialization.
2071+ ///
2072+ /// This struct groups together optional parameters for initializing an Unscented Kalman Filter,
2073+ /// reducing the number of function arguments and making it easier to specify custom configurations.
2074+ #[ derive( Debug , Clone , Default ) ]
2075+ pub struct UkfConfig {
2076+ /// Optional vector of f64 representing the initial attitude covariance (default is a small value).
2077+ pub attitude_covariance : Option < Vec < f64 > > ,
2078+ /// Optional vector of f64 representing the initial IMU biases (default is a small value).
2079+ pub imu_biases : Option < Vec < f64 > > ,
2080+ /// Optional vector of f64 representing the IMU biases covariance.
2081+ pub imu_biases_covariance : Option < Vec < f64 > > ,
2082+ /// Optional vector of f64 for any additional states (not used in the canonical UKF, but can be useful for custom implementations).
2083+ pub other_states : Option < Vec < f64 > > ,
2084+ /// Optional vector of f64 for other states covariance.
2085+ pub other_states_covariance : Option < Vec < f64 > > ,
2086+ /// Optional process noise diagonal vector.
2087+ pub process_noise_diagonal : Option < Vec < f64 > > ,
2088+ /// Optional UKF alpha parameter (sigma-point spread).
2089+ pub ukf_alpha : Option < f64 > ,
2090+ /// Optional UKF beta parameter (prior distribution).
2091+ pub ukf_beta : Option < f64 > ,
2092+ /// Optional UKF kappa parameter (secondary spread control).
2093+ pub ukf_kappa : Option < f64 > ,
2094+ }
2095+
20692096/// Helper function to initialize a UKF for closed-loop mode.
20702097///
2071- /// This function sets up the Unscented Kalman Filter (UKF) with initial pose, attitude covariance, and IMU biases based on
2072- /// the provided `TestDataRecord`. It initializes the UKF with position, velocity, attitude, and covariance matrices.
2073- /// Optional parameters for attitude covariance and IMU biases can be provided to customize the filter's initial state.
2098+ /// This function sets up the Unscented Kalman Filter (UKF) with initial pose and configuration parameters.
2099+ /// It initializes the UKF with position, velocity, attitude, and covariance matrices.
20742100///
20752101/// # Arguments
20762102///
20772103/// * `initial_pose` - A `TestDataRecord` containing the initial pose information.
2078- /// * `attitude_covariance` - Optional vector of f64 representing the initial attitude covariance (default is a small value).
2079- /// * `imu_biases` - Optional vector of f64 representing the initial IMU biases (default is a small value).
2080- /// * `other_states` - Optional vector of f64 for any additional states (not used in the canonical UKF, but can be useful for custom implementations).
2081- /// * `ukf_alpha` - Optional UKF alpha parameter (sigma-point spread).
2082- /// * `ukf_beta` - Optional UKF beta parameter (prior distribution).
2083- /// * `ukf_kappa` - Optional UKF kappa parameter (secondary spread control).
2104+ /// * `config` - A `UkfConfig` struct containing optional configuration parameters.
20842105///
20852106/// # Returns
20862107///
2087- /// * `UKF ` - An instance of the Unscented Kalman Filter initialized with the provided parameters.
2108+ /// * `UnscentedKalmanFilter ` - An instance of the Unscented Kalman Filter initialized with the provided parameters.
20882109pub fn initialize_ukf (
20892110 initial_pose : TestDataRecord ,
2090- attitude_covariance : Option < Vec < f64 > > ,
2091- imu_biases : Option < Vec < f64 > > ,
2092- imu_biases_covariance : Option < Vec < f64 > > ,
2093- other_states : Option < Vec < f64 > > ,
2094- other_states_covariance : Option < Vec < f64 > > ,
2095- process_noise_diagonal : Option < Vec < f64 > > ,
2096- ukf_alpha : Option < f64 > ,
2097- ukf_beta : Option < f64 > ,
2098- ukf_kappa : Option < f64 > ,
2111+ config : UkfConfig ,
20992112) -> UnscentedKalmanFilter {
21002113 let initial_state = InitialState {
21012114 latitude : initial_pose. latitude ,
@@ -2122,7 +2135,7 @@ pub fn initialize_ukf(
21222135 in_degrees : true ,
21232136 is_enu : true ,
21242137 } ;
2125- let process_noise_diagonal = match process_noise_diagonal {
2138+ let process_noise_diagonal = match config . process_noise_diagonal {
21262139 Some ( pn) => pn,
21272140 None => DEFAULT_PROCESS_NOISE . to_vec ( ) ,
21282141 } ;
@@ -2138,14 +2151,14 @@ pub fn initialize_ukf(
21382151 initial_pose. speed_accuracy. powf( 2.0 ) ,
21392152 ] ;
21402153 // extend the covariance diagonal if attitude covariance is provided
2141- match attitude_covariance {
2154+ match config . attitude_covariance {
21422155 Some ( att_cov) => covariance_diagonal. extend ( att_cov) ,
21432156 None => covariance_diagonal. extend ( vec ! [ 1e-9 ; 3 ] ) , // Default values if not provided
21442157 }
21452158 // extend the covariance diagonal if imu biases are provided
2146- let imu_biases = match imu_biases {
2159+ let imu_biases = match config . imu_biases {
21472160 Some ( imu_biases) => {
2148- covariance_diagonal. extend ( match imu_biases_covariance {
2161+ covariance_diagonal. extend ( match config . imu_biases_covariance {
21492162 Some ( imu_cov) => imu_cov,
21502163 None => vec ! [ 1e-3 ; 6 ] , // Default covariance if not provided
21512164 } ) ;
@@ -2157,9 +2170,9 @@ pub fn initialize_ukf(
21572170 }
21582171 } ;
21592172 // extend the covariance diagonal if other states are provided
2160- let other_states = match other_states {
2173+ let other_states = match config . other_states {
21612174 Some ( other_states) => {
2162- covariance_diagonal. extend ( match other_states_covariance {
2175+ covariance_diagonal. extend ( match config . other_states_covariance {
21632176 Some ( other_cov) => other_cov,
21642177 None => vec ! [ 1e-3 ; other_states. len( ) ] , // Default covariance if not provided
21652178 } ) ;
@@ -2193,9 +2206,9 @@ pub fn initialize_ukf(
21932206 other_states,
21942207 covariance_diagonal,
21952208 process_noise,
2196- ukf_alpha. unwrap_or ( 1e-3 ) ,
2197- ukf_beta. unwrap_or ( 2.0 ) ,
2198- ukf_kappa. unwrap_or ( 0.0 ) ,
2209+ config . ukf_alpha . unwrap_or ( 1e-3 ) ,
2210+ config . ukf_beta . unwrap_or ( 2.0 ) ,
2211+ config . ukf_kappa . unwrap_or ( 0.0 ) ,
21992212 )
22002213}
22012214
@@ -3720,15 +3733,7 @@ mod tests {
37203733 // Initialize UKF
37213734 let mut ukf = initialize_ukf (
37223735 rec. clone ( ) ,
3723- None ,
3724- None ,
3725- None ,
3726- None ,
3727- None ,
3728- None ,
3729- None ,
3730- None ,
3731- None ,
3736+ UkfConfig :: default ( ) ,
37323737 ) ;
37333738
37343739 // Create a minimal EventStream with one IMU event
@@ -3786,28 +3791,16 @@ mod tests {
37863791 } ;
37873792 let ukf = initialize_ukf (
37883793 rec. clone ( ) ,
3789- None ,
3790- None ,
3791- None ,
3792- None ,
3793- None ,
3794- None ,
3795- None ,
3796- None ,
3797- None ,
3794+ UkfConfig :: default ( ) ,
37983795 ) ;
37993796 assert ! ( !ukf. get_estimate( ) . is_empty( ) ) ;
38003797 let ukf2 = initialize_ukf (
38013798 rec,
3802- Some ( vec ! [ 0.1 , 0.2 , 0.3 ] ) ,
3803- Some ( vec ! [ 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 ] ) ,
3804- None ,
3805- None ,
3806- None ,
3807- None ,
3808- None ,
3809- None ,
3810- None ,
3799+ UkfConfig {
3800+ attitude_covariance : Some ( vec ! [ 0.1 , 0.2 , 0.3 ] ) ,
3801+ imu_biases : Some ( vec ! [ 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 ] ) ,
3802+ ..Default :: default ( )
3803+ } ,
38113804 ) ;
38123805 assert ! ( !ukf2. get_estimate( ) . is_empty( ) ) ;
38133806 }
@@ -3999,15 +3992,7 @@ mod tests {
39993992 } ;
40003993 let ukf = initialize_ukf (
40013994 rec. clone ( ) ,
4002- None ,
4003- None ,
4004- None ,
4005- None ,
4006- None ,
4007- None ,
4008- None ,
4009- None ,
4010- None ,
3995+ UkfConfig :: default ( ) ,
40113996 ) ;
40123997 let timestamp = Utc :: now ( ) ;
40133998 let nav_result = NavigationResult :: from ( ( & timestamp, & ukf) ) ;
@@ -4064,15 +4049,7 @@ mod tests {
40644049 } ;
40654050 let ukf = initialize_ukf (
40664051 rec. clone ( ) ,
4067- None ,
4068- None ,
4069- None ,
4070- None ,
4071- None ,
4072- None ,
4073- None ,
4074- None ,
4075- None ,
4052+ UkfConfig :: default ( ) ,
40764053 ) ;
40774054 // Just ensure it doesn't panic
40784055 print_ukf ( & ukf, & rec) ;
@@ -4094,7 +4071,7 @@ mod tests {
40944071 yaw : f64:: NAN ,
40954072 ..Default :: default ( )
40964073 } ;
4097- let ukf = initialize_ukf ( rec, None , None , None , None , None , None , None , None , None ) ;
4074+ let ukf = initialize_ukf ( rec, UkfConfig :: default ( ) ) ;
40984075 let estimate = ukf. get_estimate ( ) ;
40994076 // Should default NaN angles to 0.0
41004077 assert ! ( estimate[ 6 ] . abs( ) < 1e-6 ) ; // roll
@@ -4121,15 +4098,12 @@ mod tests {
41214098 } ;
41224099 let ukf = initialize_ukf (
41234100 rec,
4124- Some ( vec ! [ 1e-4 , 2e-4 , 3e-4 ] ) ,
4125- Some ( vec ! [ 0.01 , 0.02 , 0.03 , 0.001 , 0.002 , 0.003 ] ) ,
4126- Some ( vec ! [ 1e-5 ; 6 ] ) ,
4127- None ,
4128- None ,
4129- None ,
4130- None ,
4131- None ,
4132- None ,
4101+ UkfConfig {
4102+ attitude_covariance : Some ( vec ! [ 1e-4 , 2e-4 , 3e-4 ] ) ,
4103+ imu_biases : Some ( vec ! [ 0.01 , 0.02 , 0.03 , 0.001 , 0.002 , 0.003 ] ) ,
4104+ imu_biases_covariance : Some ( vec ! [ 1e-5 ; 6 ] ) ,
4105+ ..Default :: default ( )
4106+ } ,
41334107 ) ;
41344108 let estimate = ukf. get_estimate ( ) ;
41354109 assert_eq ! ( estimate. len( ) , 15 ) ;
@@ -4155,15 +4129,10 @@ mod tests {
41554129 let custom_noise = vec ! [ 1e-5 ; 15 ] ;
41564130 let ukf = initialize_ukf (
41574131 rec,
4158- None ,
4159- None ,
4160- None ,
4161- None ,
4162- None ,
4163- Some ( custom_noise) ,
4164- None ,
4165- None ,
4166- None ,
4132+ UkfConfig {
4133+ process_noise_diagonal : Some ( custom_noise) ,
4134+ ..Default :: default ( )
4135+ } ,
41674136 ) ;
41684137 assert ! ( !ukf. get_estimate( ) . is_empty( ) ) ;
41694138 }
@@ -4653,15 +4622,7 @@ mod tests {
46534622
46544623 let mut ukf = initialize_ukf (
46554624 rec. clone ( ) ,
4656- None ,
4657- None ,
4658- None ,
4659- None ,
4660- None ,
4661- None ,
4662- None ,
4663- None ,
4664- None ,
4625+ UkfConfig :: default ( ) ,
46654626 ) ;
46664627
46674628 let stream = EventStream {
0 commit comments