Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
ekf.cpp
Go to the documentation of this file.
1#include "estimators/ekf.hpp"
2
22
24 this->imu_data_ = imu_data;
25 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "1 - State: %f %f %f", this->_state_(0),
26 this->_state_(1), this->_state_(2));
27 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "1 - Covariance: \n"
28 << this->_covariance_);
29 if (!this->imu_data_received_) {
30 this->imu_data_received_ = true;
31 } else {
32 this->predict(this->_state_, this->_covariance_, this->_process_noise_matrix_,
33 this->_last_update_, this->imu_data_);
34 }
35 this->_last_update_ = rclcpp::Clock().now();
36 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "2 - State: %f %f %f", this->_state_(0),
37 this->_state_(1), this->_state_(2));
38 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "2 - Covariance: \n"
39 << this->_covariance_);
40
41 this->correct_imu(this->_state_, this->_covariance_, this->imu_data_);
42 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "3 - State: %f %f %f", this->_state_(0),
43 this->_state_(1), this->_state_(2));
44 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "3 - Covariance: \n"
45 << this->_covariance_);
46}
47
49 this->wss_data_ = wss_data;
50 this->wss_data_received_ = true;
52 this->correct_wheels(this->_state_, this->_covariance_, this->wss_data_, this->motor_rpm_,
53 this->steering_angle_);
54 this->wss_data_received_ = false;
55 this->steering_angle_received_ = false;
56 this->motor_rpm_received_ = false;
57 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "3 - State: %f %f %f", this->_state_(0),
58 this->_state_(1), this->_state_(2));
59 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "3 - Covariance: \n"
60 << this->_covariance_);
61 }
62}
63
64void EKF::motor_rpm_callback(double motor_rpm) {
65 this->motor_rpm_ = motor_rpm;
66 this->motor_rpm_received_ = true;
68 this->correct_wheels(this->_state_, this->_covariance_, this->wss_data_, this->motor_rpm_,
69 this->steering_angle_);
70 this->wss_data_received_ = false;
71 this->steering_angle_received_ = false;
72 this->motor_rpm_received_ = false;
73 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "3 - State: %f %f %f", this->_state_(0),
74 this->_state_(1), this->_state_(2));
75 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "3 - Covariance: \n"
76 << this->_covariance_);
77 }
78}
79
80void EKF::steering_callback(double steering_angle) {
81 this->steering_angle_ = steering_angle;
82 this->steering_angle_received_ = true;
83 if (this->wss_data_received_ && this->motor_rpm_received_) {
84 this->correct_wheels(this->_state_, this->_covariance_, this->wss_data_, this->motor_rpm_,
85 this->steering_angle_);
86 this->wss_data_received_ = false;
87 this->steering_angle_received_ = false;
88 this->motor_rpm_received_ = false;
89 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"), "3 - State: %f %f %f", this->_state_(0),
90 this->_state_(1), this->_state_(2));
91 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "3 - Covariance: \n"
92 << this->_covariance_);
93 }
94}
95
98 velocities.velocity_x = this->_state_(0);
99 velocities.velocity_y = this->_state_(1);
100 velocities.rotational_velocity = this->_state_(2);
101 velocities.timestamp_ = rclcpp::Clock().now();
102 velocities.velocity_x_noise_ = this->_covariance_(0, 0);
103 velocities.velocity_y_noise_ = this->_covariance_(1, 1);
104 velocities.rotational_velocity_noise_ = this->_covariance_(2, 2);
105 return velocities;
106}
107
108void EKF::predict(Eigen::Vector3d& state, Eigen::Matrix3d& covariance,
109 const Eigen::Matrix3d& process_noise_matrix, const rclcpp::Time last_update,
111 rclcpp::Time current_time_point =
112 rclcpp::Clock().now(); // TODO: change calculation to use message timestamps
113 double dt = (current_time_point - last_update).seconds();
114 Eigen::Vector3d accelerations(imu_data.acceleration_x, imu_data.acceleration_y, 0.0);
115
116 // Process noise for angular velocity greater, the greater the angular velocity
117 Eigen::Matrix3d actual_process_noise_matrix = process_noise_matrix;
118 // actual_process_noise_matrix(2, 2) += process_noise_matrix(0, 0) * state(2) * dt * 1000.0;
119
120 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"),
121 "predict - Process noise matrix: \n"
122 << actual_process_noise_matrix);
123
124 Eigen::Matrix3d jacobian = this->process_model->get_jacobian_velocities(state, accelerations, dt);
125 covariance = jacobian * covariance * jacobian.transpose() + actual_process_noise_matrix;
126 state = this->process_model->get_next_velocities(state, accelerations, dt);
127 this->_has_made_prediction_ = true;
128}
129
130void EKF::correct_wheels(Eigen::Vector3d& state, Eigen::Matrix3d& covariance,
131 common_lib::sensor_data::WheelEncoderData& wss_data, double motor_rpm,
132 double steering_angle) {
133 Eigen::VectorXd predicted_observations = this->observation_model_->expected_observations(state);
134 Eigen::VectorXd observations = Eigen::VectorXd::Zero(6);
135 observations << wss_data.fl_rpm, wss_data.fr_rpm, wss_data.rl_rpm, wss_data.rr_rpm,
136 steering_angle, motor_rpm;
137 Eigen::VectorXd y = observations - predicted_observations;
138 Eigen::MatrixXd jacobian = this->observation_model_->expected_observations_jacobian(state);
139 Eigen::MatrixXd kalman_gain =
140 covariance * jacobian.transpose() *
141 (jacobian * covariance * jacobian.transpose() + this->_wheels_measurement_noise_matrix_)
142 .inverse();
143
144 // DEBUG PRINTS
145 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"),
146 "correct_wheels - Predicted observations: %f %f %f %f %f %f",
147 predicted_observations(0), predicted_observations(1), predicted_observations(2),
148 predicted_observations(3), predicted_observations(4), predicted_observations(5));
149 RCLCPP_DEBUG(rclcpp::get_logger("velocity_estimation"),
150 "correct_wheels - Observations: %f %f %f %f %f %f", observations(0), observations(1),
151 observations(2), observations(3), observations(4), observations(5));
152 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_wheels - Covariance: \n"
153 << covariance);
154 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_wheels - y: \n" << y);
155 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_wheels - Jacobian: \n"
156 << jacobian);
157 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_wheels - Kalman gain: \n"
158 << kalman_gain);
159 state += kalman_gain * y;
160 if (this->_has_made_prediction_)
161 covariance = (Eigen::Matrix3d::Identity() - kalman_gain * jacobian) * covariance;
162}
163
164void EKF::correct_imu(Eigen::Vector3d& state, Eigen::Matrix3d& covariance,
166 Eigen::VectorXd y = Eigen::VectorXd(1);
167 y(0) = imu_data.rotational_velocity - state(2);
168 Eigen::MatrixXd jacobian = Eigen::MatrixXd(1, 3);
169 jacobian(0, 0) = 0;
170 jacobian(0, 1) = 0;
171 jacobian(0, 2) = 1;
172 Eigen::MatrixXd kalman_gain =
173 covariance * jacobian.transpose() *
174 (jacobian * covariance * jacobian.transpose() + this->_imu_measurement_noise_matrix_)
175 .inverse();
176
177 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_imu - Covariance: \n"
178 << covariance);
179 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_imu - y: \n" << y);
180 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_imu - Jacobian: \n"
181 << jacobian);
182 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("velocity_estimation"), "correct_imu - Kalman gain: \n"
183 << kalman_gain);
184 state += kalman_gain * y;
185 if (this->_has_made_prediction_)
186 covariance = (Eigen::Matrix3d::Identity() - kalman_gain * jacobian) * covariance;
187}
common_lib::car_parameters::CarParameters car_parameters_
Definition ekf.hpp:40
Eigen::Vector3d _state_
Definition ekf.hpp:19
void correct_wheels(Eigen::Vector3d &state, Eigen::Matrix3d &covariance, common_lib::sensor_data::WheelEncoderData &wss_data, double motor_rpm, double steering_angle)
Correct the state estimate based on wheel speed sensor, resolver, and steering data.
Definition ekf.cpp:130
void motor_rpm_callback(double motor_rpm) override
Callback function for the motor RPM data that should be called by adapters when new motor RPM data is...
Definition ekf.cpp:64
bool wss_data_received_
Definition ekf.hpp:36
double steering_angle_
Definition ekf.hpp:28
Eigen::Matrix3d _covariance_
Definition ekf.hpp:20
Eigen::MatrixXd _wheels_measurement_noise_matrix_
Definition ekf.hpp:22
bool motor_rpm_received_
Definition ekf.hpp:37
bool _has_made_prediction_
Definition ekf.hpp:30
void predict(Eigen::Vector3d &state, Eigen::Matrix3d &covariance, const Eigen::Matrix3d &process_noise_matrix, const rclcpp::Time last_update, common_lib::sensor_data::ImuData &imu_data)
Predict velocities at the next index based on IMU measurements and current state.
Definition ekf.cpp:108
std::shared_ptr< BaseVelocityProcessModel > process_model
Definition ekf.hpp:42
double motor_rpm_
Definition ekf.hpp:27
common_lib::structures::Velocities get_velocities() override
Definition ekf.cpp:96
bool imu_data_received_
Definition ekf.hpp:35
EKF(const VEParameters &params)
Definition ekf.cpp:3
void correct_imu(Eigen::Vector3d &state, Eigen::Matrix3d &covariance, common_lib::sensor_data::ImuData &imu_data)
Definition ekf.cpp:164
void imu_callback(const common_lib::sensor_data::ImuData &imu_data) override
Callback function for the IMU data that should be called by adapters when new IMU data is available.
Definition ekf.cpp:23
std::shared_ptr< VEObservationModel > observation_model_
Definition ekf.hpp:41
Eigen::Matrix3d _process_noise_matrix_
Definition ekf.hpp:21
rclcpp::Time _last_update_
Definition ekf.hpp:18
void steering_callback(double steering_angle) override
Callback function for the steering angle data that should be called by adapters when new steering ang...
Definition ekf.cpp:80
bool steering_angle_received_
Definition ekf.hpp:38
void wss_callback(const common_lib::sensor_data::WheelEncoderData &wss_data) override
Callback function for the wheel speed sensor data that should be called by adapters when new wheel sp...
Definition ekf.cpp:48
Eigen::MatrixXd _imu_measurement_noise_matrix_
Definition ekf.hpp:23
common_lib::sensor_data::WheelEncoderData wss_data_
Definition ekf.hpp:26
common_lib::sensor_data::ImuData imu_data_
Definition ekf.hpp:25
const std::map< std::string, std::function< std::shared_ptr< BaseVelocityProcessModel >()>, std::less<> > vel_process_models_map
Definition map.hpp:15
const std::map< std::string, std::function< std::shared_ptr< VEObservationModel >(const common_lib::car_parameters::CarParameters &)>, std::less<> > ve_observation_models_map
Definition map.hpp:18
double wheel_speed_noise_
std::string _ve_observation_model_name_
double motor_rpm_noise_
double imu_acceleration_noise_
double imu_rotational_noise_
double angular_velocity_process_noise_
std::string _process_model_name_
double steering_angle_noise_
common_lib::car_parameters::CarParameters car_parameters_