icub-test
All Data Structures Modules Pages
PortsFrequency.cpp
1 /*
2  * iCub Robot Unit Tests (Robot Testing Framework)
3  *
4  * Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <math.h>
22 #include <robottestingframework/dll/Plugin.h>
23 #include <robottestingframework/TestAssert.h>
24 #include "PortsFrequency.h"
25 #include <yarp/os/Time.h>
26 #include <yarp/os/Stamp.h>
27 #include <yarp/os/QosStyle.h>
28 #include <yarp/os/Network.h>
29 
30 using namespace std;
31 using namespace robottestingframework;
32 using namespace yarp::os;
33 
34 // prepare the plugin
35 ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(PortsFrequency)
36 
37 PortsFrequency::PortsFrequency() : yarp::robottestingframework::TestCase("PortsFrequency") {
38 }
39 
40 PortsFrequency::~PortsFrequency() { }
41 
42 bool PortsFrequency::setup(yarp::os::Property &property) {
43 
44  //updating the test name
45  if(property.check("name"))
46  setName(property.find("name").asString());
47 
48  // updating parameters
49  testTime = (property.check("time")) ? property.find("time").asFloat64() : 2;
50 
51  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("PORTS"),
52  "A list of the ports must be given");
53 
54  yarp::os::Bottle portsSet = property.findGroup("PORTS").tail();
55  for(unsigned int i=0; i<portsSet.size(); i++) {
56  yarp::os::Bottle* btport = portsSet.get(i).asList();
57  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(btport && btport->size()>=3, "The ports must be given as lists of <portname> <grequency> <tolerance>");
58  MyPortInfo info;
59  info.name = btport->get(0).asString();
60  info.frequency = btport->get(1).asInt32();
61  info.tolerance = btport->get(2).asInt32();
62  ports.push_back(info);
63  }
64 
65  // opening port
66  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(port.open("..."),
67  "opening port, is YARP network available?");
68  return true;
69 }
70 
71 void PortsFrequency::tearDown() {
72  // finalization goes her ...
73  port.close();
74 }
75 
76 void PortsFrequency::run() {
77  for(unsigned int i=0; i<ports.size(); i++) {
78  ROBOTTESTINGFRAMEWORK_TEST_REPORT("");
79  port.reset();
80  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Checking port %s ...", ports[i].name.c_str()));
81  bool connected = Network::connect(ports[i].name.c_str(), port.getName());
82  ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE(connected,
83  Asserter::format("could not connect to remote port %s.", ports[i].name.c_str()));
84  if(connected) {
85  // setting QOS
86  QosStyle qos;
87  qos.setPacketPriorityByLevel(QosStyle::PacketPriorityHigh);
88  qos.setThreadPriority(30);
89  qos.setThreadPolicy(1);
90  Network::setConnectionQos(ports[i].name.c_str(), port.getName(), qos);
91  port.useCallback();
92  Time::delay(testTime);
93  port.disableCallback();
94  if(port.getSAvg() <= 0) {
95  ROBOTTESTINGFRAMEWORK_TEST_REPORT("Sender frequency is not available");
96  }
97  else {
98  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Time delay between sender/receiver is %.4f s. (min: %.4f, max: %.f4)",
99  port.getDAvg(), port.getDMax(), port.getDMin()));
100  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Sender frequency %d hrz. (min: %d, max: %d)",
101  (int)(1.0/port.getSAvg()), (int)(1.0/port.getSMax()), (int)(1.0/port.getSMin())));
102  }
103  double freq = 1.0/port.getAvg();
104  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Receiver frequency %d hrz. (min: %d, max: %d)",
105  (int)freq, (int)(1.0/port.getMax()), (int)(1.0/port.getMin())));
106  double diff = fabs(freq - ports[i].frequency);
107  ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE(diff < ports[i].tolerance,
108  Asserter::format("Receiver frequency is outside the desired range [%d .. %d]",
109  ports[i].frequency-ports[i].tolerance,
110  ports[i].frequency+ports[i].tolerance));
111  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Lost %ld packets. received (%ld)",
112  port.getPacketLostCount(), port.getCount()));
113  Network::disconnect(ports[i].name.c_str(), port.getName());
114  }
115  }
116 }
117 
118 void DataPort::onRead(yarp::os::Bottle& bot) {
119  double tcurrent = Time::now();
120  Stamp stm;
121  bool hasTimeStamp = getEnvelope(stm);
122 
123  if(count == 0) {
124  if(hasTimeStamp) {
125  double tdiff = fabs(tcurrent - stm.getTime());
126  dsum = dmax = dmin = tdiff;
127  prevPacketCount = stm.getCount();
128  }
129  }
130  else {
131  // calculating statistics
132  double tdiff = fabs(tcurrent - tprev);
133  sum += tdiff;
134  max = (tdiff > max) ? tdiff : max;
135  min = (min<0 || min > tdiff) ? tdiff : min;
136 
137  // calculating statistics using time stamp
138  if(hasTimeStamp) {
139  tdiff = fabs(stm.getTime() - stprev);
140  ssum += tdiff;
141  smax = (tdiff > smax) ? tdiff : smax;
142  smin = (smin<0 || smin > tdiff) ? tdiff : smin;
143 
144  // calculating time delay
145  double tdiff = fabs(tcurrent - stm.getTime());
146  dsum += tdiff;
147  dmax = (tdiff > dmax) ? tdiff : dmax;
148  dmin = (dmin<0 || dmin > tdiff) ? tdiff : dmin;
149  // calculating packet losts
150  if(stm.getCount() > prevPacketCount)
151  packetLostCount += stm.getCount() - prevPacketCount - 1;
152  prevPacketCount = stm.getCount();
153  }
154  }
155 
156  count++;
157  tprev = tcurrent;
158  if(hasTimeStamp)
159  stprev = stm.getTime();
160 }