icub-test
Loading...
Searching...
No Matches
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
34using namespace robottestingframework;
35using namespace yarp::os;
36using namespace yarp::dev;
37
38// prepare the plugin
39ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(OpenLoopConsistency)
40
41OpenLoopConsistency::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
57OpenLoopConsistency::~OpenLoopConsistency() { }
58
59bool 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
123void 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
135void 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
145void 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
175void 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
202void 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
235void 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
300void 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
369void 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
434void 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}