Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
base_pose_updater.cpp
Go to the documentation of this file.
2
4
6 : _pose_buffer_(params.max_pose_history_updater) {
7 _last_pose_ = Eigen::Vector3d::Zero();
8 _last_graphed_pose_ = Eigen::Vector3d::Zero();
9 _last_pose_covariance_ = Eigen::Matrix3d::Zero();
10 _last_pose_update_ = rclcpp::Time(0);
12}
13
22
36
38
39std::shared_ptr<PoseUpdater> PoseUpdater::clone() const {
40 return std::make_shared<PoseUpdater>(*this);
41}
42
43Eigen::Vector3d PoseUpdater::get_pose_at_timestamp(const rclcpp::Time& timestamp) const {
44 if (_pose_buffer_.size() == 0) throw std::out_of_range("Pose buffer is empty");
45
46 for (size_t i = 0; i < _pose_buffer_.size(); i++) {
47 const auto& curr = _pose_buffer_.from_end(i);
48 if (curr.timestamp.seconds() <= timestamp.seconds()) {
49 if (i == 0) return curr.pose;
50 const auto& prev = _pose_buffer_.from_end(i - 1);
51 auto diff_curr = timestamp.seconds() - curr.timestamp.seconds();
52 auto diff_prev = prev.timestamp.seconds() - timestamp.seconds();
53 return (diff_curr < diff_prev) ? curr.pose : prev.pose;
54 }
55 }
56
57 return _pose_buffer_.from_end(_pose_buffer_.size() - 1).pose;
58}
59
60void PoseUpdater::update_pose(const Eigen::Vector3d& last_pose) {
61 this->_last_pose_ = last_pose;
62 this->_last_graphed_pose_ = last_pose;
63 this->_last_pose_covariance_ = Eigen::Matrix3d::Zero();
64
65 _pose_buffer_.clear(); // Clear the buffer so that old not optimized poses are not kept
67
68 this->_new_pose_from_graph_ = false; // Reset the flag for new pose from graph
69}
70
71void PoseUpdater::predict_pose(const MotionData& motion_data,
72 std::shared_ptr<V2PMotionModel> motion_model) {
74 this->_last_pose_ = Eigen::Vector3d::Zero();
75 this->_last_pose_update_ = motion_data.timestamp_;
78 return;
79 }
80
81 double delta = (motion_data.timestamp_ - this->_last_pose_update_).seconds();
82 RCLCPP_DEBUG(rclcpp::get_logger("slam"), "Delta time: %f", delta);
83 Eigen::Vector3d new_pose =
84 motion_model->get_next_pose(this->_last_pose_, *(motion_data.motion_data_), delta);
85 Eigen::MatrixXd jacobian_motion_data =
86 motion_model->get_jacobian_motion_data(this->_last_pose_, *(motion_data.motion_data_), delta);
87 Eigen::MatrixXd motion_noise = jacobian_motion_data *
88 motion_data.motion_data_noise_->asDiagonal() *
89 jacobian_motion_data.transpose();
90 Eigen::Vector3d pose_difference = pose_difference_eigen(this->_last_pose_, new_pose);
91 Eigen::Matrix3d adjoint_matrix =
92 this->get_adjoint_operator_matrix(pose_difference(0), pose_difference(1), pose_difference(2));
93
94 this->_last_pose_ = new_pose;
95 this->_last_pose_update_ = motion_data.timestamp_;
97 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Last Pose Covariance: \n"
98 // << this->_last_pose_covariance_);
100 adjoint_matrix * this->_last_pose_covariance_ * adjoint_matrix.transpose() +
101 motion_noise; // TODO: to improve further, consider including a noise for the intrinsic
102 // error of the motion model
103 this->_last_pose_update_ = motion_data.timestamp_;
104 this->_new_pose_from_graph_ = true;
105 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Transposed Jacobian Motion Data: \n"
106 // << jacobian_motion_data.transpose());
107 // RCLCPP_DEBUG_STREAM(
108 // rclcpp::get_logger("slam"),
109 // "Motion Data Noise Diagonal: \n"
110 // << static_cast<Eigen::Vector3d>(motion_data.motion_data_noise_->asDiagonal()));
111 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Adjoint Matrix: \n" << adjoint_matrix);
112 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Motion Noise: \n" << motion_noise);
113 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Jacobian Motion Data: \n"
114 // << jacobian_motion_data);
115 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("slam"), "Pose Difference Covariance: \n"
116 // << this->_last_pose_covariance_);
117}
118
120
121Eigen::Matrix3d PoseUpdater::get_adjoint_operator_matrix(const double x_translation,
122 const double y_translation,
123 const double rotation_angle) const {
124 Eigen::Matrix3d adjoint_matrix = Eigen::Matrix3d::Zero();
125 adjoint_matrix(0, 0) = cos(rotation_angle);
126 adjoint_matrix(0, 1) = -sin(rotation_angle);
127 adjoint_matrix(0, 2) = y_translation;
128 adjoint_matrix(1, 0) = sin(rotation_angle);
129 adjoint_matrix(1, 1) = cos(rotation_angle);
130 adjoint_matrix(1, 2) = -x_translation;
131 adjoint_matrix(2, 2) = 1.0;
132 return adjoint_matrix;
133}
Class to update the pose of the vehicle.
CircularBuffer< TimedPose > _pose_buffer_
Eigen::Matrix3d get_adjoint_operator_matrix(double x_translation, double y_translation, double rotation_angle) const
Eigen::Vector3d get_pose_at_timestamp(const rclcpp::Time &timestamp) const
virtual void update_pose(const Eigen::Vector3d &last_pose)
Updates the last pose with the given pose.
Eigen::Vector3d _last_graphed_pose_
Eigen::Matrix3d _last_pose_covariance_
PoseUpdater(const SLAMParameters &params)
PoseUpdater & operator=(const PoseUpdater &other)
bool _received_first_motion_data_
virtual void predict_pose(const MotionData &motion_data, std::shared_ptr< V2PMotionModel > motion_model)
Updates the last pose and returns the pose difference.
virtual bool pose_ready_for_graph_update() const
Check if the pose is ready for graph update.
virtual std::shared_ptr< PoseUpdater > clone() const
Class to update the pose of the vehicle.
rclcpp::Time _last_pose_update_
Eigen::Vector3d _last_pose_
virtual ~PoseUpdater()
Eigen::Vector3d pose_difference_eigen(const Eigen::Vector3d &pose1, const Eigen::Vector3d &pose2)
Definition utils.cpp:11
Data structure to hold motion data.
rclcpp::Time timestamp_
std::shared_ptr< Eigen::VectorXd > motion_data_
std::shared_ptr< Eigen::VectorXd > motion_data_noise_
Parameters for the SLAM node.