CConnectionManager.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) | |
3  http://www.mrpt.org/ | | | | Copyright (c)
4  2005-2016, Individual contributors, see AUTHORS file | | See:
5  http://www.mrpt.org/Authors - All rights reserved. | |
6  Released under BSD License. See details in http://www.mrpt.org/License |
7  +---------------------------------------------------------------------------+
8  */
9 
11 
12 using namespace mrpt::graphslam::detail;
13 using namespace std;
14 using namespace mrpt::system;
15 using namespace mrpt::math;
16 using namespace fkie_multimaster_msgs;
17 
19  const fkie_multimaster_msgs::ROSMaster& master1,
20  const fkie_multimaster_msgs::ROSMaster& master2)
21 {
22  return master1.uri == master2.uri;
23 }
25  const fkie_multimaster_msgs::ROSMaster& master1,
26  const fkie_multimaster_msgs::ROSMaster& master2)
27 {
28  return !(master1 == master2);
29 }
30 
32  const mrpt_msgs::GraphSlamAgent& agent1,
33  const mrpt_msgs::GraphSlamAgent& agent2)
34 {
35  return (
36  agent1.agent_id == agent2.agent_id &&
37  agent1.topic_namespace.data == agent2.topic_namespace.data);
38 }
40 
42  const mrpt_msgs::GraphSlamAgent& agent1,
43  const mrpt_msgs::GraphSlamAgent& agent2)
44 {
45  return !(agent1 == agent2);
46 }
47 
48 bool operator<(
49  const mrpt_msgs::GraphSlamAgent& agent1,
50  const mrpt_msgs::GraphSlamAgent& agent2)
51 {
52  return agent1.agent_id < agent2.agent_id;
53 }
55 
57  const fkie_multimaster_msgs::ROSMaster& master,
58  const mrpt_msgs::GraphSlamAgent& agent)
59 {
60  return (master.name == agent.name.data);
61 }
62 
64  const fkie_multimaster_msgs::ROSMaster& master,
65  const mrpt_msgs::GraphSlamAgent& agent)
66 {
67  return !(master == agent);
68 }
69 
71  const mrpt_msgs::GraphSlamAgent& agent,
72  const fkie_multimaster_msgs::ROSMaster& master)
73 {
74  return (master == agent);
75 }
77  const mrpt_msgs::GraphSlamAgent& agent,
78  const fkie_multimaster_msgs::ROSMaster& master)
79 {
80  return (master != agent);
81 }
82 
84 
86  mrpt::system::COutputLogger* logger, ros::NodeHandle* nh_in)
87  : m_logger(logger), m_nh(nh_in), has_setup_comm(false)
88 {
89  ASSERT_(m_logger);
90  ASSERT_(m_nh);
91 
92  {
93  std::string own_ns_tmp = m_nh->getNamespace();
94  // ignore starting "/" characters
95  own_ns = std::string(
96  own_ns_tmp.begin() + own_ns_tmp.find_first_not_of(" /"),
97  own_ns_tmp.end());
98  }
99 
100  // keep this call below the topic names initializations
101  this->setupComm();
102 }
103 
105 
106 const std::string& CConnectionManager::getTrimmedNs() const { return own_ns; }
107 
109  mrpt_msgs::GraphSlamAgents* agents_vec, bool ignore_self /*= true */)
110 {
111  ASSERTMSG_(agents_vec, "Invalid pointer to vector of GraphSlam Agents.");
112  this->updateNearbySlamAgents();
113  *agents_vec = m_nearby_slam_agents;
114 
115  if (ignore_self)
116  {
117  // remove the GraphSlamAgent instance whose topic namespace coincedes
118  // with the namespace that the CConnectionManager instance is running
119  // under.
120  auto search = [this](const mrpt_msgs::GraphSlamAgent& agent) {
121  return (agent.topic_namespace.data == this->own_ns);
122  };
123  agents_it it =
124  find_if(agents_vec->list.begin(), agents_vec->list.end(), search);
125 
126  // TODO - fix the following
127  // this agent should always exist
128  // TODO - well, sometimes it doesn't, investigate this
129  // UPDATE: Even when /master_discovery node is up the agents vector
130  // might be empty.
131  // ASSERT_(it != agents_vec->list.end());
132  if (it != agents_vec->list.end())
133  {
134  agents_vec->list.erase(it);
135  }
136  else
137  {
138  }
139  }
140 }
141 
142 const mrpt_msgs::GraphSlamAgents&
144 {
145  return m_nearby_slam_agents;
146 }
147 
148 const mrpt_msgs::GraphSlamAgents& CConnectionManager::getNearbySlamAgents()
149 {
150  this->updateNearbySlamAgents();
151  return this->getNearbySlamAgentsCached();
152 } // end of getNearbySlamAgents
153 
155 {
156  using ::operator==;
157  using namespace mrpt::math;
158  ASSERT_(has_setup_comm);
159 
160  DiscoverMasters srv;
161 
162  // ask for the agents in the neighborhood
164  std::vector<ROSMaster>* masters = &(srv.response.masters);
165 
166  // convert RosMaster(s) to mrpt_msgs::GraphSlamAgent(s)
167  for (std::vector<ROSMaster>::const_iterator masters_it = masters->begin();
168  masters_it != masters->end(); ++masters_it)
169  {
170  // 3 cases:
171  // In RosMasters AND In mrpt_msgs::GraphSlamAgents => update
172  // relevant fields In RosMasters AND NOT In
173  // mrpt_msgs::GraphSlamAgents => add it to mrpt_msgs::GraphSlamAgents
174  // NOT In RosMasters AND In mrpt_msgs::GraphSlamAgents => Do
175  // nothing.
176 
177  // have I already registered the current agent?
178  auto search = [masters_it](const mrpt_msgs::GraphSlamAgent& agent) {
179  return agent == *masters_it;
180  };
181  agents_it it = find_if(
182  m_nearby_slam_agents.list.begin(), m_nearby_slam_agents.list.end(),
183  search);
184 
185  if (it != m_nearby_slam_agents.list.end())
186  { // found, update relevant fields
187  // update timestamp
188  it->last_seen_time.data = ros::Time((*masters_it).last_change);
189  }
190  else
191  { // not found, try to insert it.
192  mrpt_msgs::GraphSlamAgent new_agent;
193  bool is_agent = this->convert(*masters_it, &new_agent);
194  if (is_agent)
195  {
196  m_nearby_slam_agents.list.push_back(new_agent);
197  };
198  }
199 
200  } // for all ROSMaster(s)
201 
202 } // end of updateNearbySlamAgents
203 
205 {
206  this->setupSubs();
207  this->setupPubs();
208  this->setupSrvs();
209 
210  has_setup_comm = true;
211 } // end of setupComm
212 
216 {
217  // call to the querier should be made after the
218  // fkie_multimaster_msgs::DiscoverMaster service is up and running
220  m_nh->serviceClient<fkie_multimaster_msgs::DiscoverMasters>(
221  "/master_discovery/list_masters");
222 
223  // ASSERT_(m_DiscoverMasters_client.isValid());
224 }
225 
227  const fkie_multimaster_msgs::ROSMaster& ros_master,
228  mrpt_msgs::GraphSlamAgent* slam_agent)
229 {
230  ASSERT_(slam_agent);
231  bool agent_namespace_found = false;
232 
233  slam_agent->name.data = ros_master.name;
234  slam_agent->is_online.data = static_cast<bool>(ros_master.online);
235 
236  // ip_address, hostname, port
237  std::string ip_addr =
238  CConnectionManager::extractHostnameOrIP(ros_master.monitoruri);
239  slam_agent->ip_addr.data = ip_addr;
240  std::string hostname = CConnectionManager::extractHostnameOrIP(
241  ros_master.uri, &slam_agent->port);
242  slam_agent->hostname.data = hostname;
243 
244  // agent_id - last field of the IP address
245  vector<string> tokens;
246  mrpt::system::tokenize(ip_addr, ".", tokens);
247  slam_agent->agent_id = atoi(tokens.rbegin()->c_str());
248 
249  // robot topic namespace
250  {
251  // stringstream ss("");
252  // ss << slam_agent->name.data << "_" << slam_agent->agent_id;
253  // slam_agent->topic_namespace.data = ss.str().c_str();
254  slam_agent->topic_namespace.data = slam_agent->name.data;
255 
256  // assert that there exists a subtopic namespace named feedback under
257  // this.
259  bool got_topics = ros::master::getTopics(topics);
260  ASSERTMSG_(got_topics, "Unable to fetch topics. Exiting.");
261 
262  // get the namespaces under the current topic_namespace
263  const std::string& topic_ns = "/" + slam_agent->topic_namespace.data;
264  // TODO - What if this topic changes? from the configuration file
265  const std::string& feedback_ns =
266  "/" + slam_agent->topic_namespace.data + "/" + "feedback";
267 
268  auto search = [&feedback_ns](const ros::master::TopicInfo& topic) {
269  return (strStarts(topic.name, feedback_ns));
270  };
271  ros::master::V_TopicInfo::const_iterator cit =
272  find_if(topics.begin(), topics.end(), search);
273  if (cit != topics.end())
274  {
275  agent_namespace_found = true;
276  }
277  }
278 
279  // timestamp
280  slam_agent->last_seen_time.data = ros::Time(ros_master.last_change);
281  return agent_namespace_found;
282 
283 } // end of convert
284 
286  const mrpt_msgs::GraphSlamAgent& slam_agent,
287  fkie_multimaster_msgs::ROSMaster* ros_master)
288 {
289  ASSERT_(ros_master);
290 
291  ros_master->name = slam_agent.name.data;
292  {
293  stringstream ss("");
294  ss << "http://" << slam_agent.ip_addr << ":" << slam_agent.port;
295  ros_master->uri = ss.str();
296  }
297  ros_master->online = slam_agent.is_online.data;
298  ros_master->discoverer_name = "/master_discovery";
299 
300  // TODO - timestamp
301 }
302 
304  const std::string& str, unsigned short* agent_port /*=NULL*/)
305 {
306  // example for monitoruri: http://nickkouk-ubuntu:11311/
307  std::string s = std::string(str.begin() + 7, str.end());
308 
309  vector<string> tokens;
310  mrpt::system::tokenize(s, ":", tokens);
311 
312  if (agent_port)
313  {
314  *agent_port = static_cast<unsigned short>(atoi(tokens[1].c_str()));
315  }
316 
317  return tokens[0];
318 }
operator!=
bool operator!=(const fkie_multimaster_msgs::ROSMaster &master1, const fkie_multimaster_msgs::ROSMaster &master2)
Definition: CConnectionManager.cpp:24
mrpt::graphslam::detail::CConnectionManager::m_nh
ros::NodeHandle * m_nh
Pointer to the Ros NodeHanle instance.
Definition: CConnectionManager.h:135
mrpt::graphslam::detail::CConnectionManager::~CConnectionManager
~CConnectionManager()
Destructor.
Definition: CConnectionManager.cpp:104
mrpt::graphslam::detail::CConnectionManager::own_ns
std::string own_ns
Namespace under which we are running. Corresponds to the agent_ID_str with which the nodes are going ...
Definition: CConnectionManager.h:88
CConnectionManager.h
s
XmlRpcServer s
mrpt::graphslam::detail::CConnectionManager::m_DiscoverMasters_client
ros::ServiceClient m_DiscoverMasters_client
Definition: CConnectionManager.h:137
ros::NodeHandle::serviceClient
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
mrpt::graphslam::detail::CConnectionManager::convert
static bool convert(const fkie_multimaster_msgs::ROSMaster &ros_master, mrpt_msgs::GraphSlamAgent *slam_agent)
ROSMaster ==> mrpt_msgs::GraphSlamAgent.
Definition: CConnectionManager.cpp:226
mrpt::graphslam::detail::CConnectionManager::getTrimmedNs
const std::string & getTrimmedNs() const
Get the agent ROS namespace.
Definition: CConnectionManager.cpp:106
ros::master::getTopics
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
rename_rviz_topics.logger
logger
Definition: rename_rviz_topics.py:31
operator<
bool operator<(const mrpt_msgs::GraphSlamAgent &agent1, const mrpt_msgs::GraphSlamAgent &agent2)
Definition: CConnectionManager.cpp:48
mrpt::graphslam::detail::CConnectionManager::setupSubs
void setupSubs()
Definition: CConnectionManager.cpp:213
ros::master::V_TopicInfo
std::vector< TopicInfo > V_TopicInfo
mrpt::graphslam::detail::CConnectionManager::CConnectionManager
CConnectionManager(mrpt::system::COutputLogger *logger, ros::NodeHandle *nh_in)
Constructor.
Definition: CConnectionManager.cpp:85
mrpt::graphslam::detail::CConnectionManager::agents_it
mrpt_msgs::GraphSlamAgents::_list_type::iterator agents_it
Definition: CConnectionManager.h:46
mrpt::graphslam::detail::CConnectionManager::getNearbySlamAgentsCached
const mrpt_msgs::GraphSlamAgents & getNearbySlamAgentsCached() const
Read-only method for accessing list of nearby agents. This doesn't update the internal list of GraphS...
Definition: CConnectionManager.cpp:143
search
ROSCPP_DECL bool search(const std::string &key, std::string &result)
mrpt::graphslam::detail::CConnectionManager::m_logger
mrpt::system::COutputLogger * m_logger
Pointer to the logging instance.
Definition: CConnectionManager.h:133
operator==
bool operator==(const fkie_multimaster_msgs::ROSMaster &master1, const fkie_multimaster_msgs::ROSMaster &master2)
ROSMaster instances are considered the same if the "uri" field is the same.
Definition: CConnectionManager.cpp:18
mrpt::graphslam::detail::CConnectionManager::m_nearby_slam_agents
mrpt_msgs::GraphSlamAgents m_nearby_slam_agents
List of slam agents in the current agent's neighborhood.
Definition: CConnectionManager.h:143
mrpt::graphslam::detail::CConnectionManager::setupComm
void setupComm()
Wrapper method around the private setup* class methods.
Definition: CConnectionManager.cpp:204
mrpt::graphslam::detail::CConnectionManager::setupPubs
void setupPubs()
Definition: CConnectionManager.cpp:214
ros::Time
std
mrpt::graphslam::detail
Definition: CConnectionManager.h:35
ros::ServiceClient::call
bool call(const MReq &req, MRes &resp, const std::string &service_md5sum)
mrpt::math
Definition: CGraphSlamEngine_MR_impl.h:19
mrpt::graphslam::detail::CConnectionManager::has_setup_comm
bool has_setup_comm
Definition: CConnectionManager.h:145
mrpt::graphslam::detail::CConnectionManager::getNearbySlamAgents
const mrpt_msgs::GraphSlamAgents & getNearbySlamAgents()
Read-only method for accessing list of nearby agents.
Definition: CConnectionManager.cpp:148
ros::NodeHandle::getNamespace
const std::string & getNamespace() const
mrpt::graphslam::detail::CConnectionManager::extractHostnameOrIP
static std::string extractHostnameOrIP(const std::string &str, unsigned short *agent_port=NULL)
Remove http:// prefix and port suffix from the string and return result.
Definition: CConnectionManager.cpp:303
ros::master::TopicInfo
mrpt::graphslam::detail::CConnectionManager::updateNearbySlamAgents
void updateNearbySlamAgents()
Update the internal list of nearby SLAM agents.
Definition: CConnectionManager.cpp:154
mrpt::graphslam::detail::CConnectionManager::setupSrvs
void setupSrvs()
Definition: CConnectionManager.cpp:215
ros::NodeHandle


mrpt_graphslam_2d
Author(s): Nikos Koukis
autogenerated on Thu Sep 19 2024 02:26:31