10 lpf_(
std::make_shared<
LowPassFilter>(params.pure_pursuit_lpf_alpha_, params.pure_pursuit_lpf_initial_value_)) {}
19 this->
absolute_velocity_ = std::sqrt(msg.velocity_x * msg.velocity_x + msg.velocity_y * msg.velocity_y);
29 double steering_command = 0.0;
35 this->params_->car_parameters_.dist_cg_2_rear_axis);
36 auto [closest_point, closest_point_id, closest_point_velocity] =
41 if (closest_point_id != -1) {
42 double ld = std::max(this->
params_->pure_pursuit_lookahead_gain_ * this->absolute_velocity_,
43 this->params_->pure_pursuit_lookahead_minimum_);
44 auto [lookahead_point, lookahead_velocity, lookahead_error] =
49 if (!lookahead_error) {
51 lookahead_point, this->
params_->car_parameters_.dist_cg_2_rear_axis);
56 return steering_command;
60 Position lookahead_point,
double dist_cg_2_rear_axis) {
61 double alpha =
calculate_alpha(rear_axis, cg, lookahead_point, dist_cg_2_rear_axis);
65 double steering_angle = std::atan(2 * this->
params_->car_parameters_.wheelbase * std::sin(alpha) / ld);
66 double filtered_steering_angle =
lpf_->filter(steering_angle);
68 return std::clamp(filtered_steering_angle, this->
params_->car_parameters_.steering_parameters.minimum_steering_angle,
69 this->params_->car_parameters_.steering_parameters.maximum_steering_angle);
73 Position lookahead_point,
double dist_cg_2_rear_axis) {
74 double lookhead_point_2_rear_wheel = vehicle_rear_wheel.
euclidean_distance(lookahead_point);
78 double cos_alpha = (std::pow(lookhead_point_2_rear_wheel, 2) + std::pow(dist_cg_2_rear_axis, 2) -
79 std::pow(lookhead_point_2_cg, 2)) /
80 (2 * lookhead_point_2_rear_wheel * dist_cg_2_rear_axis);
82 cos_alpha = std::clamp(cos_alpha, -1.0, 1.0);
83 double alpha = std::acos(cos_alpha);
85 if (
cross_product(vehicle_rear_wheel, vehicle_cg, lookahead_point) < 0) {
98 if (publisher_map.find(
"/pure_pursuit/closest_point") == publisher_map.end()) {
99 auto publisher = node->create_publisher<visualization_msgs::msg::Marker>(
"/pure_pursuit/closest_point", 10);
100 publisher_map[
"/pure_pursuit/closest_point"] = publisher;
103 auto publisher = std::static_pointer_cast<rclcpp::Publisher<visualization_msgs::msg::Marker>>(publisher_map[
"/pure_pursuit/closest_point"]);
105 "pure_pursuit", 0,
"blue");
106 publisher->publish(closest_marker);
110 if (publisher_map.find(
"/pure_pursuit/lookahead_point") == publisher_map.end()) {
111 auto publisher = node->create_publisher<visualization_msgs::msg::Marker>(
"/pure_pursuit/lookahead_point", 10);
112 publisher_map[
"/pure_pursuit/lookahead_point"] = publisher;
115 auto publisher = std::static_pointer_cast<rclcpp::Publisher<visualization_msgs::msg::Marker>>(publisher_map[
"/pure_pursuit/lookahead_point"]);
118 "pure_pursuit", 0,
"red");
119 publisher->publish(lookahead_marker);
Base (abstract) class for lateral control solvers (that calculate steering command)
std::shared_ptr< ControlParameters > params_
void publish_solver_data(std::shared_ptr< rclcpp::Node > node, std::map< std::string, std::shared_ptr< rclcpp::PublisherBase > > &publisher_map) override
Publishes solver specific data using the provided ControlNode.
bool received_first_state_
bool received_first_path_
void path_callback(const custom_interfaces::msg::PathPointArray &msg) override
Called when a new path is sent by Path Planning.
std::shared_ptr< Filter > lpf_
std::vector< custom_interfaces::msg::PathPoint > last_path_msg_
common_lib::structures::Position lookahead_point_
void vehicle_state_callback(const custom_interfaces::msg::Velocities &msg) override
Called when the car state (currently just velocity) is updated.
custom_interfaces::msg::Velocities last_velocity_msg_
custom_interfaces::msg::Pose last_pose_msg_
double absolute_velocity_
double get_steering_command() override
Returns the steering command calculated by the solver.
double pp_steering_control_law(common_lib::structures::Position rear_axis, common_lib::structures::Position cg, common_lib::structures::Position lookahead_point, double dist_cg_2_rear_axis)
Pure Pursuit control law.
void vehicle_pose_callback(const custom_interfaces::msg::Pose &msg) override
Called when the car pose is updated by SLAM.
double calculate_alpha(common_lib::structures::Position vehicle_rear_wheel, common_lib::structures::Position vehicle_cg, common_lib::structures::Position lookahead_point, double rear_wheel_2_c_g)
Calculate alpha (angle between the vehicle and lookahead point)
void publish_lookahead_point(std::shared_ptr< rclcpp::Node > node, std::map< std::string, std::shared_ptr< rclcpp::PublisherBase > > &publisher_map)
Function that publishes the lookahead point marker.
bool received_first_pose_
common_lib::structures::Position closest_point_
PurePursuit(const ControlParameters ¶ms)
Construct a new Pure Pursuit object.
void publish_closest_point(std::shared_ptr< rclcpp::Node > node, std::map< std::string, std::shared_ptr< rclcpp::PublisherBase > > &publisher_map)
Function that publishes the closest point marker.
std::tuple< common_lib::structures::Position, int, double > get_closest_point(const std::vector< custom_interfaces::msg::PathPoint > &pathpoint_array, const common_lib::structures::Position &position)
Find the closest point on the path.
common_lib::structures::Position rear_axis_position(const common_lib::structures::Position &cg, double orientation, double dist_cg_2_rear_axis)
Calculate rear axis coordinates.
std::tuple< common_lib::structures::Position, double, bool > get_lookahead_point(const std::vector< custom_interfaces::msg::PathPoint > &pathpoint_array, int closest_point_id, double lookahead_distance, common_lib::structures::Position rear_axis_position, double last_to_first_max_dist)
Update Lookahead point.
visualization_msgs::msg::Marker marker_from_position(const common_lib::structures::Position &position, const std::string &name_space, const int id, const std::string &color="red", float scale=0.5, const std::string &frame_id="map", const std::string &shape="sphere", int action=visualization_msgs::msg::Marker::ADD)
Converts a position to a marker.
double cross_product(const Position &p1, const Position &p2, const Position &p3)
Calculate the cross product of two vectors.
double euclidean_distance(const Position &other) const