/home/runner/work/beluga/beluga/beluga_amcl/include/beluga_amcl/amcl_node.hpp Source File

/home/runner/work/beluga/beluga/beluga_amcl/include/beluga_amcl/amcl_node.hpp Source File#

Beluga AMCL: /home/runner/work/beluga/beluga/beluga_amcl/include/beluga_amcl/amcl_node.hpp Source File
Beluga AMCL
amcl_node.hpp
Go to the documentation of this file.
1 // Copyright 2022-2024 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BELUGA_AMCL_AMCL_NODE_HPP
16 #define BELUGA_AMCL_AMCL_NODE_HPP
17 
18 #include <memory>
19 #include <optional>
20 #include <type_traits>
21 #include <utility>
22 
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wcpp"
25 #include <message_filters/subscriber.hpp>
26 #pragma GCC diagnostic pop
27 
28 #include <tf2_ros/buffer.h>
29 #include <tf2_ros/message_filter.h>
30 #include <tf2_ros/transform_broadcaster.h>
31 #include <tf2_ros/transform_listener.h>
32 #include <bondcpp/bond.hpp>
33 #include <rclcpp_lifecycle/lifecycle_node.hpp>
34 
35 #include <geometry_msgs/msg/pose_array.hpp>
36 #include <geometry_msgs/msg/pose_with_covariance_stamped.hpp>
37 #include <nav_msgs/msg/occupancy_grid.hpp>
38 #include <sensor_msgs/msg/laser_scan.hpp>
39 #include <std_srvs/srv/empty.hpp>
40 #include <visualization_msgs/msg/marker_array.hpp>
41 
42 #include <beluga/beluga.hpp>
43 #include <beluga_ros/amcl.hpp>
45 #include "beluga_amcl/ros2_common.hpp"
46 
52 namespace beluga_amcl {
53 
55 class AmclNode : public BaseAMCLNode {
56  public:
57  using rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;
58 
60  explicit AmclNode(const rclcpp::NodeOptions& options = rclcpp::NodeOptions());
61  ~AmclNode() override;
62 
63  protected:
65  void do_activate(const rclcpp_lifecycle::State&) override;
66 
68  void do_deactivate(const rclcpp_lifecycle::State&) override;
69 
71  void do_cleanup(const rclcpp_lifecycle::State&) override;
72 
74  auto get_initial_estimate() const -> std::optional<std::pair<Sophus::SE2d, Eigen::Matrix3d>>;
75 
77  auto get_motion_model(std::string_view) const -> beluga_ros::Amcl::motion_model_variant;
78 
80  auto get_sensor_model(std::string_view, nav_msgs::msg::OccupancyGrid::SharedPtr) const
81  -> beluga_ros::Amcl::sensor_model_variant;
82 
84  auto make_particle_filter(nav_msgs::msg::OccupancyGrid::SharedPtr) const -> std::unique_ptr<beluga_ros::Amcl>;
85 
87  void map_callback(nav_msgs::msg::OccupancyGrid::SharedPtr);
88 
90  void do_periodic_timer_callback() override;
91 
93  template <typename TransformT>
94  std::optional<TransformT>
95  lookup_transform(const std::string& target_frame_id, const std::string& source_frame_id, const tf2::TimePoint& stamp);
96 
98  std::optional<beluga_ros::LaserScan> wrap_sensor_data(const sensor_msgs::msg::LaserScan::ConstSharedPtr& sensor_msg);
99 
102  const sensor_msgs::msg::PointCloud2::ConstSharedPtr& sensor_msg);
103 
105  template <typename MessageT>
106  void sensor_callback(const std::shared_ptr<const MessageT>& sensor_msg);
107 
109  void do_initial_pose_callback(geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr) override;
110 
113  std::shared_ptr<rmw_request_id_t> request_header,
114  std::shared_ptr<std_srvs::srv::Empty::Request> request,
115  std::shared_ptr<std_srvs::srv::Empty::Response> response);
116 
119  std::shared_ptr<rmw_request_id_t> request_header,
120  std::shared_ptr<std_srvs::srv::Empty::Request> req,
121  std::shared_ptr<std_srvs::srv::Empty::Response> res);
122 
124 
132  bool initialize_from_estimate(const std::pair<Sophus::SE2d, Eigen::Matrix3d>& estimate);
133 
135 
143 
145  rclcpp::Subscription<nav_msgs::msg::OccupancyGrid>::SharedPtr map_sub_;
146 
148  std::unique_ptr<message_filters::Subscriber<sensor_msgs::msg::LaserScan>> laser_scan_sub_;
149 
151  std::unique_ptr<message_filters::Subscriber<sensor_msgs::msg::PointCloud2>> point_cloud_sub_;
152 
154  rclcpp_lifecycle::LifecyclePublisher<nav_msgs::msg::OccupancyGrid>::SharedPtr likelihood_field_pub_;
155 
157  rclcpp::Service<std_srvs::srv::Empty>::SharedPtr global_localization_server_;
159  rclcpp::Service<std_srvs::srv::Empty>::SharedPtr nomotion_update_server_;
160 
162  std::unique_ptr<tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan>> laser_scan_filter_;
164  ::message_filters::Connection laser_scan_connection_;
165 
167  std::unique_ptr<tf2_ros::MessageFilter<sensor_msgs::msg::PointCloud2>> point_cloud_filter_;
168 
170  ::message_filters::Connection point_cloud_connection_;
171 
173  std::unique_ptr<beluga_ros::Amcl> particle_filter_;
175  std::optional<std::pair<Sophus::SE2d, Eigen::Matrix3d>> last_known_estimate_;
179  bool enable_tf_broadcast_{false};
180 };
181 
182 } // namespace beluga_amcl
183 
184 #endif // BELUGA_AMCL_AMCL_NODE_HPP
2D AMCL as a ROS 2 composable lifecycle node.
Definition: amcl_node.hpp:55
void map_callback(nav_msgs::msg::OccupancyGrid::SharedPtr)
Callback for occupancy grid map updates.
bool enable_tf_broadcast_
Whether to broadcast transforms or not.
Definition: amcl_node.hpp:179
std::optional< beluga_ros::LaserScan > wrap_sensor_data(const sensor_msgs::msg::LaserScan::ConstSharedPtr &sensor_msg)
Try to wrap a laser scan message.
std::unique_ptr< tf2_ros::MessageFilter< sensor_msgs::msg::PointCloud2 > > point_cloud_filter_
Transform synchronization filter for laser scan updates.
Definition: amcl_node.hpp:167
std::optional< TransformT > lookup_transform(const std::string &target_frame_id, const std::string &source_frame_id, const tf2::TimePoint &stamp)
Try to look up a tf transform immediately.
auto get_motion_model(std::string_view) const -> beluga_ros::Amcl::motion_model_variant
Get motion model as per current parametrization.
std::optional< Sophus::SE2d > last_known_odom_transform_in_map_
Last known map to odom correction estimate, if any.
Definition: amcl_node.hpp:177
void global_localization_callback(std::shared_ptr< rmw_request_id_t > request_header, std::shared_ptr< std_srvs::srv::Empty::Request > request, std::shared_ptr< std_srvs::srv::Empty::Response > response)
Callback for the global relocalization service.
AmclNode(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
Constructor.
auto get_initial_estimate() const -> std::optional< std::pair< Sophus::SE2d, Eigen::Matrix3d >>
Get initial pose estimate from parameters if set.
void sensor_callback(const std::shared_ptr< const MessageT > &sensor_msg)
Callback for sensor updates.
rclcpp::Service< std_srvs::srv::Empty >::SharedPtr nomotion_update_server_
No motion update service server.
Definition: amcl_node.hpp:159
std::unique_ptr< message_filters::Subscriber< sensor_msgs::msg::PointCloud2 > > point_cloud_sub_
Point cloud updates subscription.
Definition: amcl_node.hpp:151
void nomotion_update_callback(std::shared_ptr< rmw_request_id_t > request_header, std::shared_ptr< std_srvs::srv::Empty::Request > req, std::shared_ptr< std_srvs::srv::Empty::Response > res)
Callback for the no motion update service.
std::unique_ptr< beluga_ros::Amcl > particle_filter_
Particle filter instance.
Definition: amcl_node.hpp:173
void do_activate(const rclcpp_lifecycle::State &) override
Callback for lifecycle transitions from the INACTIVE state to the ACTIVE state.
bool initialize_from_estimate(const std::pair< Sophus::SE2d, Eigen::Matrix3d > &estimate)
Initialize particles from an estimated pose and covariance.
rclcpp::Service< std_srvs::srv::Empty >::SharedPtr global_localization_server_
Global relocalization service server.
Definition: amcl_node.hpp:157
rclcpp::Subscription< nav_msgs::msg::OccupancyGrid >::SharedPtr map_sub_
Occupancy grid map updates subscription.
Definition: amcl_node.hpp:145
std::unique_ptr< message_filters::Subscriber< sensor_msgs::msg::LaserScan > > laser_scan_sub_
Laser scan updates subscription.
Definition: amcl_node.hpp:148
rclcpp_lifecycle::LifecyclePublisher< nav_msgs::msg::OccupancyGrid >::SharedPtr likelihood_field_pub_
Likelihood field publisher.
Definition: amcl_node.hpp:154
::message_filters::Connection laser_scan_connection_
Connection for laser scan updates filter and callback.
Definition: amcl_node.hpp:164
void do_periodic_timer_callback() override
Callback for periodic particle cloud updates.
void do_initial_pose_callback(geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr) override
Callback for pose (re)initialization.
void do_deactivate(const rclcpp_lifecycle::State &) override
Callback for lifecycle transitions from the ACTIVE state to the INACTIVE state.
void do_cleanup(const rclcpp_lifecycle::State &) override
Callback for lifecycle transitions from the INACTIVE state to the UNCONFIGURED state.
::message_filters::Connection point_cloud_connection_
Connection for point cloud updates filter and callback.
Definition: amcl_node.hpp:170
bool initialize_from_map()
Initialize particles from map.
std::unique_ptr< tf2_ros::MessageFilter< sensor_msgs::msg::LaserScan > > laser_scan_filter_
Transform synchronization filter for laser scan updates.
Definition: amcl_node.hpp:162
auto get_sensor_model(std::string_view, nav_msgs::msg::OccupancyGrid::SharedPtr) const -> beluga_ros::Amcl::sensor_model_variant
Get sensor model as per current parametrization.
std::optional< std::pair< Sophus::SE2d, Eigen::Matrix3d > > last_known_estimate_
Last known pose estimate, if any.
Definition: amcl_node.hpp:175
auto make_particle_filter(nav_msgs::msg::OccupancyGrid::SharedPtr) const -> std::unique_ptr< beluga_ros::Amcl >
Instantiate particle filter given an initial occupancy grid map and the current parametrization.
Definition: ros2_common.hpp:56
Compatibility layer for message_filters.
SparsePointCloud3< float, false > SparsePointCloud3f