Carma-platform v4.2.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.
platoon_strategic_ihp_node.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 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 */
17#include <carma_ros2_utils/timers/TimerFactory.hpp>
18#include <carma_ros2_utils/timers/ROSTimerFactory.hpp>
19
21{
22 namespace std_ph = std::placeholders;
23
24 Node::Node(const rclcpp::NodeOptions &options)
25 : carma_guidance_plugins::StrategicPlugin(options)
26 {
27 // Create initial config
29
30 // Declare parameters
31
32 declare_parameter<bool>("allowCutinJoin", config_.allowCutinJoin);
33 declare_parameter<bool>("test_cutin_join", config_.test_cutin_join);
34 declare_parameter<bool>("test_front_join", config_.test_front_join);
35
36 declare_parameter<int>("maxPlatoonSize", config_.maxPlatoonSize);
37 declare_parameter<int>("algorithmType", config_.algorithmType);
38 declare_parameter<int>("statusMessageInterval", config_.statusMessageInterval);
39 declare_parameter<int>("infoMessageInterval", config_.infoMessageInterval);
40 declare_parameter<int>("join_index", config_.join_index);
41
42 declare_parameter<double>("timeHeadway", config_.timeHeadway);
43 declare_parameter<double>("standStillHeadway", config_.standStillHeadway);
44 declare_parameter<double>("maxAllowedJoinTimeGap", config_.maxAllowedJoinTimeGap);
45 declare_parameter<double>("maxAllowedJoinGap", config_.maxAllowedJoinGap);
46 declare_parameter<double>("minAllowedJoinGap", config_.minAllowedJoinGap);
47 declare_parameter<double>("desiredJoinTimeGap", config_.desiredJoinTimeGap);
48 declare_parameter<double>("desiredJoinGap", config_.desiredJoinGap);
49 declare_parameter<double>("waitingStateTimeout", config_.waitingStateTimeout);
50 declare_parameter<double>("cmdSpeedMaxAdjustment", config_.cmdSpeedMaxAdjustment);
51 declare_parameter<double>("minAllowableHeadaway", config_.minAllowableHeadaway);
52 declare_parameter<double>("maxAllowableHeadaway", config_.maxAllowableHeadaway);
53 declare_parameter<double>("headawayStableLowerBond", config_.headawayStableLowerBond);
54 declare_parameter<double>("headawayStableUpperBond", config_.headawayStableUpperBond);
55 declare_parameter<double>("minCutinGap", config_.minCutinGap);
56 declare_parameter<double>("maxCutinGap", config_.maxCutinGap);
57 declare_parameter<double>("maxCrosstrackError", config_.maxCrosstrackError);
58 declare_parameter<double>("minPlatooningSpeed", config_.minPlatooningSpeed);
59 declare_parameter<double>("significantDTDchange", config_.significantDTDchange);
60 declare_parameter<double>("longitudinalCheckThresold", config_.longitudinalCheckThresold);
61 declare_parameter<double>("vehicle_length", config_.vehicleLength);
62 declare_parameter<std::string>("vehicle_id", config_.vehicleID);
63 }
64
65 rcl_interfaces::msg::SetParametersResult Node::parameter_update_callback(const std::vector<rclcpp::Parameter> &parameters)
66 {
67
68 auto error = update_params<bool>({
69 {"test_front_join", config_.test_front_join},
70 {"allowCutinJoin", config_.allowCutinJoin},
71 {"test_cutin_join", config_.test_cutin_join}
72 }, parameters);
73
74 auto error2 = update_params<int>({
75 {"maxPlatoonSize", config_.maxPlatoonSize},
76 {"algorithmType", config_.algorithmType},
77 {"statusMessageInterval", config_.statusMessageInterval},
78 {"infoMessageInterval", config_.infoMessageInterval},
79 {"join_index", config_.join_index}
80 }, parameters);
81
82 auto error3 = update_params<double>({
83 {"timeHeadway", config_.timeHeadway},
84 {"standStillHeadway", config_.standStillHeadway},
85 {"maxAllowedJoinTimeGap", config_.maxAllowedJoinTimeGap},
86 {"maxAllowedJoinGap", config_.maxAllowedJoinGap},
87 {"minAllowedJoinGap", config_.minAllowedJoinGap},
88 {"desiredJoinTimeGap", config_.desiredJoinTimeGap},
89 {"desiredJoinGap", config_.desiredJoinGap},
90 {"waitingStateTimeout", config_.waitingStateTimeout},
91 {"cmdSpeedMaxAdjustment", config_.cmdSpeedMaxAdjustment},
92 {"minAllowableHeadaway", config_.minAllowableHeadaway},
93 {"maxAllowableHeadaway", config_.maxAllowableHeadaway},
94 {"headawayStableLowerBond", config_.headawayStableLowerBond},
95 {"headawayStableUpperBond", config_.headawayStableUpperBond},
96 {"minCutinGap", config_.minCutinGap},
97 {"maxCutinGap", config_.maxCutinGap},
98 {"maxCrosstrackError", config_.maxCrosstrackError},
99 {"minPlatooningSpeed", config_.minPlatooningSpeed},
100 {"significantDTDchange", config_.significantDTDchange},
101 {"longitudinalCheckThresold", config_.longitudinalCheckThresold}
102 // vehicle_length and id excluded since they should not be updated at runtime
103 }, parameters);
104
105
106 rcl_interfaces::msg::SetParametersResult result;
107
108 result.successful = !error && !error2 && !error3;
109
110 if (result.successful && worker_)
111 {
112 worker_->setConfig(config_);
113 }
114
115 return result;
116 }
117
118 carma_ros2_utils::CallbackReturn Node::on_configure_plugin()
119 {
120 // Reset config
122
123 // Load parameters
124 get_parameter<bool>("test_front_join", config_.test_front_join);
125 get_parameter<bool>("allowCutinJoin", config_.allowCutinJoin);
126 get_parameter<bool>("test_cutin_join", config_.test_cutin_join);
127
128 get_parameter<int>("maxPlatoonSize", config_.maxPlatoonSize);
129 get_parameter<int>("algorithmType", config_.algorithmType);
130 get_parameter<int>("statusMessageInterval", config_.statusMessageInterval);
131 get_parameter<int>("infoMessageInterval", config_.infoMessageInterval);
132 get_parameter<int>("join_index", config_.join_index);
133
134 get_parameter<double>("timeHeadway", config_.timeHeadway);
135 get_parameter<double>("standStillHeadway", config_.standStillHeadway);
136 get_parameter<double>("maxAllowedJoinTimeGap", config_.maxAllowedJoinTimeGap);
137 get_parameter<double>("maxAllowedJoinGap", config_.maxAllowedJoinGap);
138 get_parameter<double>("minAllowedJoinGap", config_.minAllowedJoinGap);
139 get_parameter<double>("desiredJoinTimeGap", config_.desiredJoinTimeGap);
140 get_parameter<double>("desiredJoinGap", config_.desiredJoinGap);
141 get_parameter<double>("waitingStateTimeout", config_.waitingStateTimeout);
142 get_parameter<double>("cmdSpeedMaxAdjustment", config_.cmdSpeedMaxAdjustment);
143 get_parameter<double>("minAllowableHeadaway", config_.minAllowableHeadaway);
144 get_parameter<double>("maxAllowableHeadaway", config_.maxAllowableHeadaway);
145 get_parameter<double>("headawayStableLowerBond", config_.headawayStableLowerBond);
146 get_parameter<double>("headawayStableUpperBond", config_.headawayStableUpperBond);
147 get_parameter<double>("minCutinGap", config_.minCutinGap);
148 get_parameter<double>("maxCutinGap", config_.maxCutinGap);
149 get_parameter<double>("maxCrosstrackError", config_.maxCrosstrackError);
150 get_parameter<double>("minPlatooningSpeed", config_.minPlatooningSpeed);
151 get_parameter<double>("significantDTDchange", config_.significantDTDchange);
152 get_parameter<double>("longitudinalCheckThresold", config_.longitudinalCheckThresold);
153 get_parameter<double>("vehicle_length", config_.vehicleLength);
154 get_parameter<std::string>("vehicle_id", config_.vehicleID);
155
156 // Register runtime parameter update callback
157 add_on_set_parameters_callback(std::bind(&Node::parameter_update_callback, this, std_ph::_1));
158
159 // Setup publishers
160 mob_response_pub = create_publisher<carma_v2x_msgs::msg::MobilityResponse>("outgoing_mobility_response", 5);
161 mob_request_pub = create_publisher<carma_v2x_msgs::msg::MobilityRequest>("outgoing_mobility_request", 5);
162 mob_operation_pub = create_publisher<carma_v2x_msgs::msg::MobilityOperation>("outgoing_mobility_operation", 5);
163 platoon_info_pub = create_publisher<carma_planning_msgs::msg::PlatooningInfo>("platoon_info", 1);
164
165 // Build worker
166
167 worker_ = std::make_shared<PlatoonStrategicIHPPlugin>(get_world_model(), config_, [this](auto msg) { this->mob_response_pub->publish(msg); },
168 [this](auto msg) { this->mob_request_pub->publish(msg); }, [this](auto msg) { this->mob_operation_pub->publish(msg); },
169 [this](auto msg) { this->platoon_info_pub->publish(msg); },
170 std::make_shared<carma_ros2_utils::timers::ROSTimerFactory>(shared_from_this()));
171
172
173 // Setup subscribers
174 mob_request_sub = create_subscription<carma_v2x_msgs::msg::MobilityRequest>("incoming_mobility_request", 10,
175 std::bind(&PlatoonStrategicIHPPlugin::mob_req_cb, worker_.get(), std_ph::_1));
176
177 mob_response_sub = create_subscription<carma_v2x_msgs::msg::MobilityResponse>("incoming_mobility_response", 10,
178 std::bind(&PlatoonStrategicIHPPlugin::mob_resp_cb, worker_.get(), std_ph::_1));
179
180 mob_operation_sub = create_subscription<carma_v2x_msgs::msg::MobilityOperation>("incoming_mobility_operation", 10,
181 std::bind(&PlatoonStrategicIHPPlugin::mob_op_cb, worker_.get(), std_ph::_1));
182
183 current_pose_sub = create_subscription<geometry_msgs::msg::PoseStamped>("current_pose", 10,
184 std::bind(&PlatoonStrategicIHPPlugin::pose_cb, worker_.get(), std_ph::_1));
185
186 current_twist_sub = create_subscription<geometry_msgs::msg::TwistStamped>("current_velocity", 10,
187 std::bind(&PlatoonStrategicIHPPlugin::twist_cb, worker_.get(), std_ph::_1));
188
189 cmd_sub = create_subscription<geometry_msgs::msg::TwistStamped>("twist_raw", 10,
190 std::bind(&PlatoonStrategicIHPPlugin::cmd_cb, worker_.get(), std_ph::_1));
191
192 georeference_sub = create_subscription<std_msgs::msg::String>("georeference", 10,
193 std::bind(&PlatoonStrategicIHPPlugin::georeference_cb, worker_.get(), std_ph::_1));
194
195 loop_timer_ = create_timer(
196 get_clock(),
197 std::chrono::milliseconds(100), // 10 Hz frequency
198 std::bind(&PlatoonStrategicIHPPlugin::onSpin, worker_.get()));
199
200 // Return success if everything initialized successfully
201 return CallbackReturn::SUCCESS;
202 }
203
204 carma_ros2_utils::CallbackReturn Node::on_cleanup_plugin()
205 {
206 // Ensure subscribers are disconnected incase cleanup is called, we don't want to keep driving the worker
207 mob_response_sub.reset();
208 mob_operation_sub.reset();
209 current_pose_sub.reset();
210 current_twist_sub.reset();
211 cmd_sub.reset();
212 georeference_sub.reset();
213 worker_.reset();
214
215 return CallbackReturn::SUCCESS;
216 }
217
218
220 std::shared_ptr<rmw_request_id_t>,
221 carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req,
222 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
223 {
224 if (worker_)
225 worker_->plan_maneuver_cb(*req, *resp);
226 }
227
229 return true;
230 }
231
232 std::string Node::get_version_id() {
233 return "v4.0";
234 }
235
236} // platoon_strategic_ihp
237
238#include "rclcpp_components/register_node_macro.hpp"
239
240// Register the component with class_loader
241RCLCPP_COMPONENTS_REGISTER_NODE(platoon_strategic_ihp::Node)
virtual carma_wm::WorldModelConstPtr get_world_model() final
Method to return the default world model provided as a convience by this base class If this method or...
ROS Node to for Platooning Strategic Plugin IHP2 variant. It includes all the service clients,...
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)
Callback for dynamic parameter updates.
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityRequest > mob_request_sub
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityResponse > mob_response_pub
bool get_availability() override
Get the availability status of this plugin based on the current operating environment....
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_sub
std::string get_version_id() override
Returns the version id of this plugin.
rclcpp::TimerBase::SharedPtr loop_timer_
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_pub
Node(const rclcpp::NodeOptions &)
Node constructor.
carma_ros2_utils::CallbackReturn on_cleanup_plugin()
Method which is triggered when this plugin is moved from the INACTIVE to UNCONFIGURED states....
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityRequest > mob_request_pub
carma_ros2_utils::SubPtr< geometry_msgs::msg::TwistStamped > cmd_sub
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > current_pose_sub
carma_ros2_utils::SubPtr< std_msgs::msg::String > georeference_sub
carma_ros2_utils::CallbackReturn on_configure_plugin()
This method should be used to load parameters and will be called on the configure state transition.
carma_ros2_utils::SubPtr< geometry_msgs::msg::TwistStamped > current_twist_sub
carma_ros2_utils::PubPtr< carma_planning_msgs::msg::PlatooningInfo > platoon_info_pub
std::shared_ptr< PlatoonStrategicIHPPlugin > worker_
void plan_maneuvers_callback(std::shared_ptr< rmw_request_id_t >, carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp) override
Extending class provided callback which should return a planned trajectory based on the provided traj...
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityResponse > mob_response_sub
void georeference_cb(const std_msgs::msg::String::UniquePtr msg)
Callback for the georeference.
void mob_req_cb(const carma_v2x_msgs::msg::MobilityRequest::UniquePtr msg)
Callback function for Mobility Request Message.
void mob_op_cb(const carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
Callback function for Mobility Operation Message.
void cmd_cb(const geometry_msgs::msg::TwistStamped::UniquePtr msg)
Callback for the control command.
void pose_cb(const geometry_msgs::msg::PoseStamped::UniquePtr msg)
Callback function for current pose.
void mob_resp_cb(const carma_v2x_msgs::msg::MobilityResponse::UniquePtr msg)
Callback function for Mobility Response Message.
void twist_cb(const geometry_msgs::msg::TwistStamped::UniquePtr msg)
Callback for the twist subscriber, which will store latest twist locally.
Stuct containing the algorithm configuration values for the yield_pluginConfig.