icub-test
All Data Structures Modules Pages
OpenloopConsistency.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 
22 #include <math.h>
23 #include <robottestingframework/TestAssert.h>
24 #include <robottestingframework/dll/Plugin.h>
25 #include <yarp/os/Time.h>
26 #include <yarp/os/Property.h>
27 
28 #include "OpenloopConsistency.h"
29 
30 //example1 -v -t OpenLoopConsistency.dll -p "--robot icub --part head --joints ""(0)"" --home ""(0)"" "
31 //example2 -v -t OpenLoopConsistency.dll -p "--robot icub --part head --joints ""(0 1 2)"" --home ""(0 0 0)"" "
32 //example3 -v -t OpenLoopConsistency.dll -p "--robot icub --part head --joints ""(0 1 2 3 4 5)"" --home ""(0 0 0 0 0 10)"" "
33 
34 using namespace robottestingframework;
35 using namespace yarp::os;
36 using namespace yarp::dev;
37 
38 // prepare the plugin
39 ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(OpenLoopConsistency)
40 
41 OpenLoopConsistency::OpenLoopConsistency() : yarp::robottestingframework::TestCase("OpenLoopConsistency") {
42  jointsList=0;
43  pos_tot=0;
44  dd=0;
45  ipos=0;
46  iamp=0;
47  icmd=0;
48  iimd=0;
49  ienc=0;
50  ipwm = 0;
51  cmd_some=0;
52  cmd_tot=0;
53  prevcurr_some=0;
54  prevcurr_tot=0;
55 }
56 
57 OpenLoopConsistency::~OpenLoopConsistency() { }
58 
59 bool OpenLoopConsistency::setup(yarp::os::Property& property) {
60 
61  if(property.check("name"))
62  setName(property.find("name").asString());
63 
64  // updating parameters
65  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("robot"), "The robot name must be given as the test parameter!");
66  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("part"), "The part name must be given as the test parameter!");
67  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("joints"), "The joints list must be given as the test parameter!");
68  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("home"), "The home positions must be given as the test parameter!");
69 
70  robotName = property.find("robot").asString();
71  partName = property.find("part").asString();
72 
73  Bottle* homeBottle = property.find("home").asList();
74  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(homeBottle!=0,"unable to parse home parameter");
75 
76  Bottle* jointsBottle = property.find("joints").asList();
77  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(jointsBottle!=0,"unable to parse joints parameter");
78  n_cmd_joints = jointsBottle->size();
79  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(n_cmd_joints>0,"invalid number of joints, it must be >0");
80 
81  Property options;
82  options.put("device", "remote_controlboard");
83  options.put("remote", "/"+robotName+"/"+partName);
84  options.put("local", "/OpenLoopConsistencyTest/"+robotName+"/"+partName);
85 
86  dd = new PolyDriver(options);
87  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->isValid(),"Unable to open device driver");
88  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipwm), "Unable to open pwm control interface");
89  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ienc),"Unable to open encoders interface");
90  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iamp),"Unable to open ampliefier interface");
91  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipos),"Unable to open position interface");
92  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(icmd),"Unable to open control mode interface");
93  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimd),"Unable to open interaction mode interface");
94 
95  if (!ienc->getAxes(&n_part_joints))
96  {
97  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("unable to get the number of joints of the part");
98  }
99 
100  if (n_part_joints<=0)
101  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Error this part has in invalid (<=0) number of jonits");
102  else if (jointsBottle->size() == 1)
103  cmd_mode=single_joint;
104  else if (jointsBottle->size() < n_part_joints)
105  cmd_mode=some_joints;
106  else if (jointsBottle->size() == n_part_joints)
107  cmd_mode=all_joints;
108  else
109  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("invalid joint selection?");
110 
111  cmd_tot = new double[n_part_joints];
112  pos_tot=new double[n_part_joints];
113  jointsList=new int[n_cmd_joints];
114  cmd_some=new double[n_cmd_joints];
115  prevcurr_tot=new double[n_part_joints];
116  prevcurr_some=new double[n_cmd_joints];
117  home=new double[n_cmd_joints];
118  for (int i=0; i <n_cmd_joints; i++) jointsList[i]=jointsBottle->get(i).asInt32();
119  for (int i=0; i <n_cmd_joints; i++) home[i]=homeBottle->get(i).asFloat64();
120  return true;
121 }
122 
123 void OpenLoopConsistency::tearDown()
124 {
125 
126  setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
127  goHome();
128 
129 
130  if (jointsList) {delete jointsList; jointsList =0;}
131  if(home){delete [] home; home=0;}
132  if (dd) {delete dd; dd =0;}
133 }
134 
135 void OpenLoopConsistency::setMode(int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode)
136 {
137  for (int i=0; i<n_cmd_joints; i++)
138  {
139  icmd->setControlMode(jointsList[i],desired_control_mode);
140  iimd->setInteractionMode(jointsList[i],desired_interaction_mode);
141  yarp::os::Time::delay(0.010);
142  }
143 }
144 
145 void OpenLoopConsistency::verifyMode(int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode, std::string title)
146 {
147  int cmode;
148  yarp::dev::InteractionModeEnum imode;
149  int timeout = 0;
150 
151  while (1)
152  {
153  int ok=0;
154  for (int i=0; i<n_cmd_joints; i++)
155  {
156  icmd->getControlMode (jointsList[i],&cmode);
157  iimd->getInteractionMode(jointsList[i],&imode);
158  if (cmode==desired_control_mode && imode==desired_interaction_mode) ok++;
159  }
160  if (ok==n_cmd_joints) break;
161  if (timeout>100)
162  {
163  char sbuf[500];
164  sprintf(sbuf,"Test (%s) failed: current mode is (%s,%s), it should be (%s,%s)",title.c_str(), Vocab32::decode((NetInt32)desired_control_mode).c_str(),Vocab32::decode((NetInt32)desired_interaction_mode).c_str(), Vocab32::decode((NetInt32)cmode).c_str(),Vocab32::decode((NetInt32)imode).c_str());
165  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
166  }
167  yarp::os::Time::delay(0.2);
168  timeout++;
169  }
170  char sbuf[500];
171  sprintf(sbuf,"Test (%s) passed: current mode is (%s,%s)",title.c_str(), Vocab32::decode((NetInt32)desired_control_mode).c_str(),Vocab32::decode((NetInt32)desired_interaction_mode).c_str());
172  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
173 }
174 
175 void OpenLoopConsistency::goHome()
176 {
177  for (int i=0; i<n_cmd_joints; i++)
178  {
179  ipos->setRefSpeed(jointsList[i],20.0);
180  ipos->positionMove(jointsList[i],home[i]);
181  }
182 
183  int timeout = 0;
184  while (1)
185  {
186  int in_position=0;
187  for (int i=0; i<n_cmd_joints; i++)
188  {
189  ienc->getEncoder(jointsList[i],&pos_tot[jointsList[i]]);
190  if (fabs(pos_tot[jointsList[i]]-home[i])<0.5) in_position++;
191  }
192  if (in_position==n_cmd_joints) break;
193  if (timeout>100)
194  {
195  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Timeout while reaching home position");
196  }
197  yarp::os::Time::delay(0.2);
198  timeout++;
199  }
200 }
201 
202 void OpenLoopConsistency::setRefOpenloop(double value)
203 {
204  cmd_single=value;
205  if (cmd_mode==single_joint)
206  {
207  for (int i=0; i<n_cmd_joints; i++)
208  {
209  ipwm->setRefDutyCycle(jointsList[i], cmd_single);
210  }
211  }
212  else if (cmd_mode==some_joints)
213  {
214  //same of single_joint, since multiple joint is not currently supported
215  for (int i=0; i<n_cmd_joints; i++)
216  {
217  ipwm->setRefDutyCycle(jointsList[i], cmd_single);
218  }
219  }
220  else if (cmd_mode==all_joints)
221  {
222  for (int i=0; i<n_part_joints; i++)
223  {
224  cmd_tot[i]=cmd_single;
225  }
226  ipwm->setRefDutyCycles(cmd_tot);
227  }
228  else
229  {
230  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Invalid cmd_mode");
231  }
232  yarp::os::Time::delay(0.010);
233 }
234 
235 void OpenLoopConsistency::verifyRefOpenloop(double verify_val, std::string title)
236 {
237  double value;
238  char sbuf[500];
239  if (cmd_mode==single_joint)
240  {
241  for (int i=0; i<n_cmd_joints; i++)
242  {
243  ipwm->getRefDutyCycle(jointsList[i], &value);
244  if (value==verify_val)
245  {
246  sprintf(sbuf,"Test (%s) passed, j%d current reference is (%f)",title.c_str(),i, verify_val);
247  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
248  }
249  else
250  {
251  sprintf(sbuf,"Test (%s) failed: current reference is (%f), it should be (%f)",title.c_str(), value, verify_val);
252  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
253  }
254  }
255  }
256  else if (cmd_mode==some_joints)
257  {
258  //same of single_joint, since multiple joint is not currently supported
259  for (int i=0; i<n_cmd_joints; i++)
260  {
261  ipwm->getRefDutyCycle(jointsList[i], &value);
262  if (value==verify_val)
263  {
264  sprintf(sbuf,"Test (%s) passed j%d current reference is (%f)",title.c_str(),i, verify_val);
265  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
266  }
267  else
268  {
269  sprintf(sbuf,"Test (%s) failed: current reference is (%f), it should be (%f)",title.c_str(), value, verify_val);
270  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
271  }
272  }
273  }
274  else if (cmd_mode==all_joints)
275  {
276  int ok=0;
277  ipwm->getRefDutyCycles(cmd_tot);
278  for (int i=0; i<n_part_joints; i++)
279  {
280  if (verify_val==cmd_tot[i]) ok++;
281  }
282  if (ok==n_part_joints)
283  {
284  sprintf(sbuf,"Test (%s) passed, current reference is (%f)",title.c_str(), verify_val);
285  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
286  }
287  else
288  {
289  sprintf(sbuf,"Test (%s) failed: only %d joints (of %d) are ok",title.c_str(),ok,n_part_joints);
290  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
291  }
292  }
293  else
294  {
295  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Invalid cmd_mode");
296  }
297  yarp::os::Time::delay(0.010);
298 }
299 
300 void OpenLoopConsistency::verifyOutputEqual(double verify_val, std::string title)
301 {
302  double value;
303  char sbuf[500];
304  if (cmd_mode==single_joint)
305  {
306  for (int i=0; i<n_cmd_joints; i++)
307  {
308  ipwm->getDutyCycle(jointsList[i], &value);
309  if (value==verify_val)
310  {
311  sprintf(sbuf,"Test (%s) passed, j%d current output is (%f)",title.c_str(),i, verify_val);
312  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
313  }
314  else
315  {
316  sprintf(sbuf,"Test (%s) failed: current output is (%f), it should be (%f)",title.c_str(), value, verify_val);
317  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
318  }
319  }
320  }
321  else if (cmd_mode==some_joints)
322  {
323  //same of single_joint, since multiple joint is not currently supported
324  for (int i=0; i<n_cmd_joints; i++)
325  {
326  ipwm->getDutyCycle(jointsList[i], &value);
327  if (value==verify_val)
328  {
329  sprintf(sbuf,"Test (%s) passed j%d current output is (%f)",title.c_str(),i,verify_val);
330  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
331  }
332  else
333  {
334  sprintf(sbuf,"Test (%s) failed: current output is (%f), it should be (%f)",title.c_str(), value, verify_val);
335  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
336  }
337  }
338  }
339  else if (cmd_mode==all_joints)
340  {
341  int ok=0;
342  ipwm->getDutyCycles(cmd_tot);
343  for (int i=0; i<n_part_joints; i++)
344  {
345  if (verify_val==cmd_tot[i]) ok++;
346  else
347  {
348  ROBOTTESTINGFRAMEWORK_TEST_REPORT(robottestingframework::Asserter::format("verify_val=%.2f, read_val=%.2f j=%d",verify_val, cmd_tot[i], i ));
349  }
350  }
351  if (ok==n_part_joints)
352  {
353  sprintf(sbuf,"Test (%s) passed current output is (%f)",title.c_str(), verify_val);
354  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
355  }
356  else
357  {
358  sprintf(sbuf,"Test (%s) failed: only %d joints (of %d) are ok",title.c_str(),ok,n_part_joints);
359  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
360  }
361  }
362  else
363  {
364  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Invalid cmd_mode");
365  }
366  yarp::os::Time::delay(0.010);
367 }
368 
369 void OpenLoopConsistency::verifyOutputDiff(double verify_val, std::string title)
370 {
371  double value;
372  char sbuf[500];
373  if (cmd_mode==single_joint)
374  {
375  for (int i=0; i<n_cmd_joints; i++)
376  {
377  ipwm->getDutyCycle(jointsList[i], &value);
378  if (value!=verify_val)
379  {
380  sprintf(sbuf,"Test (%s) passed j%d, current output is (%f!=%f)",title.c_str(),i,value,verify_val);
381  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
382  }
383  else
384  {
385  sprintf(sbuf,"Test (%s) failed: current output is (%f), it should be (%f)",title.c_str(), value, verify_val);
386  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
387  }
388  }
389  }
390  else if (cmd_mode==some_joints)
391  {
392  //same of single_joint, since multiple joint is not currently supported
393  for (int i=0; i<n_cmd_joints; i++)
394  {
395  ipwm->getDutyCycle(jointsList[i], &value);
396  if (value!=verify_val)
397  {
398  sprintf(sbuf,"Test (%s) passed j%d current output is (%f!=%f)",title.c_str(), i,value,verify_val);
399  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
400  }
401  else
402  {
403  sprintf(sbuf,"Test (%s) failed: current output is (%f), it should be (%f)",title.c_str(), value, verify_val);
404  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
405  }
406  }
407  }
408  else if (cmd_mode==all_joints)
409  {
410  int ok=0;
411  ipwm->getDutyCycles(cmd_tot);
412  for (int i=0; i<n_part_joints; i++)
413  {
414  if (verify_val!=cmd_tot[i]) ok++;
415  }
416  if (ok==n_part_joints)
417  {
418  sprintf(sbuf,"Test (%s) passed current output is (%f!=%f)",title.c_str(),value,verify_val);
419  ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
420  }
421  else
422  {
423  sprintf(sbuf,"Test (%s) failed: only %d joints (of %d) are ok",title.c_str(),ok,n_part_joints);
424  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
425  }
426  }
427  else
428  {
429  ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("Invalid cmd_mode");
430  }
431  yarp::os::Time::delay(0.010);
432 }
433 
434 void OpenLoopConsistency::run()
435 {
436  setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
437  verifyMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF,"test0");
438  goHome();
439  //verifyRefOpenloop(0,"test0a"); if I get openLoop reference I get last given refrence
440  //verifyOutputDiff(0,"test0b"); //TO BE CHECKED
441 
442  setMode(VOCAB_CM_PWM,VOCAB_IM_STIFF);
443  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test1");
444  verifyRefOpenloop(0,"test0a"); //When joint swap in pwm control mode, the reference should be 0.
445  verifyOutputEqual(0,"test1a");// here i can check that iPwm reference = 0.
446  setRefOpenloop(1);
447  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test2");
448  verifyRefOpenloop(1,"test2a");
449  verifyOutputEqual(1,"test2b");
450  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test3");
451  setRefOpenloop(0);
452  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test4");
453  verifyRefOpenloop(0,"test3a");
454  verifyOutputEqual(0,"test3b");
455  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test5");
456  setRefOpenloop(-1);
457  verifyMode(VOCAB_CM_PWM, VOCAB_IM_STIFF, "test6");
458  verifyRefOpenloop(-1,"test6a");
459  verifyOutputEqual(-1,"test6b");
460 
461  setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
462  verifyMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF,"test7");
463  goHome();
464  verifyRefOpenloop(-1,"test7a");
465  //verifyOutputDiff(0,"test7b"); //TO BE CHECKED
466 
467 }