YARP
Yet Another Robot Platform
RosLookup.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include "RosLookup.h"
10 #include "TcpRosLogComponent.h"
11 
12 #include <yarp/conf/environment.h>
13 
14 #include <yarp/os/Bottle.h>
15 #include <yarp/os/ContactStyle.h>
16 #include <yarp/os/Network.h>
17 
18 #include <cstdlib>
19 
20 using namespace yarp::os;
21 
22 static bool rpc(const Contact& c,
23  const char *carrier,
24  Bottle& writer,
25  Bottle& reader)
26 {
27  ContactStyle style;
28  style.quiet = false;
29  style.timeout = 4;
30  style.carrier = carrier;
32  " > sending to [%s] %s",
33  c.toString().c_str(),
34  writer.toString().c_str());
35  bool ok = Network::write(c,writer,reader,style);
36  return ok;
37 }
38 
39 bool RosLookup::lookupCore(const std::string& name) {
40  Bottle req, reply;
41  req.addString("lookupNode");
42  req.addString("dummy_id");
43  req.addString(name);
44  rpc(getRosCoreAddress(), "xmlrpc", req, reply);
45  if (reply.get(0).asInt32()!=1) {
46  yCError(TCPROSCARRIER, "Failure: %s", reply.toString().c_str());
47  return false;
48  }
49  std::string url = reply.get(2).asString();
50  std::string::size_type break1 = url.find("://",0);
51  if (break1==std::string::npos) {
52  yCError(TCPROSCARRIER, "url not understood: %s", url.c_str());
53  return false;
54  }
55  std::string::size_type break2 = url.find(':',break1+3);
56  if (break2==std::string::npos) {
57  yCError(TCPROSCARRIER, "url not understood: %s", url.c_str());
58  return false;
59  }
60  std::string::size_type break3 = url.find('/',break2+1);
61  if (break3==std::string::npos) {
62  yCError(TCPROSCARRIER, "url not understood: %s", url.c_str());
63  return false;
64  }
65  hostname = url.substr(break1+3,break2-break1-3);
66  Value vportnum;
67  vportnum.fromString(url.substr(break2+1,break3-break2-1).c_str());
68  portnum = vportnum.asInt32();
69  yCDebug(TCPROSCARRIER, "%s", reply.toString().c_str());
70  valid = (portnum!=0);
71  rpc(getRosCoreAddress(), "xmlrpc", req, reply);
72  return valid;
73 }
74 
75 
76 bool RosLookup::lookupTopic(const std::string& name) {
77  if (!valid) {
78  yCError(TCPROSCARRIER, "Need a node");
79  return false;
80  }
81  Bottle req, reply;
82  req.addString("requestTopic");
83  req.addString("dummy_id");
84  req.addString(name);
85  Bottle& lst = req.addList();
86  Bottle& sublst = lst.addList();
87  sublst.addString("TCPROS");
89  "Sending [%s] to %s",
90  req.toString().c_str(),
91  toString().c_str());
93  rpc(c,"xmlrpc",req,reply);
94  if (reply.get(0).asInt32()!=1) {
95  yCError(TCPROSCARRIER, "Failure looking up topic %s: %s", name.c_str(), reply.toString().c_str());
96  return false;
97  }
98  Bottle *pref = reply.get(2).asList();
99  if (pref==nullptr) {
100  yCError(TCPROSCARRIER, "Failure looking up topic %s: expected list of protocols", name.c_str());
101  return false;
102  }
103  if (pref->get(0).asString()!="TCPROS") {
104  yCError(TCPROSCARRIER, "Failure looking up topic %s: unsupported protocol %s", name.c_str(),
105  pref->get(0).asString().c_str());
106  return false;
107  }
108  Value hostname2 = pref->get(1);
109  Value portnum2 = pref->get(2);
110  hostname = hostname2.asString();
111  portnum = portnum2.asInt32();
112  protocol = "tcpros";
114  "topic %s available at %s:%d",
115  name.c_str(),
116  hostname.c_str(),
117  portnum);
118  return true;
119 }
120 
122  std::string addr = yarp::conf::environment::getEnvironment("ROS_MASTER_URI");
123  Contact c = Contact::fromString(addr);
124  if (c.isValid()) {
125  c.setCarrier("xmlrpc");
126  }
127  return c;
128 }
129 
131  static bool checkedEnv = false;
132  static Contact addr;
133  if (!checkedEnv) {
134  Contact c = getRosCoreAddressFromEnv();
135  addr = c;
136  checkedEnv = true;
137  }
138  if (!addr.isValid()) {
139  addr = NetworkBase::queryName("/roscore");
140  }
141  if (!addr.isValid()) {
142  yCError(TCPROSCARRIER, "cannot find roscore, is ROS_MASTER_URI set?");
143  ::exit(1);
144  }
145  return addr;
146 }
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::Bottle::toString
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
Network.h
yarp::os::ContactStyle
Preferences for how to communicate with a contact.
Definition: ContactStyle.h:27
ContactStyle.h
yarp::conf::environment::getEnvironment
std::string getEnvironment(const char *key, bool *found=nullptr)
Read a variable from the environment.
Definition: environment.h:31
yarp::os::NetworkBase::write
static bool write(const Contact &contact, PortWriter &cmd, PortReader &reply, bool admin=false, bool quiet=false, double timeout=-1)
Send a single command to a port and await a single response.
Definition: Network.cpp:1229
RosLookup.h
RosLookup::lookupTopic
bool lookupTopic(const std::string &name)
Definition: RosLookup.cpp:76
rpc
static bool rpc(const Contact &c, const char *carrier, Bottle &writer, Bottle &reader)
Definition: RosLookup.cpp:22
RosLookup::getRosCoreAddressFromEnv
static yarp::os::Contact getRosCoreAddressFromEnv()
Definition: RosLookup.cpp:121
yarp::os::Contact::toString
std::string toString() const
Get a textual representation of the Contact.
Definition: Contact.cpp:306
yarp::os::NetworkBase::queryName
static Contact queryName(const std::string &name)
Find out information about a registered name.
Definition: Network.cpp:998
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
yarp::os::ContactStyle::quiet
bool quiet
Suppress all outputs and warnings.
Definition: ContactStyle.h:39
yarp::os::Bottle::addList
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
yarp::os::Contact::fromString
static Contact fromString(const std::string &txt)
Factory method.
Definition: Contact.cpp:142
RosLookup::getRosCoreAddress
static yarp::os::Contact getRosCoreAddress()
Definition: RosLookup.cpp:130
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Contact::setCarrier
void setCarrier(const std::string &carrier)
Set the carrier to use for this Contact.
Definition: Contact.cpp:258
RosLookup::lookupCore
bool lookupCore(const std::string &name)
Definition: RosLookup.cpp:39
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
yarp::os::ContactStyle::carrier
std::string carrier
Request that communication be made using a particular carrier.
Definition: ContactStyle.h:56
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:112
TcpRosLogComponent.h
toString
std::string toString(const T &value)
convert an arbitrary type to string.
Definition: fakeMotionControl.cpp:121
yarp::os::Contact::isValid
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:301
yarp::os::Value::fromString
void fromString(const char *str)
Set value to correspond to a textual representation.
Definition: Value.cpp:354
environment.h
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
yarp::os::Value::asList
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
yarp::os::ContactStyle::timeout
double timeout
Set a timeout for communication (in units of seconds, fractional seconds allowed).
Definition: ContactStyle.h:50
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:47
Bottle.h
TCPROSCARRIER
const yarp::os::LogComponent & TCPROSCARRIER()
Definition: TcpRosLogComponent.cpp:16