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();
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();
106 
111  unsigned int GetImuStateSize();
112 
117  unsigned int GetGpsCount();
118 
123  unsigned int GetGpsStateSize();
124 
129  unsigned int GetCamStateSize();
130 
135  unsigned int GetCamCount();
136 
141  void LogBodyStateIfNeeded(int execution_count);
142 
147  void PredictModel(double local_time);
148 
154  Eigen::MatrixXd GetStateTransition(double dT);
155 
161  void Initialize(double timeInit, const BodyState & bodyStateInit);
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);
210 
214  void AugmentStateIfNeeded();
215 
221  void AugmentStateIfNeeded(unsigned int camera_id, 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();
253 
258  double GetReferenceAngle();
259 
264  bool IsLlaInitialized();
265 
270  bool IsGravityInitialized();
271 
275  void InitializeGravity();
276 
284  AugState GetAugState(unsigned int camera_id, int frame_id, double time);
285 
290  unsigned int GetAugStateSize();
291 
295  void RefreshIndices();
296 
303  double time,
304  Eigen::Vector3d gps_lla);
305 
310  std::vector<double> GetGpsTimeVector();
311 
316  std::vector<Eigen::Vector3d> GetGpsEcefVector();
317 
322  std::vector<Eigen::Vector3d> GetGpsXyzVector();
323 
328  double GetCurrentTime();
329 
334  unsigned int GetImuStateStart();
335 
340  unsigned int GetGpsStateStart();
341 
346  unsigned int GetCamStateStart();
347 
352  unsigned int GetAugStateStart();
353 
358  unsigned int GetFidStateStart();
359 
365 
370  double GetImuNoiseScaleFactor();
371 
376  bool GetUseRootCovariance();
377 
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:203
BodyState structure.
Definition: types.hpp:81
CamState structure.
Definition: types.hpp:226
DataLogger class.
Definition: data_logger.hpp:26
Calibration EKF class.
Definition: ekf.hpp:39
bool IsGravityInitialized()
Checks if the gravity angle has been initialized.
Definition: ekf.cpp:664
void SetZeroAcceleration(bool is_zero_acceleration)
Zero acceleration flag setter.
Definition: ekf.cpp:641
void SetMaxTrackLength(unsigned int max_track_length)
Setter for maximum track length.
Definition: ekf.cpp:628
unsigned int GetImuStateSize()
IMU state size getter method.
Definition: ekf.cpp:212
AugState GetAugState(unsigned int camera_id, int frame_id, double time)
Find or interpolate augmented state.
Definition: ekf.cpp:569
void SetGpsReference(const Eigen::VectorXd &pos_e_in_g, double ang_l_to_e)
GPS reference position setter.
Definition: ekf.cpp:634
State m_state
EKF state.
Definition: ekf.hpp:391
unsigned int GetGpsStateSize()
GPS state size getter method.
Definition: ekf.cpp:222
Eigen::MatrixXd GetStateTransition(double dT)
State transition matrix getter method.
Definition: ekf.cpp:93
void AttemptGpsInitialization(double time, Eigen::Vector3d gps_lla)
GPS LLA to ENU Initialization Routine.
Definition: ekf.cpp:753
Eigen::MatrixXd m_cov
EKF covariance.
Definition: ekf.hpp:394
void RegisterIMU(unsigned int imu_id, const ImuState &imu_state, const Eigen::MatrixXd &covariance)
IMU Registration function.
Definition: ekf.cpp:249
double GetImuNoiseScaleFactor()
IMU noise scale factor getter.
Definition: ekf.cpp:848
std::vector< double > GetGpsTimeVector()
GPS time vector getter.
Definition: ekf.cpp:800
CamState GetCamState(unsigned int cam_id)
Get camera sensor state.
Definition: ekf.cpp:202
void AugmentStateIfNeeded()
Check if state should be augmented using current state.
Definition: ekf.cpp:431
void RegisterGPS(unsigned int gps_id, const GpsState &gps_state, const Eigen::Matrix3d &covariance)
GPS Registration function.
Definition: ekf.cpp:285
struct EKF::Parameters Parameters
EKF class parameters.
unsigned int GetFidStateStart()
Fiducial state start getter.
Definition: ekf.cpp:833
unsigned int GetAugStateSize()
Get augmented state size.
Definition: ekf.cpp:237
Eigen::MatrixXd AugmentCovariance(const Eigen::MatrixXd &in_cov, unsigned int index)
Augment the state covariance matrix.
Definition: ekf.cpp:376
unsigned int GetImuCount()
IMU count getter method.
Definition: ekf.cpp:207
std::vector< Eigen::Vector3d > GetGpsEcefVector()
GPS ECEF vector getter.
Definition: ekf.cpp:804
bool GetUseFirstEstimateJacobian()
Getter for use first estimate Jacobians.
Definition: ekf.cpp:858
unsigned int GetGpsStateStart()
GPS state start getter.
Definition: ekf.cpp:818
double CalculateLocalTime(double time)
Calculate UTF time to local EKF time.
Definition: ekf.cpp:863
unsigned int GetImuStateStart()
IMU state start getter.
Definition: ekf.cpp:813
void InitializeGravity()
Function to initialize gravity angle.
Definition: ekf.cpp:669
double GetCurrentTime()
Current time getter.
Definition: ekf.cpp:838
unsigned int GetAugStateStart()
Augmented states start getter.
Definition: ekf.cpp:828
void PredictModel(double local_time)
Predict state to given time using IMU measurements.
Definition: ekf.cpp:124
unsigned int GetStateSize()
Getter for state size.
Definition: ekf.cpp:187
unsigned int GetCamCount()
Camera count getter method.
Definition: ekf.cpp:232
bool IsLlaInitialized()
Checks if the LLA reference frame has been initialized.
Definition: ekf.cpp:659
GpsState GetGpsState(unsigned int gps_id)
Get GPS sensor state.
Definition: ekf.cpp:197
void RegisterFiducial(const FidState &fid_state, const Eigen::MatrixXd &covariance)
Fiducial Registration function.
Definition: ekf.cpp:353
double GetReferenceAngle()
Getter for the LLA reference frame heading.
Definition: ekf.cpp:654
void RegisterCamera(unsigned int cam_id, const CamState &cam_state, const Eigen::MatrixXd &covariance)
Camera Registration function.
Definition: ekf.cpp:314
ImuState GetImuState(unsigned int imu_id)
Get IMU sensor state.
Definition: ekf.cpp:192
void LogBodyStateIfNeeded(int execution_count)
Check if body data should be logged and do so if necessary.
Definition: ekf.cpp:101
bool GetUseRootCovariance()
Getter for use root covariance flag.
Definition: ekf.cpp:853
unsigned int GetCamStateSize()
Camera state size getter method.
Definition: ekf.cpp:227
unsigned int GetCamStateStart()
Camera state start getter.
Definition: ekf.cpp:823
void Initialize(double timeInit, const BodyState &bodyStateInit)
EKF state initialization method.
Definition: ekf.cpp:242
void SetBodyProcessNoise(const Eigen::VectorXd &process_noise)
EKF process noise setter.
Definition: ekf.cpp:564
Eigen::VectorXd GetReferenceLLA()
Getter for the LLA reference position.
Definition: ekf.cpp:646
void RefreshIndices()
Refresh the sub-state indices.
Definition: ekf.cpp:674
double GetMotionDetectionChiSquared()
Motion detection Chi squared threshold getter.
Definition: ekf.cpp:843
unsigned int GetGpsCount()
IMU count getter method.
Definition: ekf.cpp:217
EKF(Parameters params)
EKF class constructor.
Definition: ekf.cpp:37
std::vector< Eigen::Vector3d > GetGpsXyzVector()
GPS XYZ vector getter.
Definition: ekf.cpp:808
Fiducial state structure.
Definition: types.hpp:303
GpsState structure.
Definition: types.hpp:168
ImuState structure.
Definition: types.hpp:114
EKF State Class.
Definition: types.hpp:343
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