Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
costmap_cost_tool.cpp
1 // Copyright (c) 2024 Jatin Patil
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 #include "nav2_rviz_plugins/costmap_cost_tool.hpp"
16 #include <rviz_common/viewport_mouse_event.hpp>
17 #include "rviz_common/display_context.hpp"
18 #include "rviz_common/load_resource.hpp"
19 #include "rviz_common/interaction/view_picker_iface.hpp"
20 #include "rviz_common/msg_conversions.hpp"
21 #include "rviz_common/properties/bool_property.hpp"
22 
23 namespace nav2_rviz_plugins
24 {
25 CostmapCostTool::CostmapCostTool()
26 : qos_profile_(5)
27 {
28  shortcut_key_ = 'm';
29 
30  auto_deactivate_property_ = new rviz_common::properties::BoolProperty(
31  "Single click", true,
32  "Switch away from this tool after one click.",
33  getPropertyContainer(), SLOT(updateAutoDeactivate()), this);
34 }
35 
36 CostmapCostTool::~CostmapCostTool() {}
37 
38 void CostmapCostTool::onInitialize()
39 {
40  hit_cursor_ = cursor_;
41  std_cursor_ = rviz_common::getDefaultCursor();
42 
43  setName("Costmap Cost");
44  setIcon(rviz_common::loadPixmap("package://rviz_default_plugins/icons/classes/PointStamped.png"));
45 
46  node_ = context_->getRosNodeAbstraction().lock()->get_raw_node();
47  local_cost_client_ =
48  node_->create_client<nav2_msgs::srv::GetCost>("local_costmap/get_cost_local_costmap");
49  global_cost_client_ =
50  node_->create_client<nav2_msgs::srv::GetCost>("global_costmap/get_cost_global_costmap");
51 }
52 
53 void CostmapCostTool::activate() {}
54 void CostmapCostTool::deactivate() {}
55 
56 int CostmapCostTool::processMouseEvent(rviz_common::ViewportMouseEvent & event)
57 {
58  int flags = 0;
59 
60  Ogre::Vector3 position;
61  bool success = context_->getViewPicker()->get3DPoint(event.panel, event.x, event.y, position);
62  setCursor(success ? hit_cursor_ : std_cursor_);
63 
64  if (success) {
65  std::ostringstream s;
66  s << "<b>Left-Click:</b> Select this point.";
67  s.precision(3);
68  s << " [" << position.x << "," << position.y << "," << position.z << "]";
69  setStatus(s.str().c_str());
70 
71  if (event.leftUp()) {
72  auto point = rviz_common::pointOgreToMsg(position);
73 
74  callCostService(point.x, point.y);
75 
76  if (auto_deactivate_property_->getBool()) {
77  flags |= Finished;
78  }
79  }
80  } else {
81  setStatus("Move over an object to select the target point.");
82  }
83  return flags;
84 }
85 
86 void CostmapCostTool::callCostService(float x, float y)
87 {
88  // Create request for local costmap
89  auto request = std::make_shared<nav2_msgs::srv::GetCost::Request>();
90  request->x = x;
91  request->y = y;
92 
93  // Call local costmap service
94  if (local_cost_client_->wait_for_service(std::chrono::seconds(1))) {
95  local_cost_client_->async_send_request(request,
96  std::bind(&CostmapCostTool::handleLocalCostResponse, this, std::placeholders::_1));
97  }
98 
99  // Call global costmap service
100  if (global_cost_client_->wait_for_service(std::chrono::seconds(1))) {
101  global_cost_client_->async_send_request(request,
102  std::bind(&CostmapCostTool::handleGlobalCostResponse, this, std::placeholders::_1));
103  }
104 }
105 
106 void CostmapCostTool::handleLocalCostResponse(
107  rclcpp::Client<nav2_msgs::srv::GetCost>::SharedFuture future)
108 {
109  auto response = future.get();
110  if (response->cost != -1) {
111  RCLCPP_INFO(node_->get_logger(), "Local costmap cost: %.1f", response->cost);
112  } else {
113  RCLCPP_ERROR(node_->get_logger(), "Failed to get local costmap cost");
114  }
115 }
116 
117 void CostmapCostTool::handleGlobalCostResponse(
118  rclcpp::Client<nav2_msgs::srv::GetCost>::SharedFuture future)
119 {
120  auto response = future.get();
121  if (response->cost != -1) {
122  RCLCPP_INFO(node_->get_logger(), "Global costmap cost: %.1f", response->cost);
123  } else {
124  RCLCPP_ERROR(node_->get_logger(), "Failed to get global costmap cost");
125  }
126 }
127 } // namespace nav2_rviz_plugins
128 
129 #include <pluginlib/class_list_macros.hpp>
130 PLUGINLIB_EXPORT_CLASS(nav2_rviz_plugins::CostmapCostTool, rviz_common::Tool)