YARP
Yet Another Robot Platform
Ping.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <yarp/os/Ping.h>
11 
12 #include <yarp/os/Bottle.h>
14 #include <yarp/os/Network.h>
15 #include <yarp/os/Port.h>
16 #include <yarp/os/Time.h>
17 #include <yarp/os/Vocab.h>
18 
19 #include <cmath>
20 #include <cstdio>
21 #include <mutex>
22 
23 using namespace yarp::os;
24 
25 namespace {
26 YARP_OS_LOG_COMPONENT(PING, "yarp.os.Ping")
27 }
28 
30 {
31  clear();
32 }
33 
35 {
36  tot = tot2 = 0;
37  ct = at = 0;
38  mu = 0;
39  sigma = 1e10;
40  // infinity would be better, but methods of getting infinity
41  // require awkward dependencies
42 }
43 
44 void Stat::add(double val)
45 {
46  tot += val;
47  tot2 += val * val;
48  ct++;
49 }
50 
51 void Stat::add(const Stat& alt)
52 {
53  tot += alt.tot;
54  tot2 += alt.tot2;
55  ct += alt.ct;
56 }
57 
58 double Stat::mean()
59 {
60  compute();
61  return mu;
62 }
63 
65 {
66  compute();
67  return sigma;
68 }
69 
70 double Stat::count()
71 {
72  return ct;
73 }
74 
75 Stat::operator double()
76 {
77  return mean();
78 }
79 
80 void Stat::compute()
81 {
82  if (ct != at) {
83  // ct must be > 0
84  mu = tot / ct;
85  sigma = tot2 / ct - mu * mu;
86  if (sigma < 0) {
87  sigma = 0; // round-off error
88  }
89  sigma = sqrt(sigma);
90  at = ct;
91  }
92 }
93 
94 
96 {
97  totalTime.clear();
98  targetTime.clear();
99 }
100 
102 {
103  totalTime.add(alt.totalTime);
105 }
106 
107 
109 {
110  period.clear();
111 }
112 
113 void RateResult::add(const RateResult& alt)
114 {
115  period.add(alt.period);
116 }
117 
118 
119 Ping::Ping(const char* target)
120 {
121  if (target != nullptr) {
122  setTarget(target);
123  }
124 }
125 
126 bool Ping::setTarget(const char* target)
127 {
128  this->target = target;
129  return true;
130 }
131 
132 
134 {
135  lastConnect.clear();
136  double start = SystemClock::nowSystem();
137  Contact c = NetworkBase::queryName(target);
138  double afterQuery = SystemClock::nowSystem();
139  if (!c.isValid()) {
140  yCError(PING, "Port not found during ping");
141  }
143  rpc.admin = true;
144  rpc.quiet = true;
145  Bottle cmd;
146  Bottle reply;
147  cmd.addVocab(Vocab::encode("ver"));
148  bool ok = NetworkBase::write(c, cmd, reply, rpc);
149  if (!ok) {
150  yCError(PING, "Port did not respond as expected");
151  }
152  double stop = SystemClock::nowSystem();
153  lastConnect.totalTime.add(stop - start);
154  lastConnect.targetTime.add(stop - afterQuery);
155  accumConnect.add(lastConnect);
156 }
157 
159 {
160  long int ping = lround(accumConnect.targetTime.count() + 0.5);
161  if (ping > 0) {
162  yCInfo(PING, "Ping #%ld:\n", lround(accumConnect.targetTime.count() + 0.5));
163  int space = 14;
164  int decimal = 5;
165  yCInfo(PING,
166  " %s connection time (%s with name lookup)\n",
167  renderTime(lastConnect.targetTime.mean(), space, decimal).c_str(),
168  renderTime(lastConnect.totalTime.mean(), space, decimal).c_str());
169  if (accumConnect.totalTime.count() > 1) {
170  yCInfo(PING,
171  " %s +/- %s on average (%s +/- %s with name lookup)\n",
172  renderTime(accumConnect.targetTime.mean(), space, decimal).c_str(),
173  renderTime(accumConnect.targetTime.deviation(), space, decimal).c_str(),
174  renderTime(accumConnect.totalTime.mean(), space, decimal).c_str(),
175  renderTime(accumConnect.totalTime.deviation(), space, decimal).c_str());
176  }
177  }
178 }
179 
180 
181 std::string Ping::renderTime(double t, int space, int decimal)
182 {
183  std::string unit;
184  double times = 1;
185  if (space < 0) {
186  yCError(PING, "Negative space");
187  }
188  if (t >= 1) {
189  unit = "sec";
190  } else if (t > 1e-3) {
191  unit = " ms";
192  times = 1e3;
193  } else if (t > 1e-6) {
194  unit = " us";
195  times = 1e6;
196  } else if (t > 1e-9) {
197  unit = " ns";
198  times = 1e9;
199  }
200  char buf[512];
201  std::snprintf(buf, sizeof(buf), "%.*f%s", decimal, t * times, unit.c_str());
202  return buf;
203 }
204 
205 
206 class PingSampler : public PortReader
207 {
208 public:
209  std::mutex mutex;
210  int ct{0};
211  double lastTime{0};
213 
215  mutex()
216  {
217  }
218 
219  bool read(ConnectionReader& connection) override
220  {
221  double now = SystemClock::nowSystem();
222  Bottle b;
223  bool ok = b.read(connection);
224  if (ok) {
225  mutex.lock();
226  ct++;
227  if (ct > 1) {
228  double dt = now - lastTime;
229  period.add(dt);
230  }
231  lastTime = now;
232  yCInfo(PING,
233  "Period is %g +/- %g (%d)\n",
234  period.mean(),
235  period.deviation(),
236  ct);
237  mutex.unlock();
238  }
239  return ok;
240  }
241 };
242 
244 {
245  Port p;
246  PingSampler sampler;
247  p.setReader(sampler);
248  p.open("...");
249  yCInfo(PING, "Pausing for 5 seconds...\n");
250  NetworkBase::connect(target, p.getName());
252  p.close();
253  yCInfo(PING,
254  "Period is %g +/- %g (%d)\n",
255  sampler.period.mean(),
256  sampler.period.deviation(),
257  sampler.ct);
258 }
259 
261 {
262  lastConnect.clear();
263  accumConnect.clear();
264 }
265 
267 {
268  return lastConnect;
269 }
270 
272 {
273  return accumConnect;
274 }
yarp::os::Port::close
void close() override
Stop port activity.
Definition: Port.cpp:357
yarp::os::Ping::setTarget
bool setTarget(const char *target)
Definition: Ping.cpp:126
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::Ping::getLastConnect
ConnectResult getLastConnect()
Definition: Ping.cpp:266
yarp::os::Stat
Definition: Ping.h:23
yarp::os::ConnectResult::totalTime
Stat totalTime
Definition: Ping.h:51
yarp::os::ConnectResult::add
void add(const ConnectResult &alt)
Definition: Ping.cpp:101
Network.h
yarp::os::Ping::Ping
Ping(const char *target=nullptr)
Definition: Ping.cpp:119
yarp::os::ContactStyle
Preferences for how to communicate with a contact.
Definition: ContactStyle.h:27
yarp::os::ConnectResult
Definition: Ping.h:49
PingSampler::PingSampler
PingSampler()
Definition: Ping.cpp:214
t
float t
Definition: FfmpegWriter.cpp:74
yarp::os::RateResult::clear
void clear()
Definition: Ping.cpp:108
Port.h
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
yarp::os::ConnectResult::targetTime
Stat targetTime
Definition: Ping.h:52
PingSampler::ct
int ct
Definition: Ping.cpp:210
yarp::os::Stat::count
double count()
Definition: Ping.cpp:70
yarp::os::RateResult::add
void add(const RateResult &alt)
Definition: Ping.cpp:113
yarp::os::Port::open
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition: Port.cpp:82
yarp::os::Ping::getAverageConnect
ConnectResult getAverageConnect()
Definition: Ping.cpp:271
LogComponent.h
rpc
static bool rpc(const Contact &c, const char *carrier, Bottle &writer, Bottle &reader)
Definition: RosLookup.cpp:22
yarp::os::Stat::add
void add(double val)
Definition: Ping.cpp:44
yarp::os::Time::now
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
yarp::os::SystemClock::nowSystem
static double nowSystem()
Definition: SystemClock.cpp:37
yarp::os::Stat::deviation
double deviation()
Definition: Ping.cpp:64
yarp::os::Port
A mini-server for network communication.
Definition: Port.h:50
yarp::os::Ping::clear
void clear()
Definition: Ping.cpp:260
yarp::os::NetworkBase::queryName
static Contact queryName(const std::string &name)
Find out information about a registered name.
Definition: Network.cpp:998
yarp::os::PortReader
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition: PortReader.h:28
Ping.h
yarp::os::SystemClock::delaySystem
static void delaySystem(double seconds)
Definition: SystemClock.cpp:32
yarp::os::NetworkBase::connect
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition: Network.cpp:685
yarp::os::Ping::sample
void sample()
Definition: Ping.cpp:243
yarp::os::Vocab::encode
NetInt32 encode(const std::string &str)
Convert a string into a vocabulary identifier.
Definition: Vocab.cpp:14
PingSampler::mutex
std::mutex mutex
Definition: Ping.cpp:209
yarp::os::Ping::connect
void connect()
Definition: Ping.cpp:133
yarp::os::Contactable::getName
virtual std::string getName() const
Get name of port.
Definition: Contactable.cpp:17
PingSampler::read
bool read(ConnectionReader &connection) override
Read this object from a network connection.
Definition: Ping.cpp:219
yarp::os::Port::setReader
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition: Port.cpp:505
yarp::os::Bottle::addVocab
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
yarp::os::ConnectionReader
An interface for reading from a network connection.
Definition: ConnectionReader.h:40
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os::Ping::renderTime
static std::string renderTime(double t, int space, int decimal)
Definition: Ping.cpp:181
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::RateResult
Definition: Ping.h:59
yarp::os::Ping::report
void report()
Definition: Ping.cpp:158
yarp::os::Contact::isValid
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:301
yarp::os::Stat::clear
void clear()
Definition: Ping.cpp:34
Vocab.h
yarp::os::Bottle::read
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
Time.h
yarp::os::ConnectResult::clear
void clear()
Definition: Ping.cpp:95
YARP_OS_LOG_COMPONENT
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:37
yarp::os::Stat::Stat
Stat()
Definition: Ping.cpp:29
yarp::os::RateResult::period
Stat period
Definition: Ping.h:61
Bottle.h
PingSampler
Definition: Ping.cpp:207
PingSampler::period
Stat period
Definition: Ping.cpp:212
yarp::os::Stat::mean
double mean()
Definition: Ping.cpp:58