22 #include <robottestingframework/TestAssert.h>
23 #include <robottestingframework/dll/Plugin.h>
24 #include <yarp/robottestingframework/TestAsserter.h>
25 #include <yarp/os/Time.h>
26 #include <yarp/os/Property.h>
27 #include <yarp/os/LogStream.h>
28 #include <yarp/os/ResourceFinder.h>
39 #include "TorqueControlStiffDampCheck.h"
42 using namespace robottestingframework;
44 using namespace yarp::dev;
48 ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(TorqueControlStiffDampCheck)
50 TorqueControlStiffDampCheck::TorqueControlStiffDampCheck() : yarp::robottestingframework::TestCase(
"TorqueControlStiffDampCheck") {
67 TorqueControlStiffDampCheck::~TorqueControlStiffDampCheck() { }
69 bool TorqueControlStiffDampCheck::setup(yarp::os::Property& property) {
72 if(property.check(
"name"))
73 setName(property.find(
"name").asString());
76 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"robot"),
"The robot name must be given as the test parameter!");
77 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"part"),
"The part name must be given as the test parameter!");
78 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"joints"),
"The joints list must be given as the test parameter!");
79 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"home"),
"The home position list must be given as the test parameter!");
80 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"stiffness"),
"The stiffness list must be given as the test parameter!");
81 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"damping"),
"The damping listmust be given as the test parameter!");
82 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"duration"),
"The duration must be given as the test parameter!");
84 robotName =
property.find(
"robot").asString();
85 partName =
property.find(
"part").asString();
89 Bottle* jointsBottle =
property.find(
"joints").asList();
90 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(jointsBottle!=0,
"unable to parse joints parameter");
91 n_cmd_joints = jointsBottle->size();
92 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(n_cmd_joints>0,
"invalid number of joints, it must be >0");
94 Bottle *b_stiff =
property.find(
"stiffness").asList();
95 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(b_stiff!=0,
"unable to parse stiffness parameter");
96 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE((b_stiff->size()==n_cmd_joints), Asserter::format(
"invalid number of stiffness values %d %d", b_stiff->size(), n_cmd_joints));
98 Bottle *b_dump =
property.find(
"damping").asList();
99 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(b_dump!=0,
"unable to parse damping parameter");
100 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(b_dump->size()==n_cmd_joints,
"invalid number of damping values");
102 Bottle *b_home =
property.find(
"home").asList();
103 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(b_home!=0,
"unable to parse home parameter");
104 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(b_home->size()==n_cmd_joints,
"invalid number of home values");
106 testLen_sec =
property.find(
"duration").asFloat64();
107 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(testLen_sec>0,
"duretion should be bigger than 0");
109 if(property.check(
"plot_enabled"))
111 plot_enabled =
property.find(
"plot_enabled").asBool();
114 yInfo() <<
"Plot is enabled: the test will run octave and plot test result ";
116 yInfo() <<
"Plot is not enabled. The test collects only data. The user need to plot data to theck if test has successed.";
119 options.put(
"device",
"remote_controlboard");
120 options.put(
"remote",
"/"+robotName+
"/"+partName);
121 options.put(
"local",
"/TorqueControlStiffDampCheckTest/"+robotName+
"/"+partName);
123 dd =
new PolyDriver(options);
124 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->isValid(),
"Unable to open device driver");
125 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(itrq),
"Unable to open torque control interface");
126 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ienc),
"Unable to open encoders interface");
127 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iamp),
"Unable to open ampliefier interface");
128 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipos),
"Unable to open position interface");
129 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(icmd),
"Unable to open control mode interface");
130 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimd),
"Unable to open interaction mode interface");
131 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimp),
"Unable to open impedence control interface");
134 if (!ienc->getAxes(&n_part_joints))
136 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"unable to get the number of joints of the part");
140 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Error this part has in invalid (<=0) number of jonits");
144 jointsList=
new int[n_cmd_joints];
145 stiffness=
new double[n_cmd_joints];
146 damping=
new double[n_cmd_joints];
147 pos_tot=
new double[n_cmd_joints];
148 home=
new double[n_cmd_joints];
150 for (
int i=0; i <n_cmd_joints; i++) jointsList[i]=jointsBottle->get(i).asInt32();
151 for (
int i=0; i <n_cmd_joints; i++) stiffness[i]=b_stiff->get(i).asFloat64();
152 for (
int i=0; i <n_cmd_joints; i++) damping[i]=b_dump->get(i).asFloat64();
153 for (
int i=0; i <n_cmd_joints; i++) home[i]=b_home->get(i).asFloat64();
157 void TorqueControlStiffDampCheck::tearDown()
159 if (jointsList) {
delete jointsList; jointsList =0;}
160 if (stiffness) {
delete stiffness; stiffness =0;}
161 if (damping) {
delete damping; damping =0;}
162 if (dd) {
delete dd; dd =0;}
165 void TorqueControlStiffDampCheck::setMode(
int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode)
167 for (
int i=0; i<n_cmd_joints; i++)
169 icmd->setControlMode(jointsList[i],desired_control_mode);
170 iimd->setInteractionMode(jointsList[i],desired_interaction_mode);
171 yarp::os::Time::delay(0.010);
175 void TorqueControlStiffDampCheck::verifyMode(
int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode, std::string title)
178 yarp::dev::InteractionModeEnum imode;
184 for (
int i=0; i<n_cmd_joints; i++)
186 icmd->getControlMode (jointsList[i],&cmode);
187 iimd->getInteractionMode(jointsList[i],&imode);
188 if (cmode==desired_control_mode && imode==desired_interaction_mode) ok++;
190 if (ok==n_cmd_joints)
break;
194 sprintf(sbuf,
"Test (%s) failed: current mode is (%s,%s), it should be (%s,%s)",title.c_str(),
195 Vocab32::decode((NetInt32)desired_control_mode).c_str(),
196 Vocab32::decode((NetInt32)desired_interaction_mode).c_str(),
197 Vocab32::decode((NetInt32)cmode).c_str(),
198 Vocab32::decode((NetInt32)imode).c_str());
199 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(sbuf);
201 yarp::os::Time::delay(0.2);
205 sprintf(sbuf,
"Test (%s) passed: current mode is (%s,%s)",title.c_str(), Vocab32::decode((NetInt32)desired_control_mode).c_str(),
206 Vocab32::decode((NetInt32)desired_interaction_mode).c_str());
207 ROBOTTESTINGFRAMEWORK_TEST_REPORT(sbuf);
210 void TorqueControlStiffDampCheck::goHome()
212 for (
int i=0; i<n_cmd_joints; i++)
214 ipos->setRefSpeed(jointsList[i],20.0);
215 ipos->positionMove(jointsList[i],home[i]);
222 for (
int i=0; i<n_cmd_joints; i++)
224 ienc->getEncoder(jointsList[i],&pos_tot[i]);
225 if (fabs(pos_tot[i]-home[i])<0.8) in_position++;
227 if (in_position==n_cmd_joints)
break;
230 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Timeout while reaching home[i] position");
232 yarp::os::Time::delay(0.2);
237 bool TorqueControlStiffDampCheck::setAndCheckImpedance(
int joint,
double stiffness,
double damping)
239 iimp->setImpedance(joint, stiffness, damping);
240 yarp::os::Time::delay(0.01);
241 double readStiff, readDump;
242 iimp->getImpedance(joint, &readStiff, &readDump);
244 double th = stiffness/100;
245 bool r1 = yarp::robottestingframework::TestAsserter::isApproxEqual(readStiff, stiffness, th, th);
247 bool r2 = yarp::robottestingframework::TestAsserter::isApproxEqual(readDump, damping, th, th);
251 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"J %d: set stiff=%f dump=%f. Read stiff=%f dump=%f ",joint, stiffness, damping, readStiff, readDump));
258 void TorqueControlStiffDampCheck::saveToFile(std::string filename, yarp::os::Bottle &b)
261 fs.open (filename.c_str(), std::fstream::out);
263 for (
int i=0; i<b.size(); i++)
265 std::string s = b.get(i).toString();
266 std::replace(s.begin(), s.end(),
'(',
' ');
267 std::replace(s.begin(), s.end(),
')',
' ');
275 std::string TorqueControlStiffDampCheck::getPath(
const std::string& str)
278 found=str.find_last_of(
"/\\");
279 return(str.substr(0,found));
283 void TorqueControlStiffDampCheck::run()
285 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
286 verifyMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF,
"test0");
288 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"try to move joints in home positions"));
291 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"try to set compliant mode"));
292 setMode(VOCAB_CM_POSITION,VOCAB_IM_COMPLIANT);
293 verifyMode(VOCAB_CM_POSITION,VOCAB_IM_COMPLIANT,
"test1");
295 for (
int i=0; i<n_cmd_joints; i++)
298 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"***** Start first part of test on joint %d......", jointsList[i]));
299 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(setAndCheckImpedance(jointsList[i], stiffness[i], 0) , Asserter::format(
"Error setting impedance on j %d", jointsList[i]));
305 itrq->getTorque(jointsList[i], &init_torque);
306 ROBOTTESTINGFRAMEWORK_TEST_REPORT(
"Now the user should move the joint....the test will collect values of position and torque. Press a char to continue....");
308 int unused = scanf(
"%c", &c);
309 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"startingto collact data of joint %d......", jointsList[i]));
311 double start_time = yarp::os::Time::now();
312 double curr_time = start_time;
313 while(curr_time < start_time+testLen_sec)
315 double curr_pos, torque, reftrq;
316 ienc->getEncoder(jointsList[i], &curr_pos);
317 itrq->getTorque(jointsList[i], &torque);
318 itrq->getRefTorque(jointsList[i], &reftrq);
320 Bottle& row = b_pos_trq.addList();
321 row.addFloat64(curr_pos-home[i]);
322 row.addFloat64(torque- init_torque);
323 row.addFloat64(reftrq);
324 yarp::os::Time::delay(0.01);
325 curr_time = yarp::os::Time::now();
328 string testfilename =
"posVStrq_";
330 b.addInt32(jointsList[i]);
331 string filename1 = testfilename + partName +
"_j" + b.toString().c_str() +
".txt";
332 saveToFile(filename1,b_pos_trq);
336 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"....DONE on joint %d", jointsList[i]));
337 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"***** Start second part of test on joint %d......", jointsList[i]));
338 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(setAndCheckImpedance(jointsList[i], 0, damping[i]) , Asserter::format(
"Error setting impedance on j %d", jointsList[i]));
340 itrq->getTorque(jointsList[i], &init_torque);
341 ROBOTTESTINGFRAMEWORK_TEST_REPORT(
"Now the user should move the joint....the test will collect values of position and torque. Press a char to continue....");
343 unused = scanf(
"%c", &c);
345 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"startingto collact data of joint %d......", jointsList[i]));
347 start_time = yarp::os::Time::now();
348 curr_time = start_time;
349 while(curr_time < start_time+testLen_sec)
351 double curr_vel, torque, reftrq;
352 ienc->getEncoderSpeed(jointsList[i], &curr_vel);
353 itrq->getTorque(jointsList[i], &torque);
354 itrq->getRefTorque(jointsList[i], &reftrq);
356 Bottle& row = b_vel_trq.addList();
357 row.addFloat64(curr_vel);
358 row.addFloat64(torque- init_torque);
359 row.addFloat64(reftrq);
360 yarp::os::Time::delay(0.01);
361 curr_time = yarp::os::Time::now();
364 testfilename =
"velVStrq_";
366 b1.addInt32(jointsList[i]);
367 filename1 = testfilename + partName +
"_j" + b1.toString().c_str() +
".txt";
368 saveToFile(filename1,b_vel_trq);
370 ROBOTTESTINGFRAMEWORK_TEST_REPORT(Asserter::format(
"....DONE on joint %d", jointsList[i]));
374 ROBOTTESTINGFRAMEWORK_TEST_REPORT(
"Test ended. Puts joints in pos stiff and moves them to home pos");
375 setMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF);
376 verifyMode(VOCAB_CM_POSITION,VOCAB_IM_STIFF,
"test2");
380 yarp::os::ResourceFinder rf;
381 rf.setDefaultContext(
"scripts");
384 std::string octaveFile = rf.findFile(
"torqueStiffDamp_plotAll.m");
385 if(octaveFile.size() == 0)
387 yError()<<
"Cannot find file encoderConsistencyPlotAll.m";
392 std::string octaveCommand=
"octave --path "+ getPath(octaveFile);
395 stringstream ss_stifness, ss_damping, ss_joints;
399 for(
int j=0; j<n_cmd_joints-1; j++)
401 ss_stifness << stiffness[j] <<
", ";
402 ss_damping << damping[j] <<
", ";
403 ss_joints << jointsList[j] <<
", ";
406 ss_stifness << stiffness[n_cmd_joints-1] <<
"]";
407 ss_damping << damping[n_cmd_joints-1] <<
"]";
408 ss_joints << jointsList[n_cmd_joints-1] <<
"]";
411 ss << n_cmd_joints <<
", "<< ss_stifness.str() <<
", " << ss_damping.str() <<
", " << ss_joints.str();
412 string str = ss.str();
413 octaveCommand+=
" -q --eval \"torqueStiffDamp_plotAll('" +partName +
"'," + str +
")\" --persist";
415 yInfo() <<
"octave cmd= " << octaveCommand;
418 int ret = system (octaveCommand.c_str());
422 yInfo() <<
"Test has collected all data. You need to plot data to check is test is passed";
423 yInfo() <<
"Please run following command to plot data.";
424 yInfo() << octaveCommand;
425 yInfo() <<
"To exit from Octave application please type 'exit' command.";