fawkes_navgraph_retriever.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * navgraph_retriever.cpp - retrieve navgraph and write to file
3  *
4  * Created: Mon May 15 13:39:21 2017
5  * Copyright 2017 Tim Niemueller [www.niemueller.de]
6  ****************************************************************************/
7 
8 /* This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Library General Public License for more details.
17  *
18  * Read the full text in the LICENSE.GPL file in the doc directory.
19  */
20 
21 #include <ros/ros.h>
22 
23 // from Fawkes
24 #include <core/exception.h>
25 #include <navgraph/navgraph.h>
26 #include <navgraph/navgraph_node.h>
27 #include <navgraph/navgraph_edge.h>
28 #include <navgraph/yaml_navgraph.h>
29 
30 #include <fawkes_msgs/NavGraph.h>
31 
32 #include <boost/filesystem.hpp>
33 
34 #define GET_CONFIG(privn, n, path, var) \
35  if (! privn.getParam(path, var)) { \
36  n.getParam(path, var); \
37  }
38 
40 {
41  public:
43  : n(n)
44  {
45  ros::NodeHandle privn("~");
46  GET_CONFIG(privn, n, "navgraph_file", cfg_navgraph_file_);
47 
48  if (cfg_navgraph_file_.empty()) {
49  throw std::runtime_error("No navgraph file given");
50  }
51 
52  boost::filesystem::path p(cfg_navgraph_file_);
53  p = boost::filesystem::absolute(p);
54  cfg_navgraph_file_ = p.string();
55  ROS_INFO("Using navgraph path: %s", p.string().c_str());
56  if (boost::filesystem::exists(p)) {
57  boost::filesystem::remove(p);
58  }
59  boost::filesystem::create_directories(p.parent_path());
60 
61  sub_has_received_ = false;
62  sub_navgraph_ = n.subscribe<fawkes_msgs::NavGraph>("navgraph", 10, &NavGraphRosRetriever::cb_navgraph, this);
63 
66  }
67 
69  {
71  boost::filesystem::path p(cfg_navgraph_file_);
72  if (boost::filesystem::exists(p)) {
73  boost::filesystem::remove(p);
74  }
75  }
76 
77  /* This timer is a workaround for some ROS issues that fails (not so
78  * infrequently as one would hope) to retrieve the initial message
79  * from a latched publisher.
80  *
81  */
82  void
84  {
85  if (! sub_has_received_) {
86  ROS_INFO("No navgraph received, yet. Re-subscribing to avoid stale latched publisher");
89  n.subscribe<fawkes_msgs::NavGraph>("navgraph", 10, &NavGraphRosRetriever::cb_navgraph, this);
90  }
91  }
92 
93  void
94  cb_navgraph(const fawkes_msgs::NavGraph::ConstPtr& msg)
95  {
96  if (! sub_has_received_) {
97  ROS_INFO("Initial navgraph received, disabling re-connect timer");
98  sub_has_received_ = true;
100  }
101 
102  fawkes::NavGraph n("received");
103  for (size_t i = 0; i < msg->nodes.size(); ++i) {
104  const fawkes_msgs::NavGraphNode &msg_node = msg->nodes[i];
105  //ROS_INFO("Adding Node %s", msg_node.name.c_str());
106  std::map<std::string, std::string> properties;
107  for (size_t j = 0; j < msg_node.properties.size(); ++j) {
108  properties[msg_node.properties[j].key] = msg_node.properties[j].value;
109  }
110  fawkes::NavGraphNode node(msg_node.name, msg_node.pose.x, msg_node.pose.y, properties);
111  node.set_unconnected(msg_node.unconnected);
112  // has_orientation flag irrelevant, just means props have orientation field
113  n.add_node(node);
114  }
115 
116  for (size_t i = 0; i < msg->edges.size(); ++i) {
117  const fawkes_msgs::NavGraphEdge &msg_edge = msg->edges[i];
118  std::map<std::string, std::string> properties;
119  for (size_t j = 0; j < msg_edge.properties.size(); ++j) {
120  properties[msg_edge.properties[j].key] = msg_edge.properties[j].value;
121  }
122  //ROS_INFO("Adding Edge %s %s %s", msg_edge.from_node.c_str(),
123  // msg_edge.directed ? "->" : "--",
124  // msg_edge.to_node.c_str());
125  fawkes::NavGraphEdge edge(msg_edge.from_node, msg_edge.to_node,
126  properties, msg_edge.directed);
127  n.add_edge(edge);
128  }
129  n.calc_reachability(/* allow multigraph */ true);
130  ROS_INFO("Writing YAML navgraph '%s'", cfg_navgraph_file_.c_str());
131  fawkes::save_yaml_navgraph(cfg_navgraph_file_, &n);
132  }
133 
134  private:
136 
137  std::string cfg_navgraph_file_;
138 
142 };
143 
144 int
145 main(int argc, char **argv)
146 {
147  ros::init(argc, argv, "navgraph_retriever");
148 
150  NavGraphRosRetriever navgraph_retriever(n);
151  ros::spin();
152 
153  return 0;
154 }
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
#define GET_CONFIG(privn, n, path, var)
ROSCPP_DECL void spin(Spinner &spinner)
void cb_sub_init_timer(const ros::WallTimerEvent &event)
#define ROS_INFO(...)
WallTimer createWallTimer(WallDuration period, void(T::*callback)(const WallTimerEvent &), T *obj, bool oneshot=false, bool autostart=true) const
void cb_navgraph(const fawkes_msgs::NavGraph::ConstPtr &msg)
NavGraphRosRetriever(ros::NodeHandle &n)
int main(int argc, char **argv)


rcll_fawkes_sim
Author(s): Tim Niemueller
autogenerated on Mon Jun 10 2019 14:31:10