YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
Map2D_nws_ros2.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#ifndef _USE_MATH_DEFINES
7#define _USE_MATH_DEFINES
8#endif
9
10#include "Map2D_nws_ros2.h"
11
12#include <chrono>
13#include <vector>
14#include <cmath>
15#include <yarp/dev/IMap2D.h>
18#include <yarp/math/Math.h>
19#include <yarp/os/Log.h>
21#include <yarp/os/LogStream.h>
22#include <mutex>
23#include <cstdlib>
24#include <fstream>
25#include <Ros2Utils.h>
26#include <rclcpp/qos.hpp>
27
28using namespace yarp::sig;
29using namespace yarp::dev;
30using namespace yarp::dev::Nav2D;
31using namespace yarp::os;
32using namespace std;
33using namespace std::placeholders;
34
35namespace {
36YARP_LOG_COMPONENT(MAP2D_NWS_ROS2, "yarp.device.map2D_nws_ros2")
37}
38
39
42
44{
45 if (driver->isValid())
46 {
47 driver->view(m_iMap2D);
49 m_iMap2D->get_map_names(maps);
50 m_currentMapName = maps[0];
51 }
52
53 if (nullptr == m_iMap2D)
54 {
55 yCError(MAP2D_NWS_ROS2, "Subdevice passed to attach method is invalid");
56 return false;
57 }
58
59 return true;
60}
61
63{
64 m_iMap2D = nullptr;
65 return true;
66}
67
69{
70 parseParams(config);
71
72 if(m_name[0] == '/'){
73 yCError(MAP2D_NWS_ROS2) << "Nws name parameter cannot begin with an initial /";
74 return false;
75 }
76
77 m_rpcPortName = "/"+m_name+"/rpc";
78
79 //open rpc port
80 if (!m_rpcPort.open(m_rpcPortName))
81 {
82 yCError(MAP2D_NWS_ROS2, "Failed to open port %s", m_rpcPortName.c_str());
83 return false;
84 }
85 m_rpcPort.setReader(*this);
86
87 //ROS2 configuration
88 if(m_node_name[0] == '/'){
89 yCError(MAP2D_NWS_ROS2) << "node_name cannot begin with an initial /";
90 return false;
91 }
95 qos.depth=10;
96 rmw_time_t time;
97 time.sec=10000;
98 time.nsec = 0;
99 qos.deadline= time;
100 qos.lifespan=time;
101 qos.liveliness_lease_duration=time;
105 qos.avoid_ros_namespace_conventions = true;
106 m_ros2Service_getMap = m_node->create_service<nav_msgs::srv::GetMap>(m_getmap,
107 std::bind(&Map2D_nws_ros2::getMapCallback,this,_1,_2,_3),qos );
108 m_ros2Service_getMapByName = m_node->create_service<map2d_nws_ros2_msgs::srv::GetMapByName>(m_getmapbyname,
109 std::bind(&Map2D_nws_ros2::getMapByNameCallback,this,_1,_2,_3));
110 m_ros2Service_rosCmdParser = m_node->create_service<test_msgs::srv::BasicTypes>(m_roscmdparser,
111 std::bind(&Map2D_nws_ros2::rosCmdParserCallback,this,_1,_2,_3));
112
113 yCInfo(MAP2D_NWS_ROS2) << "Waiting for device to attach";
114 start();
115
116 return true;
117}
118
119
121{
122
123// if(!m_spinned) //This is just a temporary solution.
124// {
125// rclcpp::spin(m_node);
126// m_spinned = true;
127// }
128}
129
131{
132 yCTrace(MAP2D_NWS_ROS2, "Close");
133 m_rpcPort.close();
134 rclcpp::shutdown();
135 return true;
136}
137
139{
140 yCWarning(MAP2D_NWS_ROS2) << "not yet implemented";
141
142 std::lock_guard<std::mutex> lock(m_mutex);
145 bool ok = in.read(connection);
146 if (!ok) return false;
147
148 //parse string command
149 if(in.get(0).isString())
150 {
151 // parse_string_command(in, out);
152 }
153 // parse vocab command
154 else if(in.get(0).isVocab32())
155 {
156 // parse_vocab_command(in, out);
157 }
158
160 if (returnToSender != nullptr)
161 {
162 out.write(*returnToSender);
163 }
164 else
165 {
166 yCError(MAP2D_NWS_ROS2) << "Invalid return to sender";
167 }
168 return true;
169}
170
172{
173 if (!m_ros2Publisher_markers)
174 {
175 m_ros2Publisher_markers = m_node->create_publisher<visualization_msgs::msg::MarkerArray>(m_markers_pub, 10);
176 }
177 builtin_interfaces::msg::Duration dur;
178 dur.sec = 0xFFFFFFFF;
180 uint64_t time;
182 rclcpp::Time ret;
183 time = (uint64_t)(yarpTimeStamp * 1000000000UL);
184 sec_part = (time / 1000000000UL);
185 if (sec_part > std::numeric_limits<unsigned int>::max())
186 {
187 yCWarning(MAP2D_NWS_ROS2) << "Timestamp exceeded the 64 bit representation, resetting it to 0";
188 sec_part = 0;
189 }
190 visualization_msgs::msg::Marker marker;
191 builtin_interfaces::msg::Time tt;
192 yarp::sig::Vector rpy(3);
194 visualization_msgs::msg::MarkerArray markers;
195
196 std::vector<std::string> locations;
197 int count = 1;
198 m_iMap2D->getLocationsList(locations);
199 for (auto it : locations)
200 {
202 m_iMap2D->getLocation(it, loc);
203
204 if(loc.map_id != m_currentMapName && m_currentMapName != "none")
205 {
206 continue;
207 }
208
209 rpy[0] = 0; //x
210 rpy[1] = 0; //y
211 rpy[2] = loc.theta / 180 * M_PI; //z
213 q.fromRotationMatrix(m);
214
215 marker.header.frame_id = "map";
217 marker.header.stamp = tt;
218 marker.ns = m_markers_pub+"_ns";
219 marker.id = count;
220 marker.type = visualization_msgs::msg::Marker::ARROW;//yarp::rosmsg::visualization_msgs::Marker::ARROW;
221 marker.action = visualization_msgs::msg::Marker::ADD;//yarp::rosmsg::visualization_msgs::Marker::ADD;
222 marker.pose.position.x = loc.x;
223 marker.pose.position.y = loc.y;
224 marker.pose.position.z = 0;
225 marker.pose.orientation.x = q.x();
226 marker.pose.orientation.y = q.y();
227 marker.pose.orientation.z = q.z();
228 marker.pose.orientation.w = q.w();
229 marker.scale.x = 1;
230 marker.scale.y = 0.1;
231 marker.scale.z = 0.1;
232 marker.color.a = 1.0;
233 marker.color.r = 0.0;
234 marker.color.g = 1.0;
235 marker.color.b = 0.0;
236 marker.lifetime = dur;
237 marker.text = it;
238 markers.markers.push_back(marker);
239 count++;
240 }
241
242 m_ros2Publisher_markers->publish(markers);
243 return true;
244}
245
246
247void Map2D_nws_ros2::getMapCallback(const std::shared_ptr<rmw_request_id_t> request_header,
248 const std::shared_ptr<nav_msgs::srv::GetMap::Request> request,
249 std::shared_ptr<nav_msgs::srv::GetMap::Response> response)
250{
251 yCWarning(MAP2D_NWS_ROS2) << "Not yet implemented";
252 nav_msgs::msg::OccupancyGrid mapToGo;
253 mapToGo.header.frame_id = "map";
254
255 response->map = mapToGo;
256}
257
258void Map2D_nws_ros2::rosCmdParserCallback(const std::shared_ptr<rmw_request_id_t> request_header,
259 const std::shared_ptr<test_msgs::srv::BasicTypes::Request> request,
260 std::shared_ptr<test_msgs::srv::BasicTypes::Response> response)
261{
262 if(request->string_value == "updatemarkerviz")
263 {
264 if(updateVizMarkers()) response->set__string_value("done");
265 else response->set__string_value("error");
266 }
267 else
268 {
269 response->set__string_value("unknown_command");
270 }
271}
272
273//void Map2D_nws_ros2::prepareMapMsg(MapGrid2D inputMap, nav_msgs::msg::OccupancyGrid &outputMsg)
274void Map2D_nws_ros2::getMapByNameCallback(const std::shared_ptr<rmw_request_id_t> request_header,
275 const std::shared_ptr<map2d_nws_ros2_msgs::srv::GetMapByName::Request> request,
276 std::shared_ptr<map2d_nws_ros2_msgs::srv::GetMapByName::Response> response)
277{
278 if (!m_ros2Publisher_map)
279 {
280 m_ros2Publisher_map = m_node->create_publisher<nav_msgs::msg::OccupancyGrid>(m_getmapbyname+"/pub", 10);
281 }
282 nav_msgs::msg::OccupancyGrid mapToGo;
283 nav_msgs::msg::MapMetaData metaToGo;
284 mapToGo.header.frame_id = "map";
286 if(!m_iMap2D->get_map(request->name,theMap))
287 {
288 mapToGo.header.frame_id = "invalid_frame";
289 response->map = mapToGo;
290 return;
291 }
292 mapToGo.info.map_load_time = m_node->get_clock()->now();
293 mapToGo.header.stamp = m_node->get_clock()->now();
294 mapToGo.info.height = theMap.height();
295 mapToGo.info.width = theMap.width();
296
297 double DEG2RAD = M_PI/180.0;
298 double tmp=0;
299 theMap.getResolution(tmp);
300 mapToGo.info.resolution=tmp;
301 double x, y, t;
302 theMap.getOrigin(x,y,t);
303 mapToGo.info.origin.position.x=x;
304 mapToGo.info.origin.position.y=y;
307 v[0]=0; v[1]=0; v[2]=1; v[3]=t*DEG2RAD;
308 q.fromAxisAngle(v);
309 mapToGo.info.origin.orientation.x = q.x();
310 mapToGo.info.origin.orientation.y = q.y();
311 mapToGo.info.origin.orientation.z = q.z();
312 mapToGo.info.origin.orientation.w = q.w();
313 mapToGo.data.resize(theMap.width()*theMap.height());
314 int index=0;
316 for (cell.y=theMap.height(); cell.y-- > 0;)
317 {
318 for (cell.x=0; cell.x<theMap.width(); cell.x++)
319 {
320 theMap.getOccupancyData(cell,tmp);
321 mapToGo.data[index++]=(int)tmp;
322 }
323 }
324
325 response->map = mapToGo;
326 m_currentMapName = request->name;
327
328 metaToGo.map_load_time = mapToGo.info.map_load_time;
329 metaToGo.height = theMap.height();
330 metaToGo.width = theMap.width();
331 metaToGo.origin = mapToGo.info.origin;
332 metaToGo.resolution = mapToGo.info.resolution;
333
334 if (m_ros2Publisher_map)
335 {
336 m_ros2Publisher_map->publish(mapToGo);
337 }
338}
#define M_PI
bool ret
#define DEG2RAD
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
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)
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
void getMapByNameCallback(const std::shared_ptr< rmw_request_id_t > request_header, const std::shared_ptr< map2d_nws_ros2_msgs::srv::GetMapByName::Request > request, std::shared_ptr< map2d_nws_ros2_msgs::srv::GetMapByName::Response > response)
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
bool close() override
Close the DeviceDriver.
bool attach(yarp::dev::PolyDriver *driver) override
Attach to another object.
void rosCmdParserCallback(const std::shared_ptr< rmw_request_id_t > request_header, const std::shared_ptr< test_msgs::srv::BasicTypes::Request > request, std::shared_ptr< test_msgs::srv::BasicTypes::Response > response)
void run() override
Main body of the new thread.
bool detach() override
Detach the object (you must have first called attach).
static rclcpp::Node::SharedPtr createNode(std::string name)
Definition Ros2Utils.cpp:9
bool view(T *&x)
Get an interface to the device driver.
std::string map_id
name of the map
double theta
orientation [deg] in the map reference frame
double y
y position of the location [m], expressed in the map reference frame
double x
x position of the location [m], expressed in the map reference frame
virtual yarp::dev::ReturnValue get_map_names(std::vector< std::string > &map_names)=0
Gets a list containing the names of all registered maps.
virtual yarp::dev::ReturnValue getLocationsList(std::vector< std::string > &locations)=0
Get a list of the names of all stored locations.
virtual yarp::dev::ReturnValue get_map(std::string map_name, yarp::dev::Nav2D::MapGrid2D &map)=0
Gets a map from the map server.
virtual yarp::dev::ReturnValue getLocation(std::string location_name, yarp::dev::Nav2D::Map2DLocation &loc)=0
Retrieves a location specified by the user in the world reference frame.
A container for a device driver.
Definition PolyDriver.h:23
bool isValid() const
Check if device is valid.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void setReader(PortReader &reader) override
Set an external reader for port data.
void close() override
Stop port activity.
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition Bottle.cpp:240
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition Bottle.cpp:230
A mini-server for performing network communication in the background.
An interface for reading from a network connection.
An interface for writing to a network connection.
A base class for nested structures that can be searched.
Definition Searchable.h:31
bool start()
Start the new thread running.
Definition Thread.cpp:93
virtual bool isString() const
Checks if value is a string.
Definition Value.cpp:156
virtual bool isVocab32() const
Checks if value is a vocabulary identifier.
Definition Value.cpp:174
A class for a Matrix.
Definition Matrix.h:39
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
STL namespace.
For streams capable of holding different kinds of content, check what they actually have.
yarp::sig::Matrix rpy2dcm(const yarp::sig::Vector &rpy)
Converts roll-pitch-yaw angles in the corresponding dcm (direction cosine matrix) rotation matrix (de...
Definition math.cpp:847
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
An interface to the operating system, including Port based communication.
std::uint32_t NetUint32
Definition of the NetUint32 type.
Definition NetUint32.h:29