Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "mrpt_graphslam_2d/CConnectionManager.h"
00011
00012 using namespace mrpt::graphslam::detail;
00013 using namespace std;
00014 using namespace mrpt::utils;
00015 using namespace mrpt::system;
00016 using namespace mrpt::math;
00017 using namespace multimaster_msgs_fkie;
00018
00019 bool operator==(
00020 const multimaster_msgs_fkie::ROSMaster& master1,
00021 const multimaster_msgs_fkie::ROSMaster& master2) {
00022 return master1.uri == master2.uri;
00023 }
00024 bool operator!=(
00025 const multimaster_msgs_fkie::ROSMaster& master1,
00026 const multimaster_msgs_fkie::ROSMaster& master2) {
00027 return !(master1 == master2);
00028 }
00029
00030 bool operator==(
00031 const mrpt_msgs::GraphSlamAgent& agent1,
00032 const mrpt_msgs::GraphSlamAgent& agent2) {
00033 return (
00034 agent1.agent_ID == agent2.agent_ID &&
00035 agent1.topic_namespace.data == agent2.topic_namespace.data);
00036 }
00038
00039 bool operator!=(
00040 const mrpt_msgs::GraphSlamAgent& agent1,
00041 const mrpt_msgs::GraphSlamAgent& agent2) {
00042 return !(agent1 == agent2);
00043 }
00044
00045 bool operator<(
00046 const mrpt_msgs::GraphSlamAgent& agent1,
00047 const mrpt_msgs::GraphSlamAgent& agent2) {
00048 return agent1.agent_ID < agent2.agent_ID;
00049 }
00051
00052 bool operator==(
00053 const multimaster_msgs_fkie::ROSMaster& master,
00054 const mrpt_msgs::GraphSlamAgent& agent) {
00055 return (master.name == agent.name.data);
00056 }
00057
00058 bool operator!=(
00059 const multimaster_msgs_fkie::ROSMaster& master,
00060 const mrpt_msgs::GraphSlamAgent& agent) {
00061 return !(master == agent);
00062 }
00063
00064 bool operator==(
00065 const mrpt_msgs::GraphSlamAgent& agent,
00066 const multimaster_msgs_fkie::ROSMaster& master) {
00067 return (master == agent);
00068 }
00069 bool operator!=(
00070 const mrpt_msgs::GraphSlamAgent& agent,
00071 const multimaster_msgs_fkie::ROSMaster& master) {
00072 return (master != agent);
00073 }
00074
00076
00077 CConnectionManager::CConnectionManager(
00078 mrpt::utils::COutputLogger* logger,
00079 ros::NodeHandle* nh_in):
00080 m_logger(logger),
00081 m_nh(nh_in),
00082 has_setup_comm(false)
00083 {
00084
00085 ASSERT_(m_logger);
00086 ASSERT_(m_nh);
00087
00088 {
00089 std::string own_ns_tmp = m_nh->getNamespace();
00090
00091 own_ns = std::string(
00092 own_ns_tmp.begin() + own_ns_tmp.find_first_not_of(" /"),
00093 own_ns_tmp.end());
00094 }
00095
00096
00097 this->setupComm();
00098
00099 }
00100
00101 CConnectionManager::~CConnectionManager() { }
00102
00103 const std::string& CConnectionManager::getTrimmedNs() const {
00104 return own_ns;
00105 }
00106
00107 void CConnectionManager::getNearbySlamAgents(
00108 mrpt_msgs::GraphSlamAgents* agents_vec,
00109 bool ignore_self) {
00110
00111
00112 ASSERTMSG_(agents_vec, "Invalid pointer to vector of GraphSlam Agents.");
00113 this->updateNearbySlamAgents();
00114 *agents_vec = m_nearby_slam_agents;
00115
00116 if (ignore_self) {
00117
00118
00119 auto search = [this](const mrpt_msgs::GraphSlamAgent& agent) {
00120 return (agent.topic_namespace.data == this->own_ns);
00121 };
00122 agents_it it = find_if(
00123 agents_vec->list.begin(),
00124 agents_vec->list.end(), search);
00125
00126
00127
00128
00129
00130
00131
00132 if (it != agents_vec->list.end()) {
00133 agents_vec->list.erase(it);
00134 }
00135 else {
00136 }
00137 }
00138 }
00139
00140 const mrpt_msgs::GraphSlamAgents&
00141 CConnectionManager::getNearbySlamAgentsCached() const {
00142 return m_nearby_slam_agents;
00143 }
00144
00145 const mrpt_msgs::GraphSlamAgents&
00146 CConnectionManager::getNearbySlamAgents() {
00147 this->updateNearbySlamAgents();
00148 return this->getNearbySlamAgentsCached();
00149 }
00150
00151 void CConnectionManager::updateNearbySlamAgents() {
00152 using ::operator==;
00153 using namespace mrpt::utils;
00154 using namespace mrpt::math;
00155 ASSERT_(has_setup_comm);
00156
00157 DiscoverMasters srv;
00158
00159
00160 m_DiscoverMasters_client.call(srv);
00161 std::vector<ROSMaster>* masters = &(srv.response.masters);
00162
00163
00164 for (std::vector<ROSMaster>::const_iterator
00165 masters_it = masters->begin();
00166 masters_it != masters->end();
00167 ++masters_it) {
00168
00169
00170
00171
00172
00173
00174
00175 auto search = [masters_it](const mrpt_msgs::GraphSlamAgent& agent) {
00176 return agent == *masters_it;
00177 };
00178 agents_it it = find_if(
00179 m_nearby_slam_agents.list.begin(),
00180 m_nearby_slam_agents.list.end(), search);
00181
00182 if (it != m_nearby_slam_agents.list.end()) {
00183
00184 it->last_seen_time.data = ros::Time(masters_it->timestamp);
00185 }
00186 else {
00187 mrpt_msgs::GraphSlamAgent new_agent;
00188 bool is_agent = this->convert(*masters_it, &new_agent);
00189 if (is_agent) {
00190 m_nearby_slam_agents.list.push_back(new_agent);
00191 };
00192 }
00193
00194 }
00195
00196 }
00197
00198
00199 void CConnectionManager::setupComm() {
00200
00201 this->setupSubs();
00202 this->setupPubs();
00203 this->setupSrvs();
00204
00205 has_setup_comm = true;
00206 }
00207
00208 void CConnectionManager::setupSubs() { }
00209 void CConnectionManager::setupPubs() { }
00210 void CConnectionManager::setupSrvs() {
00211
00212
00213 m_DiscoverMasters_client =
00214 m_nh->serviceClient<multimaster_msgs_fkie::DiscoverMasters>(
00215 "/master_discovery/list_masters");
00216
00217
00218 }
00219
00220 bool CConnectionManager::convert(
00221 const multimaster_msgs_fkie::ROSMaster& ros_master,
00222 mrpt_msgs::GraphSlamAgent* slam_agent) {
00223 ASSERT_(slam_agent);
00224 bool agent_namespace_found = false;
00225
00226 slam_agent->name.data = ros_master.name;
00227 slam_agent->is_online.data = static_cast<bool>(ros_master.online);
00228
00229
00230 std::string ip_addr = CConnectionManager::extractHostnameOrIP(ros_master.monitoruri);
00231 slam_agent->ip_addr.data = ip_addr;
00232 std::string hostname = CConnectionManager::extractHostnameOrIP(
00233 ros_master.uri, &slam_agent->port);
00234 slam_agent->hostname.data = hostname;
00235
00236
00237 vector<string> tokens;
00238 mrpt::system::tokenize(ip_addr, ".", tokens);
00239 slam_agent->agent_ID = atoi(tokens.rbegin()->c_str());
00240
00241
00242 {
00243
00244
00245
00246 slam_agent->topic_namespace.data = slam_agent->name.data;
00247
00248
00249 ros::master::V_TopicInfo topics;
00250 bool got_topics = ros::master::getTopics(topics);
00251 ASSERTMSG_(got_topics, "Unable to fetch topics. Exiting.");
00252
00253
00254 const std::string& topic_ns = "/" + slam_agent->topic_namespace.data;
00255
00256 const std::string& feedback_ns =
00257 "/" + slam_agent->topic_namespace.data + "/" + "feedback";
00258
00259 auto search = [&feedback_ns](
00260 const ros::master::TopicInfo& topic) {
00261 return (strStarts(topic.name, feedback_ns));
00262 };
00263 ros::master::V_TopicInfo::const_iterator cit = find_if(
00264 topics.begin(), topics.end(), search);
00265 if (cit != topics.end()) {
00266 agent_namespace_found = true;
00267 }
00268 }
00269
00270
00271 slam_agent->last_seen_time.data = ros::Time(ros_master.timestamp);
00272 return agent_namespace_found;
00273
00274 }
00275
00276 void CConnectionManager::convert(
00277 const mrpt_msgs::GraphSlamAgent& slam_agent,
00278 multimaster_msgs_fkie::ROSMaster* ros_master) {
00279 ASSERT_(ros_master);
00280
00281 ros_master->name = slam_agent.name.data;
00282 {
00283 stringstream ss("");
00284 ss << "http://" << slam_agent.ip_addr << ":" << slam_agent.port;
00285 ros_master->uri = ss.str();
00286 }
00287 ros_master->online = slam_agent.is_online.data;
00288 ros_master->discoverer_name = "/master_discovery";
00289
00290
00291
00292 }
00293
00294 std::string CConnectionManager::extractHostnameOrIP(const std::string& str,
00295 unsigned short* agent_port) {
00296
00297 std::string s = std::string(str.begin()+7, str.end());
00298
00299 vector<string> tokens;
00300 mrpt::system::tokenize(s, ":", tokens);
00301
00302 if (agent_port) {
00303 *agent_port = static_cast<unsigned short>(atoi(tokens[1].c_str()));
00304 }
00305
00306 return tokens[0];
00307 }
00308