22 #include <robottestingframework/TestAssert.h>
23 #include <robottestingframework/dll/Plugin.h>
24 #include <yarp/os/Time.h>
25 #include <yarp/math/Math.h>
26 #include <yarp/os/Property.h>
30 #include "MotorStiction.h"
34 using namespace robottestingframework;
35 using namespace yarp::os;
36 using namespace yarp::dev;
39 ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(MotorStiction)
41 MotorStiction::MotorStiction() : yarp::robottestingframework::TestCase(
"MotorStiction") {
52 MotorStiction::~MotorStiction() { }
54 bool MotorStiction::setup(yarp::os::Property& property) {
55 if(property.check(
"name"))
56 setName(property.find(
"name").asString());
59 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"robot"),
"The robot name must be given as the test parameter!");
60 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"part"),
"The part name must be given as the test parameter!");
61 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"joints"),
"The joints list must be given as the test parameter!");
62 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"home"),
"The home position must be given as the test parameter!");
64 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"outputStep"),
"The output_step must be given as the test parameter!");
65 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"outputDelay") ,
"The output_delay must be given as the test parameter!");
66 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"outputMax"),
"The output_max must be given as the test parameter!");
67 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"threshold"),
"The threshold must be given as the test parameter!");
68 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"repeat"),
"The repeat must be given as the test parameter!");
70 robotName =
property.find(
"robot").asString();
71 partName =
property.find(
"part").asString();
73 repeat =
property.find(
"repeat").asInt32();
74 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(repeat>=0,
"repeat must be greater than zero");
76 Bottle* homeBottle =
property.find(
"home").asList();
77 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(homeBottle!=0,
"unable to parse zero parameter");
79 Bottle* jointsBottle =
property.find(
"joints").asList();
80 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(jointsBottle!=0,
"unable to parse joints parameter");
82 Bottle* output_step_Bottle =
property.find(
"outputStep").asList();
83 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(output_step_Bottle!=0,
"unable to parse joints parameter");
85 Bottle* output_delay_Bottle =
property.find(
"outputDelay").asList();
86 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(output_delay_Bottle!=0,
"unable to parse joints parameter");
88 Bottle* output_max_Bottle =
property.find(
"outputMax").asList();
89 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(output_max_Bottle!=0,
"unable to parse joints parameter");
91 Bottle* threshold_Bottle =
property.find(
"threshold").asList();
92 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(threshold_Bottle!=0,
"unable to parse joints parameter");
95 options.put(
"device",
"remote_controlboard");
96 options.put(
"remote",
"/"+robotName+
"/"+partName);
97 options.put(
"local",
"/MotorStictionTest/"+robotName+
"/"+partName);
99 dd =
new PolyDriver(options);
100 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->isValid(),
"Unable to open device driver");
101 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipwm),
"Unable to open pwm control interface");
102 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ienc),
"Unable to open encoders interface");
103 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iamp),
"Unable to open ampliefier interface");
104 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipos),
"Unable to open position interface");
105 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(icmd),
"Unable to open control mode interface");
106 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimd),
"Unable to open interaction mode interface");
107 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ilim),
"Unable to open limits interface");
109 if (!ienc->getAxes(&n_part_joints))
111 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"unable to get the number of joints of the part");
114 int n_cmd_joints = jointsBottle->size();
115 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(n_cmd_joints>0 && n_cmd_joints<=n_part_joints,"invalid number of joints, it must be >0 & <= number of part joints
");
116 for (int i=0; i <n_cmd_joints; i++) jointsList.push_back(jointsBottle->get(i).asInt32());
118 home.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) home[i]=homeBottle->get(i).asFloat64();
119 opl_step.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_step[i]=output_step_Bottle->get(i).asFloat64();
120 opl_delay.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_delay[i]=output_delay_Bottle->get(i).asFloat64();
121 opl_max.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_max[i]=output_max_Bottle->get(i).asFloat64();
122 movement_threshold.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) movement_threshold[i]=threshold_Bottle->get(i).asFloat64();
124 max_lims.resize(n_cmd_joints);
125 min_lims.resize(n_cmd_joints);
126 for (int i=0; i <n_cmd_joints; i++) ilim->getLimits((int)jointsList[i],&min_lims[i],&max_lims[i]);
131 void MotorStiction::tearDown()
134 sprintf(buff,"Closing test module
");ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
135 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
136 verifyMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF,"test0
");
138 if (dd) {delete dd; dd =0;}
141 void MotorStiction::setMode(int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode)
143 for (unsigned int i=0; i<jointsList.size(); i++)
145 icmd->setControlMode((int)jointsList[i],desired_control_mode);
146 iimd->setInteractionMode((int)jointsList[i],desired_interaction_mode);
147 yarp::os::Time::delay(0.010);
151 void MotorStiction::setModeSingle(int i, int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode)
153 icmd->setControlMode((int)jointsList[i],desired_control_mode);
154 iimd->setInteractionMode((int)jointsList[i],desired_interaction_mode);
155 yarp::os::Time::delay(0.010);
158 void MotorStiction::verifyMode(int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode, std::string title)
161 yarp::dev::InteractionModeEnum imode;
167 for (unsigned int i=0; i<jointsList.size(); i++)
169 icmd->getControlMode ((int)jointsList[i],&cmode);
170 iimd->getInteractionMode((int)jointsList[i],&imode);
171 if (cmode==desired_control_mode && imode==desired_interaction_mode) ok++;
173 if (ok==jointsList.size()) break;
177 sprintf(sbuf,"Test (%s) failed: current mode is (%d,%d), it should be (%d,%d)
",title.c_str(), desired_control_mode,desired_interaction_mode,cmode,imode);
178 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
180 yarp::os::Time::delay(0.2);
184 sprintf(sbuf,"Test (%s) passed: current mode is (%d,%d)
",title.c_str(), desired_control_mode,desired_interaction_mode);
185 ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
188 void MotorStiction::goHome()
190 for (unsigned int i=0; i<jointsList.size(); i++)
192 ipos->setRefSpeed((int)jointsList[i],20.0);
193 ipos->positionMove((int)jointsList[i],home[i]);
194 yarp::os::Time::delay(0.010);
198 sprintf(buff,"Homing the whole part
");ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
201 for (unsigned int i=0; i<jointsList.size(); i++)
203 double time_started = yarp::os::Time::now();
207 ienc->getEncoder((int)jointsList[i],&pos);
208 if (fabs(pos-home[i])<1.0) break;
209 if (yarp::os::Time::now()-time_started>20)
211 sprintf(buff,"Timeout
while reaching zero position, joint %d, curr_enc %f, home %f
", (int)jointsList[i],pos,home[i]);
212 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(buff);
217 sprintf(buff,"Homing succesfully completed
");ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
220 void MotorStiction::saveToFile(std::string filename, yarp::os::Bottle &b)
223 fs.open (filename.c_str(), std::fstream::out);
225 for (int i=0; i<b.size(); i++)
227 std::string s = b.get(i).toString();
228 std::replace(s.begin(), s.end(), '(', ' ');
229 std::replace(s.begin(), s.end(), ')', ' ');
230 fs << s << std::endl;
236 void MotorStiction::OplExecute(int i, std::vector<yarp::os::Bottle>& dataToPlotList, stiction_data& current_test, bool positive_sign)
239 double time = yarp::os::Time::now();
240 double time_old = yarp::os::Time::now();
243 ienc->getEncoder((int)jointsList[i],&enc);
244 ienc->getEncoder((int)jointsList[i],&start_enc);
245 bool not_moving = true;
247 setMode(VOCAB_CM_PWM, VOCAB_IM_STIFF);
248 ipwm->setRefDutyCycle((int)jointsList[i], opl);
249 double last_opl_cmd=yarp::os::Time::now();
254 Bottle& row = dataToPlot.addList();
255 Bottle& v1 = row.addList();
256 Bottle& v2 = row.addList();
258 ipwm->setRefDutyCycle((int)jointsList[i],opl);
259 ienc->getEncoder((int)jointsList[i],&enc);
261 //sprintf(buff,"%f %f %f %f
",enc,start_enc,fabs(enc-start_enc),movement_threshold[i]);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
263 if (fabs(enc-start_enc)>movement_threshold[i])
265 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
267 if (positive_sign) {current_test.pos_opl=opl; current_test.pos_test_passed=true;}
268 else {current_test.neg_opl=opl; current_test.neg_test_passed=true;}
269 dataToPlotList.push_back(dataToPlot);
270 sprintf(buff,"Test success (output=%f)
",opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
272 else if (opl>=opl_max[i])
274 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
276 if (positive_sign) {current_test.pos_opl=opl; current_test.pos_test_passed=false;}
277 else {current_test.neg_opl=opl; current_test.neg_test_passed=false;}
278 dataToPlotList.push_back(dataToPlot);
279 sprintf(buff,"Test failed failed because max output was reached(output=%f)
",opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
281 else if (fabs(enc-max_lims[i]) < 1.0 ||
282 fabs(enc-min_lims[i]) < 1.0 )
284 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
286 if (positive_sign) {current_test.pos_opl=opl; current_test.pos_test_passed=false;}
287 else {current_test.neg_opl=opl; current_test.neg_test_passed=false;}
288 dataToPlotList.push_back(dataToPlot);
289 sprintf(buff,"Test failed because hw limit was touched (enc=%f)
",enc);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
292 if (yarp::os::Time::now()-last_opl_cmd>opl_delay[i])
298 last_opl_cmd=yarp::os::Time::now();
301 time = yarp::os::Time::now();
305 yarp::os::Time::delay(0.010);
307 if (time-time_old>5.0 && not_moving==true)
309 sprintf(buff,"test in progress on joint %d, current output value = %f
",(int)jointsList[i],opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
315 void MotorStiction::OplExecute2(int i, std::vector<yarp::os::Bottle>& dataToPlotList, stiction_data& current_test, bool positive_sign)
318 double time = yarp::os::Time::now();
319 double time_old = yarp::os::Time::now();
322 ienc->getEncoder((int)jointsList[i],&enc);
323 ienc->getEncoder((int)jointsList[i],&start_enc);
324 bool not_moving = true;
326 setMode(VOCAB_CM_PWM,VOCAB_IM_STIFF);
327 ipwm->setRefDutyCycle((int)jointsList[i], opl);
328 double last_opl_cmd=yarp::os::Time::now();
333 Bottle& row = dataToPlot.addList();
334 Bottle& v1 = row.addList();
335 Bottle& v2 = row.addList();
337 ipwm->setRefDutyCycle((int)jointsList[i], opl);
338 ienc->getEncoder((int)jointsList[i],&enc);
340 //sprintf(buff,"%f %f %f %f
",enc,start_enc,fabs(enc-start_enc),movement_threshold[i]);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
344 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
346 if (positive_sign) {current_test.pos_opl=opl; current_test.pos_test_passed=false;}
347 else {current_test.neg_opl=opl; current_test.neg_test_passed=false;}
348 dataToPlotList.push_back(dataToPlot);
349 sprintf(buff,"Test failed failed because max output was reached(output=%f)
",opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
351 else if (fabs(enc-max_lims[i]) < 1.0 ||
352 fabs(enc-min_lims[i]) < 1.0 )
354 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
356 if (positive_sign) {current_test.pos_opl=opl; current_test.pos_test_passed=true;}
357 else {current_test.neg_opl=opl; current_test.neg_test_passed=true;}
358 dataToPlotList.push_back(dataToPlot);
359 sprintf(buff,"Test success (output=%f)
",opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
362 if (yarp::os::Time::now()-last_opl_cmd>opl_delay[i])
368 last_opl_cmd=yarp::os::Time::now();
371 time = yarp::os::Time::now();
375 yarp::os::Time::delay(0.010);
377 if (time-time_old>5.0 && not_moving==true)
379 sprintf(buff,"test in progress on joint %d, current output value = %f
",(int)jointsList[i],opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
385 void MotorStiction::run()
387 //yarp::os::Time::delay(10);
390 std::vector<Bottle> dataToPlotList;
392 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
395 for (unsigned int i=0 ; i<jointsList.size(); i++)
397 for (int repeat_count=0; repeat_count<repeat; repeat_count++)
399 stiction_data current_test;
400 current_test.jnt=(int)jointsList[i];
401 current_test.cycle= repeat_count;
403 setModeSingle(i,VOCAB_CM_PWM,VOCAB_IM_STIFF);
404 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
406 sprintf(buff,"Testing joint %d, cycle %d, positive output
",(int)jointsList[i],repeat_count);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
407 OplExecute(i,dataToPlotList,current_test, true);
409 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
412 setModeSingle(i, VOCAB_CM_PWM,VOCAB_IM_STIFF);
413 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
415 sprintf(buff,"Testing joint %d, cycle %d, negative output
",(int)jointsList[i],repeat_count);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
416 OplExecute(i,dataToPlotList,current_test, false);
418 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
421 //test cycle complete, save data
422 stiction_data_list.push_back(current_test);
425 sprintf (filename, "plot_stiction_%s_j%d_n_c%d.txt
",partName.c_str(),(int)jointsList[i],repeat_count);
426 saveToFile(filename,dataToPlotList.rbegin()[0]); //last element
427 sprintf (filename, "plot_stiction_%s_j%d_p_c%d.txt
",partName.c_str(),(int)jointsList[i],repeat_count);
428 saveToFile(filename,dataToPlotList.rbegin()[1]); //second last element
434 for (unsigned int i=0 ; i<jointsList.size(); i++)
437 char plotstring[1000];
438 sprintf (filename, "plot_stiction_j%d.txt
",(int)jointsList[i]);
439 //gnuplot -e "unset key; plot
for [col=1:6]
'C:\software\icub-tests\build\plugins\Debug\plot.txt' using col with lines
" -persist
440 sprintf (plotstring, "gnuplot -e \
" unset key; plot for [col=1:%d] '%s' using col with lines \" -persist", n_part_joints,filename);
445 for (
unsigned int i=0; i <stiction_data_list.size(); i++)
447 if (stiction_data_list[i].neg_test_passed==
false)
450 sprintf(buff,
"test failed on joint %d, cycle %d, negative output value: %f",stiction_data_list[i].jnt,stiction_data_list[i].cycle,stiction_data_list[i].neg_opl);
451 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(buff);
453 else if (stiction_data_list[i].pos_test_passed==
false)
456 sprintf(buff,
"test failed on joint %d, cycle %d, positive output value: %f",stiction_data_list[i].jnt,stiction_data_list[i].cycle,stiction_data_list[i].pos_opl);
457 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(buff);