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.
localization_manager_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 <boost/bind.hpp>
18#include <boost/bind/placeholders.hpp>
19#include <carma_ros2_utils/timers/ROSTimerFactory.hpp>
20
22{
23 namespace std_ph = std::placeholders;
24
25 Node::Node(const rclcpp::NodeOptions &options)
26 : carma_ros2_utils::CarmaLifecycleNode(options)
27
28 {
29 // Create initial config
31
32 // Declare parameters
33 config_.fitness_score_degraded_threshold = declare_parameter<double>("fitness_score_degraded_threshold", config_.fitness_score_degraded_threshold);
34 config_.fitness_score_fault_threshold = declare_parameter<double>("fitness_score_fault_threshold", config_.fitness_score_fault_threshold);
35 config_.ndt_frequency_degraded_threshold = declare_parameter<double>("ndt_frequency_degraded_threshold", config_.ndt_frequency_degraded_threshold);
36 config_.ndt_frequency_fault_threshold = declare_parameter<double>("ndt_frequency_fault_threshold", config_.ndt_frequency_fault_threshold);
37 config_.auto_initialization_timeout = declare_parameter<int>("auto_initialization_timeout", config_.auto_initialization_timeout);
38 config_.gnss_only_operation_timeout = declare_parameter<int>("gnss_only_operation_timeout", config_.gnss_only_operation_timeout);
39 config_.sequential_timesteps_until_gps_operation = declare_parameter<int>("sequential_timesteps_until_gps_operation", config_.sequential_timesteps_until_gps_operation);
40 config_.gnss_data_timeout = declare_parameter<int>("gnss_data_timeout", config_.gnss_data_timeout);
41 config_.localization_mode = declare_parameter<int>("localization_mode", config_.localization_mode);
42 config_.pose_pub_rate = declare_parameter<double>("pose_pub_rate", config_.pose_pub_rate);
43 config_.x_offset = declare_parameter<double>("x_offset", config_.x_offset);
44 config_.y_offset = declare_parameter<double>("y_offset", config_.y_offset);
45 config_.z_offset = declare_parameter<double>("z_offset", config_.z_offset);
46 }
47
48 carma_ros2_utils::CallbackReturn Node::handle_on_configure(const rclcpp_lifecycle::State &)
49 {
50 // Reset config
52
53 // Load parameters
54 get_parameter<double>("fitness_score_degraded_threshold", config_.fitness_score_degraded_threshold);
55 get_parameter<double>("fitness_score_fault_threshold", config_.fitness_score_fault_threshold);
56 get_parameter<double>("ndt_frequency_degraded_threshold", config_.ndt_frequency_degraded_threshold);
57 get_parameter<double>("ndt_frequency_fault_threshold", config_.ndt_frequency_fault_threshold);
58 get_parameter<int>("auto_initialization_timeout", config_.auto_initialization_timeout);
59 get_parameter<int>("gnss_only_operation_timeout", config_.gnss_only_operation_timeout);
60 get_parameter<int>("sequential_timesteps_until_gps_operation", config_.sequential_timesteps_until_gps_operation);
61 get_parameter<int>("gnss_data_timeout", config_.gnss_data_timeout);
62 get_parameter<int>("localization_mode", config_.localization_mode);
63 get_parameter<double>("pose_pub_rate", config_.pose_pub_rate);
64 get_parameter<double>("x_offset", config_.x_offset);
65 get_parameter<double>("y_offset", config_.y_offset);
66 get_parameter<double>("z_offset", config_.z_offset);
67
68 RCLCPP_INFO_STREAM(rclcpp::get_logger("localization_manager"), "Loaded params: ");
69
70 // Initialize worker object
71 manager_.reset(new LocalizationManager(std::bind(&Node::publishPoseStamped, this, std_ph::_1),
72 std::bind(&Node::publishStatus, this, std_ph::_1),
73 std::bind(&Node::publishManagedInitialPose, this, std_ph::_1),
74 config_,
75 get_node_logging_interface(),
76 std::make_unique<carma_ros2_utils::timers::ROSTimerFactory>(shared_from_this())));
77
78 // Register runtime parameter update callback
79 add_on_set_parameters_callback(std::bind(&Node::parameter_update_callback, this, std_ph::_1));
80
81 // Setup subscribers
82 gnss_pose_sub_ = create_subscription<geometry_msgs::msg::PoseStamped>("gnss_pose", 5,
83 std::bind(&LocalizationManager::gnssPoseCallback, manager_.get(), std_ph::_1));
84 initialpose_sub_ = create_subscription<geometry_msgs::msg::PoseWithCovarianceStamped>("initialpose", 1,
85 std::bind(&LocalizationManager::initialPoseCallback, manager_.get(), std_ph::_1));
86
87 // Setup synchronized message_filters subscribers
88 rclcpp::QoS qos(5);
89 ndt_pose_sub_.subscribe(this, "ndt_pose", qos.get_rmw_qos_profile());
90 ndt_score_sub_.subscribe(this, "ndt_stat", qos.get_rmw_qos_profile());
91
92 pose_stats_synchronizer_ = std::make_shared<TimeSynchronizer>(ndt_pose_sub_, ndt_score_sub_, 5);
93 pose_stats_synchronizer_->registerCallback(std::bind(&Node::poseAndStatsCallback, this, std_ph::_1, std_ph::_2));
94
95 // system_alert_topic_ protected member of CarmaLifecycleNode
96 system_alert_sub_ = create_subscription<carma_msgs::msg::SystemAlert>(system_alert_topic_, 1,
97 std::bind(&LocalizationManager::systemAlertCallback, manager_.get(), std_ph::_1));
98 // Setup publishers
99 pose_pub_ = create_publisher<geometry_msgs::msg::PoseStamped>("selected_pose", 5);
100 state_pub_ = create_publisher<carma_localization_msgs::msg::LocalizationStatusReport>("localization_status", 5);
101
102 // Create a publisher that will send all previously published messages to late-joining subscribers ONLY If the subscriber is transient_local too
103 rclcpp::PublisherOptions intra_proc_disabled;
104 intra_proc_disabled.use_intra_process_comm = rclcpp::IntraProcessSetting::Disable; // Disable intra-process comms for this PublisherOptions object
105
106 auto pub_qos_transient_local = rclcpp::QoS(rclcpp::KeepLast(1)); // A publisher with this QoS will store all messages that it has sent on the topic
107 pub_qos_transient_local.transient_local(); // A publisher with this QoS will re-send all (when KeepAll is used) messages to all late-joining subscribers
108 // NOTE: The subscriber's QoS must be set to transient_local() as well for earlier messages to be resent to the later-joiner.
109 managed_initial_pose_pub_ = create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>("managed_initialpose", pub_qos_transient_local, intra_proc_disabled);
110
111 // Setup timer
112 pose_timer_ = create_timer(get_clock(), std::chrono::milliseconds(int(1 / config_.pose_pub_rate * 1000)),
113 std::bind(&LocalizationManager::posePubTick, manager_.get()));
114
115 // Return success if everything initialized successfully
116 return CallbackReturn::SUCCESS;
117 }
118
119 void Node::publishPoseStamped(const geometry_msgs::msg::PoseStamped &msg) const
120 {
121 pose_pub_->publish(msg);
122 }
123
124 void Node::publishStatus(const carma_localization_msgs::msg::LocalizationStatusReport &msg) const
125 {
126 state_pub_->publish(msg);
127 }
128
129 rcl_interfaces::msg::SetParametersResult Node::parameter_update_callback(const std::vector<rclcpp::Parameter> &parameters)
130 {
131 auto error = update_params<double>(
132 {{"pose_pub_rate", config_.pose_pub_rate},
133 {"fitness_score_degraded_threshold", config_.fitness_score_degraded_threshold},
134 {"fitness_score_fault_threshold", config_.fitness_score_fault_threshold},
135 {"ndt_frequency_degraded_threshold", config_.ndt_frequency_degraded_threshold},
136 {"ndt_frequency_fault_threshold", config_.ndt_frequency_fault_threshold},
137 {"x_offset", config_.x_offset},
138 {"y_offset", config_.y_offset},
139 {"z_offset", config_.z_offset}}, parameters);
140
141 auto error_2 = update_params<int>(
142 {{"auto_initialization_timeout", config_.auto_initialization_timeout},
143 {"gnss_only_operation_timeout", config_.gnss_only_operation_timeout},
144 {"gnss_data_timeout", config_.gnss_data_timeout},
145 {"sequential_timesteps_until_gps_operation", config_.sequential_timesteps_until_gps_operation}
146 }, parameters);
147
148 rcl_interfaces::msg::SetParametersResult result;
149
150 result.successful = !error && !error_2;
151
152 if (result.successful)
153 {
154 manager_->setConfig(config_);
155 }
156
157 return result;
158 }
159
160 void Node::publishManagedInitialPose(const geometry_msgs::msg::PoseWithCovarianceStamped &msg) const
161 {
162 managed_initial_pose_pub_->publish(msg);
163 }
164
165 void Node::poseAndStatsCallback(const geometry_msgs::msg::PoseStamped::ConstPtr pose,
166 const autoware_msgs::msg::NDTStat::ConstPtr stats)
167 {
168 try
169 {
170 manager_->poseAndStatsCallback(pose, stats);
171 }
172 catch (const std::exception &e)
173 {
174 RCLCPP_ERROR_STREAM(rclcpp::get_logger("localization_manager"), "Uncaught Exception in localization_manager. Exception: " << e.what());
175 handle_primary_state_exception(e);
176 }
177 }
178} // namespace localization_manager
179
180#include "rclcpp_components/register_node_macro.hpp"
181
182// Register the component with class_loader
183RCLCPP_COMPONENTS_REGISTER_NODE(localization_manager::Node)
Primary logic class for the localization manager node.
void posePubTick()
Timer callback that controls the publication of the selected pose and status report.
void gnssPoseCallback(const geometry_msgs::msg::PoseStamped::SharedPtr msg)
Callback for new GNSS messages.
void initialPoseCallback(const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr msg)
Callback for the initial pose provided by Rviz or some external localization initializer.
void systemAlertCallback(const carma_msgs::msg::SystemAlert::SharedPtr alert)
Callback for SystemAlert data. Used to check for lidar failure.
Core execution node for this package.
LocalizationManagerConfig config_
void publishStatus(const carma_localization_msgs::msg::LocalizationStatusReport &msg) const
Callback to publish the provided localization status report.
std::unique_ptr< LocalizationManager > manager_
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > gnss_pose_sub_
Node(const rclcpp::NodeOptions &)
Node constructor.
carma_ros2_utils::PubPtr< geometry_msgs::msg::PoseStamped > pose_pub_
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)
Callback for dynamic parameter updates.
carma_ros2_utils::PubPtr< carma_localization_msgs::msg::LocalizationStatusReport > state_pub_
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseWithCovarianceStamped > initialpose_sub_
void publishPoseStamped(const geometry_msgs::msg::PoseStamped &msg) const
Callback to publish the selected pose.
message_filters::Subscriber< geometry_msgs::msg::PoseStamped, Node > ndt_pose_sub_
void publishManagedInitialPose(const geometry_msgs::msg::PoseWithCovarianceStamped &msg) const
Callback to publish the initial pose deemed suitable to intialize NDT.
carma_ros2_utils::SubPtr< carma_msgs::msg::SystemAlert > system_alert_sub_
rclcpp::TimerBase::SharedPtr pose_timer_
message_filters::Subscriber< autoware_msgs::msg::NDTStat, Node > ndt_score_sub_
void poseAndStatsCallback(const geometry_msgs::msg::PoseStamped::ConstPtr pose, const autoware_msgs::msg::NDTStat::ConstPtr stats)
Synchronized callback for pose and stats data for usage with message_filters. Provides exception hand...
carma_ros2_utils::PubPtr< geometry_msgs::msg::PoseWithCovarianceStamped > managed_initial_pose_pub_
std::shared_ptr< TimeSynchronizer > pose_stats_synchronizer_
carma_ros2_utils::CallbackReturn handle_on_configure(const rclcpp_lifecycle::State &)
Struct to store the configuration settings for the LocalizationManager class.
int gnss_only_operation_timeout
Timeout in ms for GNSS only operation. Ignored when in GNSS mode.
double fitness_score_degraded_threshold
NDT Fitness score above which the localization is considered in a degraded state.
double pose_pub_rate
Selected pose publication rate.
double x_offset
GPS Offset to apply if that mode is enabled.
int gnss_data_timeout
GNSS Data timeout. If exceeded the system will assume the GNSS is no longer functional....
double ndt_frequency_degraded_threshold
NDT solution frequency below which the localization is considered in a degraded state.