ekf_cal  0.4.0
A Kalman filter-based sensor calibration package
ekf.hpp
1 // Copyright 2022 Jacob Hartzer
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <https://www.gnu.org/licenses/>.
15 
16 #ifndef EKF__EKF_HPP_
17 #define EKF__EKF_HPP_
18 
19 #include <eigen3/Eigen/Eigen>
20 #include <stddef.h>
21 
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include "ekf/constants.hpp"
27 #include "ekf/types.hpp"
28 #include "infrastructure/data_logger.hpp"
29 #include "infrastructure/debug_logger.hpp"
30 
38 class EKF
39 {
40 public:
44  typedef struct Parameters
45  {
46  std::shared_ptr<DebugLogger> debug_logger;
47  double data_log_rate{0.0};
48  std::string log_directory{""};
49  AugmentationType augmenting_type{AugmentationType::ALL};
50  double augmenting_delta_time{1.0};
51  double augmenting_pos_error{0.1};
52  double augmenting_ang_error{0.1};
54  Eigen::VectorXd process_noise{Eigen::VectorXd::Ones(g_body_state_size)};
55  Eigen::Vector3d pos_b_in_l{Eigen::Vector3d::Zero()};
56  Eigen::Quaterniond ang_b_to_l {1, 0, 0, 0};
57  Eigen::Vector3d pos_e_in_g {Eigen::Vector3d::Zero()};
58  double ang_l_to_e{0.0};
59  GpsInitType gps_init_type {GpsInitType::CONSTANT};
60  double gps_init_baseline_dist {100.0};
61  double gps_init_pos_thresh {0.1};
62  double gps_init_ang_thresh {0.1};
64  double imu_noise_scale_factor {100.0};
65  bool use_root_covariance{false};
68 
73  explicit EKF(Parameters params);
74 
79  unsigned int GetStateSize() const;
80 
86  ImuState GetImuState(unsigned int imu_id);
87 
93  GpsState GetGpsState(unsigned int gps_id);
99  CamState GetCamState(unsigned int cam_id);
100 
105  unsigned int GetImuCount() const;
106 
111  unsigned int GetImuStateSize() const;
112 
117  unsigned int GetGpsCount() const;
118 
123  unsigned int GetGpsStateSize() const;
124 
129  unsigned int GetCamStateSize() const;
130 
135  unsigned int GetCamCount() const;
136 
141  void LogBodyStateIfNeeded(int execution_count);
142 
147  void PredictModel(double local_time);
148 
154  static Eigen::MatrixXd GetStateTransition(double delta_time);
155 
161  void Initialize(double initial_time, const BodyState & body_state_init);
162 
169  void RegisterIMU(
170  unsigned int imu_id,
171  const ImuState & imu_state,
172  const Eigen::MatrixXd & covariance);
173 
180  void RegisterGPS(
181  unsigned int gps_id,
182  const GpsState & gps_state,
183  const Eigen::Matrix3d & covariance);
184 
191  void RegisterCamera(
192  unsigned int cam_id,
193  const CamState & cam_state,
194  const Eigen::MatrixXd & covariance);
195 
201  void RegisterFiducial(const FidState & fid_state, const Eigen::MatrixXd & covariance);
202 
209  Eigen::MatrixXd AugmentCovariance(const Eigen::MatrixXd & in_cov, unsigned int index) const;
210 
214  void AugmentStateIfNeeded();
215 
221  void AugmentStateIfNeeded(unsigned int camera_id, unsigned int frame_id);
222 
227  void SetMaxTrackLength(unsigned int max_track_length);
228 
233  void SetBodyProcessNoise(const Eigen::VectorXd & process_noise);
234 
240  void SetGpsReference(const Eigen::VectorXd & pos_e_in_g, double ang_l_to_e);
241 
246  void SetZeroAcceleration(bool is_zero_acceleration);
247 
252  Eigen::VectorXd GetReferenceLLA() const;
253 
258  double GetReferenceAngle() const;
259 
264  bool IsLlaInitialized() const;
265 
270  bool IsGravityInitialized() const;
271 
275  void InitializeGravity();
276 
284  AugState GetAugState(unsigned int camera_id, unsigned int frame_id, double time);
285 
290  unsigned int GetAugStateSize() const;
291 
295  void RefreshIndices();
296 
303  double time,
304  const Eigen::Vector3d & gps_lla);
305 
310  std::vector<double> GetGpsTimeVector() const;
311 
316  std::vector<Eigen::Vector3d> GetGpsEcefVector() const;
317 
322  std::vector<Eigen::Vector3d> GetGpsXyzVector() const;
323 
328  double GetCurrentTime() const;
329 
334  unsigned int GetImuStateStart() const;
335 
340  unsigned int GetGpsStateStart() const;
341 
346  unsigned int GetCamStateStart() const;
347 
352  unsigned int GetAugStateStart() const;
353 
358  unsigned int GetFidStateStart() const;
359 
364  double GetMotionDetectionChiSquared() const;
365 
370  double GetImuNoiseScaleFactor() const;
371 
376  bool GetUseRootCovariance() const;
377 
382  bool GetUseFirstEstimateJacobian() const;
383 
388  double CalculateLocalTime(double time);
389 
392 
394  Eigen::MatrixXd m_cov = Eigen::MatrixXd::Identity(g_body_state_size, g_body_state_size) * 1e-2;
395 
396 private:
397  unsigned int m_state_size{g_body_state_size};
398  unsigned int m_imu_state_size{0};
399  unsigned int m_gps_state_size{0};
400  unsigned int m_cam_state_size{0};
401  unsigned int m_aug_state_size{0};
402  unsigned int m_fid_state_size{0};
403  double m_current_time {0};
404  double m_reference_time {0};
405  bool m_time_initialized {false};
406  unsigned int m_max_track_length{20};
407  Eigen::MatrixXd m_process_noise {Eigen::MatrixXd::Zero(g_body_state_size, g_body_state_size)};
408  Eigen::VectorXd m_body_process_noise {Eigen::VectorXd::Zero(g_body_state_size)};
409  std::shared_ptr<DebugLogger> m_debug_logger;
410  DataLogger m_data_logger;
411  DataLogger m_augmentation_logger;
412  double m_data_log_rate{0.0};
413 
414  GpsInitType m_gps_init_type;
415  double m_gps_init_pos_thresh;
416  double m_gps_init_ang_thresh;
417  double m_gps_init_baseline_dist;
418  bool m_is_lla_initialized;
419  Eigen::Vector3d m_pos_e_in_g;
420  double m_ang_l_to_e;
421  std::vector<double> m_gps_time_vec;
422  std::vector<Eigen::Vector3d> m_gps_ecef_vec;
423  std::vector<Eigen::Vector3d> m_gps_xyz_vec;
424 
425  AugmentationType m_augmenting_type;
426  double m_augmenting_prev_time;
427  double m_augmenting_delta_time;
428  double m_augmenting_pos_error;
429  double m_augmenting_ang_error;
430  unsigned int m_primary_camera_id{0};
431  double m_max_frame_period {0.0};
432  double m_max_track_duration {0.0};
433  double m_min_aug_period {1.0};
434 
435  unsigned int m_imu_state_start{0};
436  unsigned int m_gps_state_start{0};
437  unsigned int m_cam_state_start{0};
438  unsigned int m_aug_state_start{0};
439  unsigned int m_fid_state_start{0};
440 
441  bool m_is_gravity_initialized{false};
442  double m_motion_detection_chi_squared{1.0};
443  double m_imu_noise_scale_factor{100.0};
444 
445  bool m_use_root_covariance{true};
446  bool m_use_first_estimate_jacobian{false};
447  bool m_is_zero_acceleration{true};
448  bool m_frame_received_since_last_aug {true};
449 };
450 
451 #endif // EKF__EKF_HPP_
AugState structure.
Definition: types.hpp:213
BodyState structure.
Definition: types.hpp:81
CamState structure.
Definition: types.hpp:236
DataLogger class.
Definition: data_logger.hpp:26
Calibration EKF class.
Definition: ekf.hpp:39
void SetZeroAcceleration(bool is_zero_acceleration)
Zero acceleration flag setter.
Definition: ekf.cpp:647
bool GetUseRootCovariance() const
Getter for use root covariance flag.
Definition: ekf.cpp:855
void SetMaxTrackLength(unsigned int max_track_length)
Setter for maximum track length.
Definition: ekf.cpp:634
void SetGpsReference(const Eigen::VectorXd &pos_e_in_g, double ang_l_to_e)
GPS reference position setter.
Definition: ekf.cpp:640
State m_state
EKF state.
Definition: ekf.hpp:391
unsigned int GetFidStateStart() const
Fiducial state start getter.
Definition: ekf.cpp:835
Eigen::MatrixXd m_cov
EKF covariance.
Definition: ekf.hpp:394
static Eigen::MatrixXd GetStateTransition(double delta_time)
State transition matrix getter method.
Definition: ekf.cpp:89
unsigned int GetCamStateStart() const
Camera state start getter.
Definition: ekf.cpp:825
void RegisterIMU(unsigned int imu_id, const ImuState &imu_state, const Eigen::MatrixXd &covariance)
IMU Registration function.
Definition: ekf.cpp:252
CamState GetCamState(unsigned int cam_id)
Get camera sensor state.
Definition: ekf.cpp:205
void AugmentStateIfNeeded()
Check if state should be augmented using current state.
Definition: ekf.cpp:436
void RegisterGPS(unsigned int gps_id, const GpsState &gps_state, const Eigen::Matrix3d &covariance)
GPS Registration function.
Definition: ekf.cpp:288
Eigen::VectorXd GetReferenceLLA() const
Getter for the LLA reference position.
Definition: ekf.cpp:652
struct EKF::Parameters Parameters
EKF class parameters.
unsigned int GetImuCount() const
IMU count getter method.
Definition: ekf.cpp:210
std::vector< Eigen::Vector3d > GetGpsXyzVector() const
GPS XYZ vector getter.
Definition: ekf.cpp:810
Eigen::MatrixXd AugmentCovariance(const Eigen::MatrixXd &in_cov, unsigned int index) const
Augment the state covariance matrix.
Definition: ekf.cpp:381
unsigned int GetCamCount() const
Camera count getter method.
Definition: ekf.cpp:235
unsigned int GetAugStateStart() const
Augmented states start getter.
Definition: ekf.cpp:830
bool IsLlaInitialized() const
Checks if the LLA reference frame has been initialized.
Definition: ekf.cpp:665
double CalculateLocalTime(double time)
Calculate UTF time to local EKF time.
Definition: ekf.cpp:865
void InitializeGravity()
Function to initialize gravity angle.
Definition: ekf.cpp:675
AugState GetAugState(unsigned int camera_id, unsigned int frame_id, double time)
Find or interpolate augmented state.
Definition: ekf.cpp:574
unsigned int GetCamStateSize() const
Camera state size getter method.
Definition: ekf.cpp:230
unsigned int GetGpsStateSize() const
GPS state size getter method.
Definition: ekf.cpp:225
double GetCurrentTime() const
Current time getter.
Definition: ekf.cpp:840
std::vector< double > GetGpsTimeVector() const
GPS time vector getter.
Definition: ekf.cpp:802
bool IsGravityInitialized() const
Checks if the gravity angle has been initialized.
Definition: ekf.cpp:670
double GetImuNoiseScaleFactor() const
IMU noise scale factor getter.
Definition: ekf.cpp:850
unsigned int GetStateSize() const
Getter for state size.
Definition: ekf.cpp:190
void PredictModel(double local_time)
Predict state to given time using IMU measurements.
Definition: ekf.cpp:120
void Initialize(double initial_time, const BodyState &body_state_init)
EKF state initialization method.
Definition: ekf.cpp:245
GpsState GetGpsState(unsigned int gps_id)
Get GPS sensor state.
Definition: ekf.cpp:200
void RegisterFiducial(const FidState &fid_state, const Eigen::MatrixXd &covariance)
Fiducial Registration function.
Definition: ekf.cpp:356
void RegisterCamera(unsigned int cam_id, const CamState &cam_state, const Eigen::MatrixXd &covariance)
Camera Registration function.
Definition: ekf.cpp:317
std::vector< Eigen::Vector3d > GetGpsEcefVector() const
GPS ECEF vector getter.
Definition: ekf.cpp:806
unsigned int GetAugStateSize() const
Get augmented state size.
Definition: ekf.cpp:240
ImuState GetImuState(unsigned int imu_id)
Get IMU sensor state.
Definition: ekf.cpp:195
unsigned int GetGpsCount() const
IMU count getter method.
Definition: ekf.cpp:220
double GetReferenceAngle() const
Getter for the LLA reference frame heading.
Definition: ekf.cpp:660
bool GetUseFirstEstimateJacobian() const
Getter for use first estimate Jacobians.
Definition: ekf.cpp:860
void LogBodyStateIfNeeded(int execution_count)
Check if body data should be logged and do so if necessary.
Definition: ekf.cpp:97
unsigned int GetGpsStateStart() const
GPS state start getter.
Definition: ekf.cpp:820
double GetMotionDetectionChiSquared() const
Motion detection Chi squared threshold getter.
Definition: ekf.cpp:845
unsigned int GetImuStateStart() const
IMU state start getter.
Definition: ekf.cpp:815
void SetBodyProcessNoise(const Eigen::VectorXd &process_noise)
EKF process noise setter.
Definition: ekf.cpp:569
void RefreshIndices()
Refresh the sub-state indices.
Definition: ekf.cpp:680
unsigned int GetImuStateSize() const
IMU state size getter method.
Definition: ekf.cpp:215
EKF(Parameters params)
EKF class constructor.
Definition: ekf.cpp:37
void AttemptGpsInitialization(double time, const Eigen::Vector3d &gps_lla)
GPS LLA to ENU Initialization Routine.
Definition: ekf.cpp:759
Fiducial state structure.
Definition: types.hpp:318
GpsState structure.
Definition: types.hpp:178
ImuState structure.
Definition: types.hpp:114
EKF State Class.
Definition: types.hpp:363
EKF class parameters.
Definition: ekf.hpp:45
double gps_init_pos_thresh
Minimum ang projection error.
Definition: ekf.hpp:61
Eigen::VectorXd process_noise
Process noise.
Definition: ekf.hpp:54
AugmentationType augmenting_type
Augmenting type.
Definition: ekf.hpp:49
double augmenting_ang_error
Augmenting ang error.
Definition: ekf.hpp:52
double data_log_rate
Body data log rate.
Definition: ekf.hpp:47
std::shared_ptr< DebugLogger > debug_logger
Debug logger.
Definition: ekf.hpp:46
bool use_first_estimate_jacobian
Flag to use first estimate Jacobians.
Definition: ekf.hpp:66
Eigen::Quaterniond ang_b_to_l
Body local orientation.
Definition: ekf.hpp:56
double gps_init_baseline_dist
Minimum pos projection error.
Definition: ekf.hpp:60
double motion_detection_chi_squared
Motion detection chi squared threshold.
Definition: ekf.hpp:63
GpsInitType gps_init_type
GPS initialization type.
Definition: ekf.hpp:59
double imu_noise_scale_factor
Motion detection IMU noise scale factor.
Definition: ekf.hpp:64
double gps_init_ang_thresh
Baseline distance threshold.
Definition: ekf.hpp:62
double augmenting_pos_error
Augmenting pos error.
Definition: ekf.hpp:51
bool use_root_covariance
Flag to use the square-root form of Kalman filter.
Definition: ekf.hpp:65
Eigen::Vector3d pos_e_in_g
Local frame position.
Definition: ekf.hpp:57
std::string log_directory
Data log directory.
Definition: ekf.hpp:48
Eigen::Vector3d pos_b_in_l
Body local position.
Definition: ekf.hpp:55
double augmenting_delta_time
Augmenting time.
Definition: ekf.hpp:50
double ang_l_to_e
Local frame heading.
Definition: ekf.hpp:58