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.
WMListener.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 */
16
17#include <new>
19#include "WMListenerWorker.hpp"
20
21
22namespace carma_wm
23{
24 // @SONAR_STOP@
26 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
27 rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
28 rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
29 rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_params_,
30 bool multi_thread)
31 :node_base_(node_base),node_logging_(node_logging),node_topics_(node_topics),worker_(std::unique_ptr<WMListenerWorker>(new WMListenerWorker)), multi_threaded_(multi_thread)
32{
33
34 RCLCPP_DEBUG_STREAM(node_logging_->get_logger(), "WMListener: Creating world model listener");
35
36 //Declare parameter if it doesn't exist
37 rclcpp::Parameter config_speed_limit_param("config_speed_limit");
38 if(!node_params_->get_parameter("config_speed_limit", config_speed_limit_param)){
39 rclcpp::ParameterValue config_speed_limit_param_value;
40 config_speed_limit_param_value = node_params_->declare_parameter("config_speed_limit", rclcpp::ParameterValue (0.0));
41 }
42
43 rclcpp::Parameter participant_param("vehicle_participant_type");
44 if(!node_params_->get_parameter("vehicle_participant_type", participant_param)){
45 rclcpp::ParameterValue participant_param_value;
46 participant_param_value = node_params_->declare_parameter("vehicle_participant_type", rclcpp::ParameterValue(""));
47 }
48
49 //Declare parameter if it doesn't exist
50 rclcpp::Parameter use_sim_time_param("use_sim_time");
51 if(!node_params_->get_parameter("use_sim_time", use_sim_time_param)){
52 rclcpp::ParameterValue use_sim_time_param_value;
53 use_sim_time_param_value = node_params_->declare_parameter("use_sim_time", rclcpp::ParameterValue (false));
54 }
55
56 rclcpp::Parameter is_spat_wall_time_param("is_spat_wall_time");
57 if(!node_params_->get_parameter("is_spat_wall_time", is_spat_wall_time_param)){
58 rclcpp::ParameterValue is_spat_wall_time_param_value;
59 is_spat_wall_time_param_value = node_params_->declare_parameter("is_spat_wall_time", rclcpp::ParameterValue (true));
60 }
61
62 // Get params
63 config_speed_limit_param = node_params_->get_parameter("config_speed_limit");
64 participant_param = node_params_->get_parameter("vehicle_participant_type");
65 use_sim_time_param = node_params_->get_parameter("use_sim_time");
66 is_spat_wall_time_param = node_params_->get_parameter("is_spat_wall_time");
67
68 RCLCPP_INFO_STREAM(node_logging->get_logger(), "Loaded config speed limit: " << config_speed_limit_param.as_double());
69 RCLCPP_INFO_STREAM(node_logging->get_logger(), "Loaded vehicle participant type: " << participant_param.as_string());
70 RCLCPP_INFO_STREAM(node_logging->get_logger(), "Is using simulation time? : " << use_sim_time_param.as_bool());
71 RCLCPP_INFO_STREAM(node_logging->get_logger(), "Is SPaT using wall time? : " << is_spat_wall_time_param.as_bool());
72
73
74 setConfigSpeedLimit(config_speed_limit_param.as_double());
75 worker_->setVehicleParticipationType(participant_param.as_string());
76 worker_->isUsingSimTime(use_sim_time_param.as_bool());
77 worker_->isSpatWallTime(is_spat_wall_time_param.as_bool());
78
79 rclcpp::SubscriptionOptions map_update_options;
80 rclcpp::SubscriptionOptions map_options;
81 rclcpp::SubscriptionOptions route_options;
82 rclcpp::SubscriptionOptions roadway_objects_options;
83 rclcpp::SubscriptionOptions traffic_spat_options;
84 rclcpp::SubscriptionOptions ros1_clock_options;
85 rclcpp::SubscriptionOptions sim_clock_options;
86
88 {
89 RCLCPP_DEBUG_STREAM(node_logging_->get_logger(), "WMListener: Using a multi-threaded subscription");
90
91 map_update_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
92
93 map_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
94
95 route_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
96
97 roadway_objects_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
98
99 traffic_spat_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
100
101 ros1_clock_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
102
103 sim_clock_options.callback_group = node_base_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
104 }
105
106 // Setup subscribers
107 route_sub_ = rclcpp::create_subscription<carma_planning_msgs::msg::Route>(node_topics_, "route", 1,
108 [this](const carma_planning_msgs::msg::Route::SharedPtr msg)
109 {
110 this->worker_->routeCallback(msg);
111 }
112 , route_options);
113
114 ros1_clock_sub_ = rclcpp::create_subscription<rosgraph_msgs::msg::Clock>(node_topics_, "/clock", 1,
115 [this](const rosgraph_msgs::msg::Clock::SharedPtr msg)
116 {
117 this->worker_->ros1ClockCallback(msg);
118 }
119 , ros1_clock_options);
120
121 sim_clock_sub_ = rclcpp::create_subscription<rosgraph_msgs::msg::Clock>(node_topics_, "/sim_clock", 1,
122 [this](const rosgraph_msgs::msg::Clock::SharedPtr msg)
123 {
124 this->worker_->simClockCallback(msg);
125 }
126 , sim_clock_options);
127
128 roadway_objects_sub_ = rclcpp::create_subscription<carma_perception_msgs::msg::RoadwayObstacleList>(node_topics_, "roadway_objects", 1,
129 [this](const carma_perception_msgs::msg::RoadwayObstacleList::SharedPtr msg)
130 {
131 this->worker_->roadwayObjectListCallback(msg);
132 }
133 , roadway_objects_options);
134
135 traffic_spat_sub_ = rclcpp::create_subscription<carma_v2x_msgs::msg::SPAT>(node_topics_, "incoming_spat", 1,
136 [this](const carma_v2x_msgs::msg::SPAT::SharedPtr msg)
137 {
138 this->worker_->incomingSpatCallback(msg);
139 }
140 , traffic_spat_options);
141
142 // NOTE: Currently, intra-process comms must be disabled for subscribers that are transient_local: https://github.com/ros2/rclcpp/issues/1753
143 map_update_options.use_intra_process_comm = rclcpp::IntraProcessSetting::Disable; // Disable intra-process comms for the map update subscriber
144 auto map_update_sub_qos = rclcpp::QoS(rclcpp::KeepLast(10)); // Set the queue size for the map update subscriber
145 map_update_sub_qos.transient_local(); // If it is possible that this node is a late-joiner to its topic, it must be set to transient_local to receive earlier messages that were missed.
146 // NOTE: The publisher's QoS must be set to transisent_local() as well for earlier messages to be resent to this later-joiner.
147
148 // Create map update subscriber that will receive earlier messages that were missed ONLY if the publisher is transient_local too
149 map_update_sub_ = rclcpp::create_subscription<autoware_lanelet2_msgs::msg::MapBin>(node_topics_, "map_update", map_update_sub_qos,
150 [this](const autoware_lanelet2_msgs::msg::MapBin::SharedPtr msg)
151 {
152 this->mapUpdateCallback(msg);
153 }
154 , map_update_options);
155
156 map_options.use_intra_process_comm = rclcpp::IntraProcessSetting::Disable; // Disable intra-process comms for the semantic map subscriber
157 auto map_sub_qos = rclcpp::QoS(rclcpp::KeepLast(2)); // Set the queue size for the semantic map subscriber
158 map_sub_qos.transient_local(); // If it is possible that this node is a late-joiner to its topic, it must be set to transient_local to receive earlier messages that were missed.
159 // NOTE: The publisher's QoS must be set to transisent_local() as well for earlier messages to be resent to this later-joiner.
160
161 // Create semantic mab subscriber that will receive earlier messages that were missed ONLY if the publisher is transient_local too
162 map_sub_ = rclcpp::create_subscription<autoware_lanelet2_msgs::msg::MapBin>(node_topics_, "semantic_map", map_sub_qos,
163 [this](const autoware_lanelet2_msgs::msg::MapBin::SharedPtr msg)
164 {
165 this->worker_->mapCallback(msg);
166 }
167 , map_options);
168}
169
171
173{
174 const std::lock_guard<std::mutex> lock(mw_mutex_);
175 worker_->enableUpdatesWithoutRoute();
176}
177
179{
180 const std::lock_guard<std::mutex> lock(mw_mutex_);
181 return worker_->checkIfReRoutingNeeded();
182}
183
185{
186 const std::lock_guard<std::mutex> lock(mw_mutex_);
187 return worker_->getWorldModel();
188}
189
190void WMListener::mapUpdateCallback(autoware_lanelet2_msgs::msg::MapBin::SharedPtr geofence_msg)
191{
192 const std::lock_guard<std::mutex> lock(mw_mutex_);
193
194 RCLCPP_INFO_STREAM(node_logging_->get_logger(), "New Map Update Received. SeqNum: " << geofence_msg->seq_id);
195
196 worker_->mapUpdateCallback(geofence_msg);
197}
198
199void WMListener::setMapCallback(std::function<void()> callback)
200{
201 const std::lock_guard<std::mutex> lock(mw_mutex_);
202 worker_->setMapCallback(callback);
203}
204
205void WMListener::setRouteCallback(std::function<void()> callback)
206{
207 const std::lock_guard<std::mutex> lock(mw_mutex_);
208 worker_->setRouteCallback(callback);
209}
210
211std::unique_lock<std::mutex> WMListener::getLock(bool pre_locked)
212{
213 if (pre_locked)
214 {
215 std::unique_lock<std::mutex> lock(mw_mutex_); // Create movable lock
216 return lock;
217 }
218 std::unique_lock<std::mutex> lock(mw_mutex_, std::defer_lock); // Create movable deferred lock
219 return lock;
220}
221
222void WMListener::setConfigSpeedLimit(double config_lim) const
223{
224 worker_->setConfigSpeedLimit(config_lim);
225}
226
227// @SONAR_START@
228
229}
Backend logic class for WMListener.
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_
Definition: WMListener.hpp:136
void mapUpdateCallback(autoware_lanelet2_msgs::msg::MapBin::SharedPtr geofence_msg)
Definition: WMListener.cpp:190
void setConfigSpeedLimit(double config_lim) const
Allows user to set a callback to be triggered when a route update is received NOTE: If operating in m...
Definition: WMListener.cpp:222
carma_ros2_utils::SubPtr< autoware_lanelet2_msgs::msg::MapBin > map_update_sub_
Definition: WMListener.hpp:133
void setMapCallback(std::function< void()> callback)
Allows user to set a callback to be triggered when a map update is received NOTE: If operating in mul...
Definition: WMListener.cpp:199
WorldModelConstPtr getWorldModel()
Returns a pointer to an intialized world model instance.
Definition: WMListener.cpp:184
carma_ros2_utils::SubPtr< rosgraph_msgs::msg::Clock > sim_clock_sub_
Definition: WMListener.hpp:145
carma_ros2_utils::SubPtr< rosgraph_msgs::msg::Clock > ros1_clock_sub_
Definition: WMListener.hpp:146
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_
Definition: WMListener.hpp:137
~WMListener()
Destructor.
Definition: WMListener.cpp:170
carma_ros2_utils::SubPtr< autoware_lanelet2_msgs::msg::MapBin > map_sub_
Definition: WMListener.hpp:142
std::unique_ptr< WMListenerWorker > worker_
Definition: WMListener.hpp:140
void enableUpdatesWithoutRouteWL()
Use to allow updates to occur even if they invalidate the current route. This is only meant to be use...
Definition: WMListener.cpp:172
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_params_
Definition: WMListener.hpp:138
carma_ros2_utils::SubPtr< carma_perception_msgs::msg::RoadwayObstacleList > roadway_objects_sub_
Definition: WMListener.hpp:132
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_
Definition: WMListener.hpp:135
void setRouteCallback(std::function< void()> callback)
Allows user to set a callback to be triggered when a route update is received NOTE: If operating in m...
Definition: WMListener.cpp:205
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::Route > route_sub_
Definition: WMListener.hpp:143
WMListener(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base, rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging, rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics, rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_params_, bool multi_thread=false)
Constructor which can be used to specify threading behavior of this class.
Definition: WMListener.cpp:25
const bool multi_threaded_
Definition: WMListener.hpp:147
bool checkIfReRoutingNeededWL()
Returns true if a map update has been processed which requires rerouting. This method is meant to be ...
Definition: WMListener.cpp:178
std::unique_lock< std::mutex > getLock(bool pre_locked=true)
Returns a unique_lock which can be used to lock world model updates until the user finishes a desired...
Definition: WMListener.cpp:211
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::SPAT > traffic_spat_sub_
Definition: WMListener.hpp:144
bool callback(cav_srvs::PlanTrajectory::Request &req, cav_srvs::PlanTrajectory::Response &res)
Definition: helper.cpp:21
std::shared_ptr< const WorldModel > WorldModelConstPtr
Definition: WorldModel.hpp:452