3#include <yaml-cpp/yaml.h>
16#include "geometry_msgs/msg/pose_with_covariance.hpp"
17#include "rclcpp/rclcpp.hpp"
18#include "visualization_msgs/msg/marker.hpp"
19#include "utils/utils.hpp"
25 auto global_config_path =
27 auto global_config = YAML::LoadFile(global_config_path);
30 _adapter_name_ = global_config[
"global"][
"adapter"].as<std::string>();
35 auto se_config = YAML::LoadFile(se_config_path)[
"ekf_state_est"];
36 RCLCPP_DEBUG(rclcpp::get_logger(
"ekf_state_est"),
"SE config contents: %s",
37 YAML::Dump(se_config).c_str());
40 std::string motion_model_name = se_config[
"motion_model"].as<std::string>();
41 std::string data_assocation_model_name = se_config[
"data_association_model"].as<std::string>();
43 float wss_noise = 0.0f;
44 float imu_noise = 0.0f;
45 if (data_assocation_model_name ==
"max_likelihood") {
46 wss_noise = se_config[
"wss_noise"].as<
float>();
47 imu_noise = se_config[
"imu_noise"].as<
float>();
49 float data_association_limit_distance = se_config[
"data_association_limit_distance"].as<
float>();
50 float observation_noise = se_config[
"observation_noise"].as<
float>();
57 std::shared_ptr<ObservationModel> observation_model = std::make_shared<ObservationModel>(
59 std::shared_ptr<DataAssociationModel> data_association_model =
61 data_association_limit_distance);
62 _ekf_ = std::make_shared<ExtendedKalmanFilter>(observation_model, data_association_model);
63 _ekf_->add_motion_model(
"wheel_speed_sensor", motion_model_wss);
64 _ekf_->add_motion_model(
"imu", motion_model_imu);
65 _perception_map_ = std::make_shared<std::vector<common_lib::structures::Cone>>();
67 _track_map_ = std::make_shared<std::vector<common_lib::structures::Cone>>();
68 _vehicle_state_ = std::make_shared<common_lib::structures::VehicleState>();
73 "/perception/cones", 1,
77 "/state_estimation/vehicle_state", 10);
79 this->create_publisher<custom_interfaces::msg::VehicleState>(
80 "/state_estimation/vehicle_state/wss", 10);
82 this->create_publisher<custom_interfaces::msg::VehicleState>(
83 "/state_estimation/vehicle_state/imu", 10);
85 this->create_publisher<custom_interfaces::msg::ConeArray>(
"/state_estimation/map", 10);
87 this->create_publisher<visualization_msgs::msg::MarkerArray>(
88 "/state_estimation/visualization_map", 10);
90 "/state_estimation/execution_time/correction_step", 10);
92 "/state_estimation/execution_time/prediction_step", 10);
96 "/state_estimation/visualization/position", 10);
98 "/state_estimation/visualization/car_model", 10);
104 auto const &cone_array = msg.cone_array;
106 RCLCPP_WARN(this->get_logger(),
"SUB - Perception map is null");
114 rclcpp::Time start_time = this->get_clock()->now();
118 for (
auto &cone : cone_array) {
120 cone.color, cone.confidence));
123 if (this->
_ekf_ ==
nullptr) {
124 RCLCPP_WARN(this->get_logger(),
"ATTR - EKF object is null");
131 rclcpp::Time end_time = this->get_clock()->now();
134 std_msgs::msg::Float64 correction_execution_time;
135 correction_execution_time.data = (end_time - start_time).seconds() * 1000.0;
150 rclcpp::Time start_time = this->get_clock()->now();
152 double ax = imu_msg.linear_acceleration.x;
155 double v_rot = imu_msg.angular_velocity.z;
157 double angle = this->
_ekf_->get_state()(2);
159 double ax_map = ax * cos(angle) ;
160 double ay_map = ax * sin(angle) ;
170 if (this->
_ekf_ ==
nullptr) {
171 RCLCPP_ERROR(this->get_logger(),
"ATTR - EKF object is null");
175 this->
_ekf_->prediction_step(temp_update,
"imu");
179 rclcpp::Time end_time = this->get_clock()->now();
180 std_msgs::msg::Float64 prediction_execution_time;
181 prediction_execution_time.data = (end_time - start_time).seconds() * 1000.0;
192 double fr_speed,
double steering_angle,
193 const rclcpp::Time ×tamp) {
211 RCLCPP_INFO(this->get_logger(),
"Rear Left: %f\n Rear Right: %f", rl_speed, rr_speed);
212 rclcpp::Time start_time = this->get_clock()->now();
214 auto [linear_velocity, angular_velocity] =
217 RCLCPP_INFO(this->get_logger(),
"Linear Velocity: %f\nAngular Velocity: %f", linear_velocity,
229 if (this->
_ekf_ ==
nullptr) {
230 RCLCPP_ERROR(this->get_logger(),
"ATTR - EKF object is null");
235 RCLCPP_INFO(this->get_logger(),
"Motion update Translational Velocity: %f",
238 this->
_ekf_->prediction_step(temp_update,
"wheel_speed_sensor");
242 rclcpp::Time end_time = this->get_clock()->now();
243 std_msgs::msg::Float64 prediction_execution_time;
244 prediction_execution_time.data = (end_time - start_time).seconds() * 1000.0;
254 RCLCPP_WARN(this->get_logger(),
"PUB - Vehicle state object is null");
261 auto message = custom_interfaces::msg::VehicleState();
267 message.linear_velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y);
269 message.header.stamp = this->get_clock()->now();
271 RCLCPP_DEBUG(this->get_logger(),
"PUB - Pose: (%f, %f, %f); Velocities: (%f, %f)",
272 message.position.x, message.position.y, message.theta, message.linear_velocity,
273 message.angular_velocity);
279 RCLCPP_WARN(this->get_logger(),
"PUB - Vehicle state object is null");
282 auto message = custom_interfaces::msg::VehicleState();
288 message.linear_velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y);
290 message.header.stamp = this->get_clock()->now();
292 RCLCPP_DEBUG(this->get_logger(),
"PUB - Pose: (%f, %f, %f); Velocities: (%f, %f)",
293 message.position.x, message.position.y, message.theta, message.linear_velocity,
294 message.angular_velocity);
297 auto marker = visualization_msgs::msg::Marker();
298 marker.header.frame_id =
"map";
299 marker.header.stamp = this->get_clock()->now();
300 marker.ns =
"vehicle_state";
302 marker.type = visualization_msgs::msg::Marker::SPHERE;
303 marker.action = visualization_msgs::msg::Marker::ADD;
306 marker.pose.position.z = 0.0;
307 marker.pose.orientation.w = 1.0;
308 marker.scale.x = 0.5;
309 marker.scale.y = 0.5;
310 marker.scale.z = 0.5;
311 marker.color.r = 0.0;
312 marker.color.g = 1.0;
313 marker.color.b = 0.0;
314 marker.color.a = 1.0;
316 RCLCPP_DEBUG(this->get_logger(),
"PUB - Marker at position: (%f, %f)", marker.pose.position.x,
317 marker.pose.position.y);
324 double cos_theta = std::cos(theta);
325 double sin_theta = std::sin(theta);
327 geometry_msgs::msg::Point rear_axis;
328 rear_axis.x = message.position.x - lr * cos_theta;
329 rear_axis.y = message.position.y - lr * sin_theta;
331 geometry_msgs::msg::Point front_axis;
332 front_axis.x = message.position.x + lf * cos_theta;
333 front_axis.y = message.position.y + lf * sin_theta;
336 visualization_msgs::msg::Marker line_marker;
337 line_marker.header.frame_id =
"map";
338 line_marker.header.stamp = this->get_clock()->now();
339 line_marker.ns =
"vehicle_state";
341 line_marker.type = visualization_msgs::msg::Marker::LINE_STRIP;
342 line_marker.action = visualization_msgs::msg::Marker::ADD;
343 line_marker.scale.x = 0.1;
344 line_marker.color.r = 1.0;
345 line_marker.color.g = 1.0;
346 line_marker.color.b = 0.0;
347 line_marker.color.a = 1.0;
350 line_marker.points.push_back(rear_axis);
351 line_marker.points.push_back(front_axis);
359 RCLCPP_WARN(this->get_logger(),
"PUB - Vehicle state object is null");
362 auto message = custom_interfaces::msg::VehicleState();
368 message.linear_velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y);
370 message.header.stamp = this->get_clock()->now();
372 RCLCPP_DEBUG(this->get_logger(),
"PUB - Pose: (%f, %f, %f); Velocities: (%f, %f)",
373 message.position.x, message.position.y, message.theta, message.linear_velocity,
374 message.angular_velocity);
379 auto cone_array_msg = custom_interfaces::msg::ConeArray();
380 auto marker_array_msg = visualization_msgs::msg::MarkerArray();
381 RCLCPP_DEBUG(this->get_logger(),
"PUB - cone map:");
382 RCLCPP_DEBUG(this->get_logger(),
"--------------------------------------");
384 auto cone_message = custom_interfaces::msg::Cone();
385 cone_message.position.x = cone.position.x;
386 cone_message.position.y = cone.position.y;
388 cone_array_msg.cone_array.push_back(cone_message);
389 RCLCPP_DEBUG(this->get_logger(),
"(%f\t%f)\t%s", cone_message.position.x,
390 cone_message.position.y, cone_message.color.c_str());
392 RCLCPP_DEBUG(this->get_logger(),
"--------------------------------------");
393 cone_array_msg.header.stamp = this->get_clock()->now();
404 if (this->
_ekf_ ==
nullptr) {
405 RCLCPP_WARN(this->get_logger(),
"PUB - EKF object is null");
409 this->
_ekf_->prediction_step(temp_update,
"wheel_speed_sensor");
412 RCLCPP_DEBUG(this->get_logger(),
"EKF - EFK Step");
static Eigen::MatrixXf create_process_noise_covariance_matrix(float process_noise)
static Eigen::MatrixXf create_observation_noise_covariance_matrix(float noise_value)
Create a Q matrix from a given noise value.
bool _use_simulated_perception_
rclcpp::Subscription< custom_interfaces::msg::ConeArray >::SharedPtr _perception_subscription_
void _publish_vehicle_state_wss()
publishes the localization ('vehicle_localization') to the topic vehicle_location
rclcpp::Publisher< visualization_msgs::msg::Marker >::SharedPtr _car_model_publisher_
std::shared_ptr< common_lib::car_parameters::CarParameters > _car_parameters_
Mutex used to lock EKF access.
std::shared_ptr< ExtendedKalmanFilter > _ekf_
SLAM EKF object.
std::shared_ptr< std::vector< common_lib::structures::Cone > > _perception_map_
rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr _visualization_map_publisher_
std::shared_ptr< std::vector< common_lib::structures::Cone > > _track_map_
void _ekf_step()
executes the prediction step of the EKF
std::string _adapter_name_
rclcpp::Publisher< custom_interfaces::msg::VehicleState >::SharedPtr _vehicle_state_publisher_wss_
void _wheel_speeds_subscription_callback(double rl_speed, double rr_speed, double fl_speed, double fr_speed, double steering_angle, const rclcpp::Time ×tamp)
Function to be called everytime information is received from the wheel encoders.
SENode()
Constructor of the main node, most things are received by launch parameter.
rclcpp::Publisher< std_msgs::msg::Float64 >::SharedPtr _prediction_execution_time_publisher_
rclcpp::Publisher< custom_interfaces::msg::ConeArray >::SharedPtr _map_publisher_
void _imu_subscription_callback(const sensor_msgs::msg::Imu &imu_msg)
Function to be called everytime information is received from the IMU.
void _publish_map()
publishes the map ('track_map') to the topic track_map
void _publish_vehicle_state_imu()
publishes the localization ('vehicle_localization') to the topic vehicle_location
std::shared_ptr< MotionUpdate > _motion_update_
void _update_and_publish()
Executes:
void _publish_vehicle_state()
publishes the localization ('vehicle_localization') to the topic vehicle_location
std::shared_ptr< Adapter > _adapter_
rclcpp::Publisher< custom_interfaces::msg::VehicleState >::SharedPtr _vehicle_state_publisher_
rclcpp::Publisher< visualization_msgs::msg::Marker >::SharedPtr _position_publisher_
std::shared_ptr< common_lib::structures::VehicleState > _vehicle_state_
rclcpp::Publisher< std_msgs::msg::Float64 >::SharedPtr _correction_execution_time_publisher_
void _perception_subscription_callback(const custom_interfaces::msg::ConeArray &msg)
Callback that updates everytime information is received from the perception module.
rclcpp::Publisher< custom_interfaces::msg::VehicleState >::SharedPtr _vehicle_state_publisher_imu_
bool _use_odometry_
flag to start the mission
const std::map< std::string, std::function< std::shared_ptr< ControlNode >(const ControlParameters &)>, std::less<> > adapter_map
const std::map< std::string, std::function< std::shared_ptr< DataAssociationModel >(float max_landmark_distance)>, std::less<> > data_association_model_constructors
std::pair< double, double > wheels_velocities_to_cg(std::shared_ptr< common_lib::car_parameters::CarParameters > car_parameters, double rl_rpm, double fl_rpm, double rr_rpm, double fr_rpm, double steering_angle)
Calculates the translational and rotational velocities of the vehicle from wheel rotations and steeri...
const std::map< std::string, std::function< std::shared_ptr< MotionModel >(const Eigen::MatrixXf &)>, std::less<> > motion_model_constructors
Map object to map strings from launch file parameter to constructor.
visualization_msgs::msg::MarkerArray marker_array_from_structure_array(const std::vector< T > &structure_array, const std::string &name_space, const std::string &frame_id, const std::string &color="red", const std::string &shape="cylinder", float scale=0.5, int action=visualization_msgs::msg::Marker::MODIFY)
Converts a vector of cones to a marker array.
std::string get_color_string(int color)
std::string get_config_yaml_path(const std::string &package_name, const std::string &dir, const std::string &filename)
Struct for data retrieved by the IMU.
double rotational_velocity
Degrees per sec.
double translational_velocity
Meters per sec.
double acceleration_x
Meters per sec.
double acceleration_y
Meters per sec.