icub-test
SensorsDuplicateReadings.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 <Plugin.h>
23 #include "SensorsDuplicateReadings.h"
24 #include <yarp/os/Time.h>
25 #include <yarp/os/Stamp.h>
26 #include <yarp/math/Math.h>
27 
28 using namespace std;
29 using namespace robottestingframework;
30 using namespace yarp::os;
31 using namespace yarp::math;
32 
33 // prepare the plugin
34 ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(SensorsDuplicateReadings)
35 
36 SensorsDuplicateReadings::SensorsDuplicateReadings() : yarp::robottestingframework::TestCase("SensorsDuplicateReadings") {
37 }
38 
39 SensorsDuplicateReadings::~SensorsDuplicateReadings() { }
40 
41 bool SensorsDuplicateReadings::setup(yarp::os::Property &property) {
42 
43  //updating the test name
44  if(property.check("name"))
45  setName(property.find("name").asString());
46 
47  // updating parameters
48  testTime = (property.check("time")) ? property.find("time").asFloat64() : 2;
49 
50  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check("PORTS"),
51  "A list of the ports must be given");
52 
53  yarp::os::Bottle portsSet = property.findGroup("PORTS").tail();
54  for(unsigned int i=0; i<portsSet.size(); i++) {
55  yarp::os::Bottle* btport = portsSet.get(i).asList();
56  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(btport && btport->size()>=3, "The ports must be given as lists of <portname> <toleratedDuplicates>");
57  DuplicateReadingsPortInfo info;
58  info.name = btport->get(0).asString();
59  info.toleratedDuplicates = btport->get(1).asInt32();
60  ports.push_back(info);
61  }
62 
63  // opening port
64  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(port.open("..."),
65  "opening port, is YARP network available?");
66  return true;
67 }
68 
69 void SensorsDuplicateReadings::tearDown() {
70  // finalization goes her ...
71  port.close();
72 }
73 
74 void SensorsDuplicateReadings::run() {
75  for(unsigned int i=0; i<ports.size(); i++) {
76  port.reset();
77  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Checking port %s ...", ports[i].name.c_str()));
78  bool connected = Network::connect(ports[i].name.c_str(), port.getName());
79  ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF(connected,
80  Asserter::format("could not connect to remote port %s.", ports[i].name.c_str()));
81  if(connected) {
82  port.useCallback();
83  Time::delay(testTime);
84  port.disableCallback();
85 
86  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Computed a total of %lu duplicates out of %lu samples.",
87  port.getTotalNrOfDuplicates(),port.getCount()));
88  ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format("Maximum number of consecutive duplicates: %lu Maximum jitter: %lf ",
89  port.getMaxNrOfDuplicates(), port.getMaxJitter()));
90 
91  ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF(port.getTotalNrOfDuplicates() > ports[i].toleratedDuplicates,
92  Asserter::format("Number of duplicates (%lu) is higher than the tolerated (%d)",
93  port.getTotalNrOfDuplicates(),
94  ports[i].toleratedDuplicates));
95 
96  Network::disconnect(ports[i].name.c_str(), port.getName());
97  }
98  }
99 }
100 
101 void DuplicateDetector::onRead(yarp::sig::Vector& vec) {
102  double tcurrent = Time::now();
103 
104  if(count == 0)
105  {
106  lastReading = vec;
107  currentJitter = 0.0;
108  currentNrOfDuplicates = 0;
109  totalNrOfDuplicates = 0;
110  lastNewValueTime = tcurrent;
111  maxJitter = currentJitter;
112  maxNrOfDuplicates = currentNrOfDuplicates;
113  }
114  else
115  {
116  // Check for duplicate data
117  double diff = yarp::math::norm(vec-lastReading);
118  if( diff < this->tolerance )
119  {
120  // duplicate ! report a duplicate
121  currentNrOfDuplicates++;
122  currentJitter = tcurrent - lastNewValueTime;
123 
124  totalNrOfDuplicates++;
125 
126  maxJitter = std::max(currentJitter,maxJitter);
127  maxNrOfDuplicates = std::max(currentJitter,maxJitter);
128 
129  }
130  else
131  {
132  // not duplicate! update last read value
133  lastReading = vec;
134  currentNrOfDuplicates = 0;
135  currentJitter = 0.0;
136  lastNewValueTime = tcurrent;
137  }
138  }
139 
140  count++;
141 }
Check if a yarp port is correctly publishing unique values at each update .