test_find_pinches.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
2 #include "testUtils.h"
3 
4 #include <ros/ros.h>
5 
11 
12 
13 namespace {
14 
15 class testFindPinches: public ::testing::Test {
16 
17 
18 protected:
19 
20  testFindPinches() {
21  }
22 
23  virtual ~testFindPinches() {
24  }
25 
26  virtual void SetUp() override {
27 
28  std::shared_ptr <ROSEE::ParserMoveIt> parserMoveIt = std::make_shared <ROSEE::ParserMoveIt> ();
29  //if return false, models are not found and it is useless to continue the test
30  ASSERT_TRUE(parserMoveIt->init ("robot_description", false)) ;
31  ROSEE::FindActions actionsFinder (parserMoveIt);
32 
33  std::string folderForActions = "ROSEE/actions/" + parserMoveIt->getHandName();
34 
35  auto theTwoMaps = actionsFinder.findPinch(folderForActions + "/primitives/");
36 
37  pinchMap = theTwoMaps.first;
38  pinchLooseMap = theTwoMaps.second;
39 
40  ROSEE::YamlWorker yamlWorker;
41 
42  if (pinchMap.size() > 0 ) {
43  pinchParsedMap = yamlWorker.parseYamlPrimitive(folderForActions + "/primitives/" + "pinchTight.yaml" );
44  }
45 
46  if (pinchLooseMap.size() > 0 ) {
47  pinchLooseParsedMap = yamlWorker.parseYamlPrimitive(folderForActions + "/primitives/" + "pinchLoose.yaml");
48  }
49 
50  }
51 
52  virtual void TearDown() {
53  }
54 
55  std::map < std::pair < std::string, std::string >, ROSEE::ActionPinchTight > pinchMap;
56  std::map < std::set < std::string >, std::shared_ptr<ROSEE::ActionPrimitive> > pinchParsedMap;
57 
58  std::map < std::pair < std::string, std::string >, ROSEE::ActionPinchLoose > pinchLooseMap;
59  std::map < std::set < std::string >, std::shared_ptr<ROSEE::ActionPrimitive> > pinchLooseParsedMap;
60 };
61 
62 
63 TEST_F ( testFindPinches, checkNumberLinks ) {
64 
65  for (auto &mapEl: pinchMap ) {
66 
67  //being a pair the .first has always dimension 2
68  EXPECT_EQ (2, mapEl.second.getFingersInvolved().size() ); //the names inside the action
69  EXPECT_EQ (2, mapEl.second.getnFingersInvolved() ); //the int nLinkInvolved member of action
70  }
71 
72  for (auto &mapEl: pinchParsedMap ) {
73 
74  EXPECT_EQ (2, mapEl.first.size()); // the key
75  EXPECT_EQ (2, mapEl.second->getFingersInvolved().size()); //the names inside the action
76  EXPECT_EQ (2, mapEl.second->getnFingersInvolved()); //the int nLinkInvolved member of action
77  }
78 }
79 
80 TEST_F ( testFindPinches, checkSizeStatesInfoSet ) {
81 
82  for (auto &mapEl: pinchMap ) {
83 
84  //get the member which is set in costructor
85  unsigned int size = mapEl.second.getMaxStoredActionStates();
86 
87  //it must be equal to the real size of the actionState set
88  EXPECT_EQ ( size, mapEl.second.getActionStates().size() );
89  EXPECT_EQ ( size, mapEl.second.getAllJointPos().size() );
90  }
91 
92  for (auto &mapEl: pinchParsedMap ) {
93 
94  //get the member which is set in costructor
95  unsigned int size = mapEl.second->getMaxStoredActionStates();
96 
97  EXPECT_EQ (size, mapEl.second->getAllJointPos().size());
98  }
99 }
100 
101 TEST_F ( testFindPinches, checkName ) {
102 
103  for (auto &mapEl: pinchMap ) {
104 
105  EXPECT_TRUE (mapEl.second.getName().compare("pinchTight") == 0);
106  EXPECT_EQ (ROSEE::ActionPrimitive::Type::PinchTight, mapEl.second.getPrimitiveType() );
107  }
108 
109  for (auto &mapEl: pinchParsedMap ) {
110 
111  EXPECT_TRUE (mapEl.second->getName().compare("pinchTight") == 0);
112  EXPECT_EQ (ROSEE::ActionPrimitive::Type::PinchTight, mapEl.second->getPrimitiveType() );
113  }
114 }
115 
116 //this is an important test: check if the order of statesInfo in right according to depth
117 TEST_F ( testFindPinches, checkOrderStatesInfoSet ) {
118 
119  for (auto &mapEl: pinchMap ) {
120 
121  std::vector < ROSEE::ActionPinchTight::StateWithContact> statesInfo =
122  mapEl.second.getActionStates();
123 
124  double oldDepth = std::numeric_limits<double>::infinity();
125 
126  for (auto &setEl : statesInfo) {
127  EXPECT_LE (std::abs(setEl.second.depth), std::abs(oldDepth) ); //lesser or equal
128  oldDepth = setEl.second.depth;
129  }
130  }
131 
132 
133  for (auto &mapEl: pinchParsedMap ) {
134 
135  std::shared_ptr <ROSEE::ActionPinchTight> pinchCasted =
136  std::dynamic_pointer_cast < ROSEE::ActionPinchTight > (mapEl.second);
137 
138  ASSERT_FALSE (pinchCasted == nullptr);
139  std::vector < ROSEE::ActionPinchTight::StateWithContact> statesInfo =
140  pinchCasted->getActionStates();
141 
142  double oldDepth = std::numeric_limits<double>::infinity();
143 
144  for (auto &setEl : statesInfo) {
145  EXPECT_LE (std::abs(setEl.second.depth), std::abs(oldDepth) ); //lesser or equal
146  oldDepth = setEl.second.depth;
147  }
148  }
149 }
150 
151 // to check if the found map is the same map that is emitted in the file and then parsed
152 TEST_F ( testFindPinches, checkEmitParse ) {
153 
154  ASSERT_EQ (pinchMap.size(), pinchParsedMap.size() );
155 
156  for (auto &mapEl: pinchParsedMap ) {
157 
158  std::shared_ptr <ROSEE::ActionPinchTight> pinchCasted =
159  std::dynamic_pointer_cast < ROSEE::ActionPinchTight > (mapEl.second);
160 
161  ASSERT_FALSE (pinchCasted == nullptr);
162  ASSERT_EQ (2, mapEl.first.size() );
163  std::pair <std::string, std::string> keyPair;
164  std::set<std::string>::iterator it = mapEl.first.begin();
165  keyPair.first = *it;
166  std::advance ( it, 1 );
167  keyPair.second = *it;
168 
169  //std::string is ok to compare with _EQ
170  EXPECT_EQ (pinchCasted->getName(), pinchMap.at(keyPair).getName() );
171  EXPECT_EQ (pinchCasted->getType(), pinchMap.at(keyPair).getType() );
172  EXPECT_EQ (pinchCasted->getnFingersInvolved(), pinchMap.at(keyPair).getnFingersInvolved() );
173  EXPECT_EQ (pinchCasted->getMaxStoredActionStates(), pinchMap.at(keyPair).getMaxStoredActionStates());
174  EXPECT_EQ (pinchCasted->getPrimitiveType(), pinchMap.at(keyPair).getPrimitiveType() );
175  EXPECT_EQ (pinchCasted->getFingersInvolved(), pinchMap.at(keyPair).getFingersInvolved());
176 
177  unsigned int i = 0;
178  for (auto as: pinchCasted->getActionStates() ) {
179 
180  //check equality of joint states (as.first)
181  for (auto joint : as.first) {
182  ASSERT_EQ ( joint.second.size(),
183  pinchMap.at(keyPair).getAllJointPos().at(i).at(joint.first).size() );
184  //loop the eventually multiple joint pos (when dofs > 1)
185  for (int j=0; j<joint.second.size(); ++j){
186  EXPECT_DOUBLE_EQ ( joint.second.at(j),
187  pinchMap.at(keyPair).getAllJointPos().at(i).at(joint.first).at(j) );
188  }
189  }
190 
191  //check equality of contact (as.second)
192  collision_detection::Contact thisCont = as.second;
193  collision_detection::Contact otherCont =
194  pinchMap.at(keyPair).getActionStates().at(i).second;
195  // Tricky here, body colliding names can be swapped.
196  // BUT it seems that depth, normal and pos refer to a fixed something, so they must
197  // not be swapped (I don't see that EXPECT fails if I don't swap them when names are swapped)
198  if (thisCont.body_name_1 > thisCont.body_name_2) {
199  std::swap(thisCont.body_name_1, thisCont.body_name_2);
200  std::swap(thisCont.body_type_1, thisCont.body_type_2);
201  }
202  if (otherCont.body_name_1 > otherCont.body_name_2) {
203  std::swap(otherCont.body_name_1, otherCont.body_name_2);
204  std::swap(otherCont.body_type_1, otherCont.body_type_2);
205 
206  }
207  EXPECT_EQ (thisCont.body_name_1, otherCont.body_name_1 );
208  EXPECT_EQ (thisCont.body_name_2, otherCont.body_name_2 );
209  EXPECT_EQ (thisCont.body_type_1, otherCont.body_type_1 );
210  EXPECT_EQ (thisCont.body_type_2, otherCont.body_type_2 );
211  EXPECT_NEAR (thisCont.depth, otherCont.depth, 0.00001);
212  EXPECT_NEAR (thisCont.pos.x(), otherCont.pos.x(), 0.00001);
213  EXPECT_NEAR (thisCont.pos.y(), otherCont.pos.y(), 0.00001);
214  EXPECT_NEAR (thisCont.pos.z(), otherCont.pos.z(), 0.00001);
215  EXPECT_NEAR (thisCont.normal.x(), otherCont.normal.x(), 0.00001);
216  EXPECT_NEAR (thisCont.normal.y(), otherCont.normal.y(), 0.00001);
217  EXPECT_NEAR (thisCont.normal.z(), otherCont.normal.z(), 0.00001);
218 
219  // TODO HOW TO print this once and only if any of the expect at this loop iteration fails?
220  if ( (std::abs(thisCont.depth - otherCont.depth)) > 0.00001) {
221  std::cout << "EXPECT equal depths fails: error is on the actionState_" << i << std::endl;
222  pinchCasted->print();
223  pinchMap.at(keyPair).print();
224  std::cout << std::endl;
225  }
226 
227  i++;
228  }
229  }
230 }
231 
232 
234 TEST_F ( testFindPinches, checkNumberLinksLoose ) {
235 
236  for (auto &mapEl: pinchLooseMap ) {
237 
238  //being a pair the .first has always dimension 2
239  EXPECT_EQ (2, mapEl.second.getFingersInvolved().size() ); //the names inside the action
240  EXPECT_EQ (2, mapEl.second.getnFingersInvolved() ); //the int nLinkInvolved member of action
241  }
242 
243  for (auto &mapEl: pinchLooseParsedMap ) {
244 
245  EXPECT_EQ (2, mapEl.first.size()); // the key
246  EXPECT_EQ (2, mapEl.second->getFingersInvolved().size()); //the names inside the action
247  EXPECT_EQ (2, mapEl.second->getnFingersInvolved()); //the int nLinkInvolved member of action
248  }
249 }
250 
251 TEST_F ( testFindPinches, checkSizeStatesInfoSetLoose ) {
252 
253  for (auto &mapEl: pinchLooseMap ) {
254 
255  //get the member which is set in costructor
256  unsigned int size = mapEl.second.getMaxStoredActionStates();
257 
258  //it must be equal to the real size of the action state set
259  EXPECT_EQ ( size, mapEl.second.getActionStates().size() );
260  EXPECT_EQ ( size, mapEl.second.getAllJointPos().size() );
261  }
262 
263  for (auto &mapEl: pinchLooseParsedMap ) {
264 
265  //get the member which is set in costructor
266  unsigned int size = mapEl.second->getMaxStoredActionStates();
267 
268  EXPECT_EQ (size, mapEl.second->getAllJointPos().size());
269  }
270 }
271 
272 TEST_F ( testFindPinches, checkNameLoose ) {
273 
274  for (auto &mapEl: pinchLooseMap ) {
275 
276  EXPECT_TRUE (mapEl.second.getName().compare("pinchLoose") == 0);
277  EXPECT_EQ (ROSEE::ActionPrimitive::Type::PinchLoose, mapEl.second.getPrimitiveType() );
278  }
279 
280  for (auto &mapEl: pinchLooseParsedMap ) {
281 
282  EXPECT_TRUE (mapEl.second->getName().compare("pinchLoose") == 0);
283  EXPECT_EQ (ROSEE::ActionPrimitive::Type::PinchLoose, mapEl.second->getPrimitiveType() );
284  }
285 }
286 
287 //this is an important test: check if the order of statesInfo in right according to distance
288 TEST_F ( testFindPinches, checkOrderStatesInfoSetLoose ) {
289 
290  for (auto &mapEl: pinchLooseMap ) {
291 
292  std::vector < ROSEE::ActionPinchLoose::StateWithDistance> statesInfo =
293  mapEl.second.getActionStates();
294 
295  double oldDist = 0;
296  for (auto &setEl : statesInfo) {
297  EXPECT_GE ( setEl.second, oldDist ); //greater or equal
298  oldDist = setEl.second;
299  }
300  }
301 
302 
303  for (auto &mapEl: pinchLooseParsedMap ) {
304 
305  std::shared_ptr <ROSEE::ActionPinchLoose> pinchLooseCasted =
306  std::dynamic_pointer_cast < ROSEE::ActionPinchLoose > (mapEl.second);
307 
308  ASSERT_FALSE (pinchLooseCasted == nullptr);
309  std::vector < ROSEE::ActionPinchLoose::StateWithDistance> statesInfo =
310  pinchLooseCasted->getActionStates();
311 
312  double oldDist = 0;
313  for (auto &setEl : statesInfo) {
314  EXPECT_GE ( setEl.second, oldDist ); //greater or equal
315  oldDist = setEl.second;
316  }
317  }
318 }
319 
320 // to check if the found map is the same map that is emitted in the file and then parsed
321 TEST_F ( testFindPinches, checkEmitParseLoose ) {
322 
323  ASSERT_EQ (pinchLooseMap.size(), pinchLooseParsedMap.size() );
324 
325  for (auto &mapEl: pinchLooseParsedMap ) {
326 
327  std::shared_ptr <ROSEE::ActionPinchLoose> pinchCasted =
328  std::dynamic_pointer_cast < ROSEE::ActionPinchLoose > (mapEl.second);
329 
330  ASSERT_FALSE (pinchCasted == nullptr);
331  ASSERT_EQ (2, mapEl.first.size() ); // the key set must have dim 2 (the tip pair)
332  std::pair <std::string, std::string> keyPair;
333  std::set<std::string>::iterator it = mapEl.first.begin();
334  keyPair.first = *it;
335  std::advance ( it, 1 );
336  keyPair.second = *it;
337 
338  //std::string is ok to compare with _EQ
339  EXPECT_EQ (pinchCasted->getName(), pinchLooseMap.at(keyPair).getName() );
340  EXPECT_EQ (pinchCasted->getnFingersInvolved(), pinchLooseMap.at(keyPair).getnFingersInvolved() );
341  EXPECT_EQ (pinchCasted->getMaxStoredActionStates(), pinchLooseMap.at(keyPair).getMaxStoredActionStates());
342  EXPECT_EQ (pinchCasted->getPrimitiveType(), pinchLooseMap.at(keyPair).getPrimitiveType() );
343  EXPECT_EQ (pinchCasted->getFingersInvolved(), pinchLooseMap.at(keyPair).getFingersInvolved());
344 
345  unsigned int i = 0;
346  for (auto as: pinchCasted->getActionStates() ) {
347 
348  //check equality of joint states (as.first)
349  for (auto joint : as.first) {
350  ASSERT_EQ ( joint.second.size(),
351  pinchLooseMap.at(keyPair).getAllJointPos().at(i).at(joint.first).size() );
352  //loop the eventually multiple joint pos (when dofs > 1)
353  for (int j=0; j<joint.second.size(); ++j){
354  EXPECT_DOUBLE_EQ ( joint.second.at(j),
355  pinchLooseMap.at(keyPair).getAllJointPos().at(i).at(joint.first).at(j) );
356  }
357  }
358 
359  //check equality of distance (as.second)
360  EXPECT_DOUBLE_EQ (as.second, pinchLooseMap.at(keyPair).getActionStates().at(i).second);
361 
362  i++;
363  }
364  }
365 }
366 
367 
368 //A tight pinch cant be a loose pinch and viceversa
369 //here we check if all entries of one map are not present in the other (and viceversa)
370 //we check only the not parsed maps, other tests are done for correctness of parsing (checkEmitParse)
371 TEST_F ( testFindPinches, checkTightLooseExclusion ) {
372 
373  for (auto mapEl : pinchMap ) {
374  EXPECT_EQ (0, pinchLooseMap.count(mapEl.first)) << mapEl.first.first << ", " << mapEl.first.second
375  << " " << " is also present in Loose Pinches" << std::endl;
376  }
377 
378  for (auto mapEl : pinchLooseMap ) {
379  EXPECT_EQ (0, pinchMap.count(mapEl.first)) << mapEl.first.first << ", " << mapEl.first.second
380  << " " << " is also present in Tight Pinches" << std::endl;
381  }
382 
383 }
384 
385 
386 
387 } //namespace
388 
389 int main ( int argc, char **argv ) {
390 
391  if (argc < 2 ){
392 
393  std::cout << "[TEST ERROR] Insert hand name as argument" << std::endl;
394  return -1;
395  }
396 
397  /* Run tests on an isolated roscore */
398  if(setenv("ROS_MASTER_URI", "http://localhost:11322", 1) == -1)
399  {
400  perror("setenv");
401  return 1;
402  }
403 
404  //run roscore
405  std::unique_ptr<ROSEE::TestUtils::Process> roscore;
406  roscore.reset(new ROSEE::TestUtils::Process({"roscore", "-p", "11322"}));
407 
408  if ( ROSEE::TestUtils::prepareROSForTests ( argc, argv, "testFindPinches" ) != 0 ) {
409 
410  std::cout << "[TEST ERROR] Prepare Funcion failed" << std::endl;
411  return -1;
412  }
413 
414 
415  ::testing::InitGoogleTest ( &argc, argv );
416  return RUN_ALL_TESTS();
417 }
std::map< std::set< std::string >, ROSEE::ActionPrimitive::Ptr > parseYamlPrimitive(std::string fileWithPath)
Parse a yaml file and return the map with all the actions present in the file. For the moment...
Definition: YamlWorker.cpp:144
int main(int argc, char **argv)
std::size_t size(custom_string const &s)
The action of pinch with two tips. The two tips must not collide ever (otherwise we have a TightPinch...
#define EXPECT_NEAR(a, b, prec)
#define EXPECT_EQ(a, b)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector3d pos
int prepareROSForTests(int argc, char **argv, std::string testName)
Function to be called in the main of each test, it runs roscore and fill parameter server with robot ...
Definition: testUtils.h:95
Class to check which fingertips collide (for the pinch action at the moment)
Definition: FindActions.h:36
The action of pinch with two tips. The two tips must collide for some hand configuration to mark this...
#define EXPECT_TRUE(args)
TEST_F(TestRunner, threaded_test)


end-effector
Author(s): Luca Muratore , Davide Torielli , Liana Bertoni
autogenerated on Tue Apr 5 2022 02:57:53