47 #include "nav2_map_server/map_server.hpp"
55 #include "yaml-cpp/yaml.h"
56 #include "lifecycle_msgs/msg/state.hpp"
57 #include "nav2_map_server/map_io.hpp"
59 using namespace std::chrono_literals;
60 using namespace std::placeholders;
62 namespace nav2_map_server
65 MapServer::MapServer(
const rclcpp::NodeOptions & options)
66 : nav2::LifecycleNode(
"map_server",
"", options), map_available_(false)
68 RCLCPP_INFO(get_logger(),
"Creating");
71 declare_parameter(
"yaml_filename", rclcpp::PARAMETER_STRING);
72 declare_parameter(
"topic_name",
"map");
73 declare_parameter(
"frame_id",
"map");
83 RCLCPP_INFO(get_logger(),
"Configuring");
86 std::string yaml_filename = get_parameter(
"yaml_filename").as_string();
87 std::string topic_name = get_parameter(
"topic_name").as_string();
88 frame_id_ = get_parameter(
"frame_id").as_string();
91 if (!yaml_filename.empty()) {
94 std::shared_ptr<nav2_msgs::srv::LoadMap::Response> rsp =
95 std::make_shared<nav2_msgs::srv::LoadMap::Response>();
98 throw std::runtime_error(
"Failed to load map yaml file: " + yaml_filename);
103 "yaml-filename parameter is empty, set map through '%s'-service",
104 load_map_service_name_.c_str());
108 const std::string service_prefix = get_name() + std::string(
"/");
111 occ_service_ = create_service<nav_msgs::srv::GetMap>(
112 service_prefix + std::string(service_name_),
116 occ_pub_ = create_publisher<nav_msgs::msg::OccupancyGrid>(
121 load_map_service_ = create_service<nav2_msgs::srv::LoadMap>(
122 service_prefix + std::string(load_map_service_name_),
125 return nav2::CallbackReturn::SUCCESS;
131 RCLCPP_INFO(get_logger(),
"Activating");
134 occ_pub_->on_activate();
135 if (map_available_) {
136 auto occ_grid = std::make_unique<nav_msgs::msg::OccupancyGrid>(msg_);
137 occ_pub_->publish(std::move(occ_grid));
143 return nav2::CallbackReturn::SUCCESS;
149 RCLCPP_INFO(get_logger(),
"Deactivating");
151 occ_pub_->on_deactivate();
156 return nav2::CallbackReturn::SUCCESS;
162 RCLCPP_INFO(get_logger(),
"Cleaning up");
165 occ_service_.reset();
166 load_map_service_.reset();
167 map_available_ =
false;
168 msg_ = nav_msgs::msg::OccupancyGrid();
170 return nav2::CallbackReturn::SUCCESS;
176 RCLCPP_INFO(get_logger(),
"Shutting down");
177 return nav2::CallbackReturn::SUCCESS;
181 const std::shared_ptr<rmw_request_id_t>,
182 const std::shared_ptr<nav_msgs::srv::GetMap::Request>,
183 std::shared_ptr<nav_msgs::srv::GetMap::Response> response)
186 if (get_current_state().
id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
189 "Received GetMap request but not in ACTIVE state, ignoring!");
192 RCLCPP_INFO(get_logger(),
"Handling GetMap request");
193 response->map = msg_;
197 const std::shared_ptr<rmw_request_id_t>,
198 const std::shared_ptr<nav2_msgs::srv::LoadMap::Request> request,
199 std::shared_ptr<nav2_msgs::srv::LoadMap::Response> response)
202 if (get_current_state().
id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
205 "Received LoadMap request but not in ACTIVE state, ignoring!");
206 response->result = response->RESULT_UNDEFINED_FAILURE;
209 RCLCPP_INFO(get_logger(),
"Handling LoadMap request");
212 auto occ_grid = std::make_unique<nav_msgs::msg::OccupancyGrid>(msg_);
213 occ_pub_->publish(std::move(occ_grid));
218 const std::string & yaml_file,
219 std::shared_ptr<nav2_msgs::srv::LoadMap::Response> response)
221 switch (loadMapFromYaml(yaml_file, msg_)) {
222 case MAP_DOES_NOT_EXIST:
223 response->result = nav2_msgs::srv::LoadMap::Response::RESULT_MAP_DOES_NOT_EXIST;
225 case INVALID_MAP_METADATA:
226 response->result = nav2_msgs::srv::LoadMap::Response::RESULT_INVALID_MAP_METADATA;
228 case INVALID_MAP_DATA:
229 response->result = nav2_msgs::srv::LoadMap::Response::RESULT_INVALID_MAP_DATA;
231 case LOAD_MAP_SUCCESS:
235 map_available_ =
true;
236 response->map = msg_;
237 response->result = nav2_msgs::srv::LoadMap::Response::RESULT_SUCCESS;
245 msg_.info.map_load_time = now();
246 msg_.header.frame_id = frame_id_;
247 msg_.header.stamp = now();
252 #include "rclcpp_components/register_node_macro.hpp"
void destroyBond()
Destroy bond connection to lifecycle manager.
void createBond()
Create bond connection to lifecycle manager.
A QoS profile for latched, reliable topics with a history of 1 messages.
Parses the map yaml file and creates a service and a publisher that provides occupancy grid.
nav2::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Start publishing the map using the latched topic.
void loadMapCallback(const std::shared_ptr< rmw_request_id_t > request_header, const std::shared_ptr< nav2_msgs::srv::LoadMap::Request > request, std::shared_ptr< nav2_msgs::srv::LoadMap::Response > response)
Map loading service callback.
void getMapCallback(const std::shared_ptr< rmw_request_id_t > request_header, const std::shared_ptr< nav_msgs::srv::GetMap::Request > request, std::shared_ptr< nav_msgs::srv::GetMap::Response > response)
Map getting service callback.
void updateMsgHeader()
Method correcting msg_ header when it belongs to instantiated object.
~MapServer()
A Destructor for nav2_map_server::MapServer.
bool loadMapResponseFromYaml(const std::string &yaml_file, std::shared_ptr< nav2_msgs::srv::LoadMap::Response > response)
Load the map YAML, image from map file name and generate output response containing an OccupancyGrid....
nav2::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Called when in Shutdown state.
nav2::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Sets up required params and services. Loads map and its parameters from the file.
nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Stops publishing the latched topic.
nav2::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Resets the member variables.