Carma-platform v4.11.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
pure_pursuit_wrapper.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2022 LEIDOS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
18#include <trajectory_utils/conversions/conversions.hpp>
19#include <carma_wm/Geometry.hpp>
20#include <algorithm>
22
23
25{
26namespace std_ph = std::placeholders;
27
28PurePursuitWrapperNode::PurePursuitWrapperNode(const rclcpp::NodeOptions& options)
29 : carma_guidance_plugins::ControlPlugin(options)
30{
31 basic_autonomy::set_logger(get_logger().get_child("basic_autonomy"));
33 config_.vehicle_response_lag = declare_parameter<double>("vehicle_response_lag", config_.vehicle_response_lag);
34 config_.minimum_lookahead_distance = declare_parameter<double>("minimum_lookahead_distance", config_.minimum_lookahead_distance);
35 config_.maximum_lookahead_distance = declare_parameter<double>("maximum_lookahead_distance", config_.maximum_lookahead_distance);
36 config_.speed_to_lookahead_ratio = declare_parameter<double>("speed_to_lookahead_ratio", config_.speed_to_lookahead_ratio);
37 config_.is_interpolate_lookahead_point = declare_parameter<bool>("is_interpolate_lookahead_point", config_.is_interpolate_lookahead_point);
38 config_.is_delay_compensation = declare_parameter<bool>("is_delay_compensation", config_.is_delay_compensation);
39 config_.emergency_stop_distance = declare_parameter<double>("emergency_stop_distance", config_.emergency_stop_distance);
40 config_.speed_thres_traveling_direction = declare_parameter<double>("speed_thres_traveling_direction", config_.speed_thres_traveling_direction);
41 config_.dist_front_rear_wheels = declare_parameter<double>("dist_front_rear_wheels", config_.dist_front_rear_wheels);
42
43 // integrator part
44 config_.dt = declare_parameter<double>("dt", config_.dt);
45 config_.integrator_max_pp = declare_parameter<double>("integrator_max_pp", config_.integrator_max_pp);
46 config_.integrator_min_pp = declare_parameter<double>("integrator_min_pp", config_.integrator_min_pp);
47 config_.Ki_pp = declare_parameter<double>("Ki_pp", config_.Ki_pp);
48 config_.is_integrator_enabled = declare_parameter<bool>("is_integrator_enabled", config_.is_integrator_enabled);
49}
50
51carma_ros2_utils::CallbackReturn PurePursuitWrapperNode::on_configure_plugin()
52{
54 get_parameter<double>("vehicle_response_lag", config_.vehicle_response_lag);
55 get_parameter<double>("minimum_lookahead_distance", config_.minimum_lookahead_distance);
56 get_parameter<double>("maximum_lookahead_distance", config_.maximum_lookahead_distance);
57 get_parameter<double>("speed_to_lookahead_ratio", config_.speed_to_lookahead_ratio);
58 get_parameter<bool>("is_interpolate_lookahead_point", config_.is_interpolate_lookahead_point);
59 get_parameter<bool>("is_delay_compensation", config_.is_delay_compensation);
60 get_parameter<double>("emergency_stop_distance", config_.emergency_stop_distance);
61 get_parameter<double>("speed_thres_traveling_direction", config_.speed_thres_traveling_direction);
62 get_parameter<double>("dist_front_rear_wheels", config_.dist_front_rear_wheels);
63
64 // integrator configs
65 get_parameter<double>("dt", config_.dt);
66 get_parameter<double>("integrator_max_pp", config_.integrator_max_pp);
67 get_parameter<double>("integrator_min_pp", config_.integrator_min_pp);
68 get_parameter<double>("Ki_pp", config_.Ki_pp);
69 get_parameter<bool>("is_integrator_enabled", config_.is_integrator_enabled);
70
71 RCLCPP_INFO_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "Loaded Params: " << config_);
72
73 // Register runtime parameter update callback
74 add_on_set_parameters_callback(std::bind(&PurePursuitWrapperNode::parameter_update_callback, this, std_ph::_1));
75
76 // create config for pure_pursuit worker
77 pure_pursuit::Config cfg{
86 };
87
88 pure_pursuit::IntegratorConfig i_cfg;
89 i_cfg.dt = config_.dt;
90 i_cfg.integrator_max_pp = config_.integrator_max_pp;
91 i_cfg.integrator_min_pp = config_.integrator_min_pp;
92 i_cfg.Ki_pp = config_.Ki_pp;
93 i_cfg.integral = 0.0; // accumulator of integral starts from 0
94 i_cfg.is_integrator_enabled = config_.is_integrator_enabled;
95
96 pp_ = std::make_shared<pure_pursuit::PurePursuit>(cfg, i_cfg);
97
98 // Return success if everything initialized successfully
99 return CallbackReturn::SUCCESS;
100}
101
102motion::motion_common::State PurePursuitWrapperNode::convert_state(geometry_msgs::msg::PoseStamped pose, geometry_msgs::msg::TwistStamped twist)
103{
104 motion::motion_common::State state;
105 state.header = pose.header;
106 state.state.x = pose.pose.position.x;
107 state.state.y = pose.pose.position.y;
108 state.state.z = pose.pose.position.z;
109 state.state.heading.real = pose.pose.orientation.w;
110 state.state.heading.imag = pose.pose.orientation.z;
111
112 state.state.longitudinal_velocity_mps = twist.twist.linear.x;
113 return state;
114}
115
116autoware_msgs::msg::ControlCommandStamped PurePursuitWrapperNode::convert_cmd(motion::motion_common::Command cmd)
117{
118 autoware_msgs::msg::ControlCommandStamped return_cmd;
119 return_cmd.header.stamp = cmd.stamp;
120
121 return_cmd.cmd.linear_acceleration = cmd.long_accel_mps2;
122 return_cmd.cmd.linear_velocity = cmd.velocity_mps;
123 return_cmd.cmd.steering_angle = cmd.front_wheel_angle_rad;
124
125 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "generate_command() cmd.stamp: " << std::to_string(rclcpp::Time(cmd.stamp).seconds()));
126 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "generate_command() cmd.long_accel_mps2: " << cmd.long_accel_mps2);
127 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "generate_command() cmd.velocity_mps: " << cmd.velocity_mps);
128 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "generate_command() cmd.rear_wheel_angle_rad: " << cmd.rear_wheel_angle_rad);
129 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "generate_command() cmd.front_wheel_angle_rad: " << cmd.front_wheel_angle_rad);
130
131 return return_cmd;
132}
133
134autoware_msgs::msg::ControlCommandStamped PurePursuitWrapperNode::generate_command()
135{
136 // process and save the trajectory inside pure_pursuit
137 autoware_msgs::msg::ControlCommandStamped converted_cmd;
138
140 return converted_cmd;
141
142 motion::control::controller_common::State state_tf = convert_state(current_pose_.get(), current_twist_.get());
143
144 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "Forced from frame_id: " << state_tf.header.frame_id << ", into: " << current_trajectory_.get().header.frame_id);
145
146 current_trajectory_.get().header.frame_id = state_tf.header.frame_id;
147
149
150 pp_->set_trajectory(autoware_traj_plan);
151
152 const auto cmd{pp_->compute_command(state_tf)};
153
154 converted_cmd = convert_cmd(cmd);
155
156
157 return converted_cmd;
158}
159
160rcl_interfaces::msg::SetParametersResult PurePursuitWrapperNode::parameter_update_callback(const std::vector<rclcpp::Parameter> &parameters)
161{
162 auto error_double = update_params<double>({
163 {"vehicle_response_lag", config_.vehicle_response_lag},
164 {"minimum_lookahead_distance", config_.minimum_lookahead_distance},
165 {"maximum_lookahead_distance", config_.maximum_lookahead_distance},
166 {"speed_to_lookahead_ratio", config_.speed_to_lookahead_ratio},
167 {"emergency_stop_distance", config_.emergency_stop_distance},
168 {"speed_thres_traveling_direction", config_.speed_thres_traveling_direction},
169 {"dist_front_rear_wheels", config_.dist_front_rear_wheels},
170 {"integrator_max_pp", config_.integrator_max_pp},
171 {"integrator_min_pp", config_.integrator_min_pp},
172 {"Ki_pp", config_.Ki_pp},
173 }, parameters);
174
175 auto error_bool = update_params<bool>({
176 {"is_interpolate_lookahead_point", config_.is_interpolate_lookahead_point},
177 {"is_delay_compensation", config_.is_delay_compensation},
178 {"is_integrator_enabled", config_.is_integrator_enabled}
179 }, parameters);
180
181 rcl_interfaces::msg::SetParametersResult result;
182
183 result.successful = !error_double && !error_bool;
184
185 return result;
186}
187
188
190{
191 return true;
192}
193
195{
196 return "v4.0";
197}
198
199std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> PurePursuitWrapperNode::remove_repeated_timestamps(const std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint>& traj_points)
200{
201
202 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> new_traj_points;
203
204 carma_planning_msgs::msg::TrajectoryPlanPoint prev_point;
205 bool first = true;
206
207 for(auto point : traj_points){
208
209 if(first){
210 first = false;
211 prev_point = point;
212 new_traj_points.push_back(point);
213 continue;
214 }
215
216 if(point.target_time != prev_point.target_time){
217 new_traj_points.push_back(point);
218 prev_point = point;
219 }
220 else{
221 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("pure_pursuit_wrapper"), "Duplicate point found");
222 }
223 }
224
225 return new_traj_points;
226
227}
228
229} // namespace pure_pursuit_wrapper
230
231#include "rclcpp_components/register_node_macro.hpp"
232
233// Register the component with class_loader
234RCLCPP_COMPONENTS_REGISTER_NODE(pure_pursuit_wrapper::PurePursuitWrapperNode)
boost::optional< geometry_msgs::msg::TwistStamped > current_twist_
The most recent velocity message received by this node.
boost::optional< carma_planning_msgs::msg::TrajectoryPlan > current_trajectory_
The most recent trajectory received by this plugin.
boost::optional< geometry_msgs::msg::PoseStamped > current_pose_
The most recent pose message received by this node.
std::shared_ptr< pure_pursuit::PurePursuit > pp_
autoware_msgs::msg::ControlCommandStamped generate_command() override
Extending class provided method which should generate a command message which will be published to th...
autoware_msgs::msg::ControlCommandStamped convert_cmd(motion::motion_common::Command cmd)
motion::motion_common::State convert_state(geometry_msgs::msg::PoseStamped pose, geometry_msgs::msg::TwistStamped twist)
std::string get_version_id() override
Returns the version id of this plugin.
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > remove_repeated_timestamps(const std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > &traj_points)
Drops any points that sequentially have same target_time and return new trajectory_points in order to...
carma_ros2_utils::CallbackReturn on_configure_plugin() override
This method should be used to load parameters and will be called on the configure state transition.
bool get_availability() override
Get the availability status of this plugin based on the current operating environment....
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)
Example callback for dynamic parameter updates.
PurePursuitWrapperNode(const rclcpp::NodeOptions &options)
Constructor.
autoware_auto_msgs::msg::Trajectory process_trajectory_plan(const carma_planning_msgs::msg::TrajectoryPlan &tp, double vehicle_response_lag)
Given a carma type of trajectory_plan, generate autoware type of trajectory accounting for speed_lag ...
void set_logger(rclcpp::Logger logger)
Replace the module-level logger used by all basic_autonomy functions.
Definition: log.cpp:33
rclcpp::Logger get_logger()
Return the module-level logger used by all basic_autonomy functions.
Definition: log.cpp:32
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21
Struct containing the algorithm configuration values for the PurePursuitWrapperConfig.