11#include <yarp/os/Time.h>
12#include <yarp/dev/PolyDriver.h>
18#include <yarp/os/LogStream.h>
20using namespace yarp::os;
28static bool extractGroup(Bottle &input, Bottle &
out,
const std::string &key1,
const std::string &txt,
int size)
31 Bottle &tmp=input.findGroup(key1.c_str(), txt.c_str());
34 yError () << key1.c_str() <<
" not found\n";
40 yError () << key1.c_str() <<
" incorrect number of entries in board.";
28static bool extractGroup(Bottle &input, Bottle &
out,
const std::string &key1,
const std::string &txt,
int size) {
…}
50bool parametricCalibratorEth::parseSequenceGroup(yarp::os::Searchable &config, std::string sequence, std::vector<PositionSequence> &seqList)
52 Bottle parkSeq_group = config.findGroup(sequence);
53 if (parkSeq_group.isNull())
62 if(!
extractGroup(parkSeq_group, xtmp,
"numberOfSequences",
"number of sequences listed ", 1))
67 numOfSeq = xtmp.get(1).asInt32();
69 seqList.resize(numOfSeq);
73 yError() <<
"ParametricCalibratorEth " << deviceName <<
"<numberOfSequences> must be a positive integer";
78 for(
int seq_idx=0; seq_idx<numOfSeq; seq_idx++)
80 char sequence_name[80];
81 snprintf(sequence_name, 80,
"SEQUENCE_%d", seq_idx);
83 Bottle &seq_i = parkSeq_group.findGroup(sequence_name);
86 yError() <<
"ParametricCalibratorEth " << deviceName <<
"cannot find " << sequence_name;
91 seqList.at(seq_idx).seq_num = seq_idx;
94 Bottle & poss = seq_i.findGroup(
"position",
"desired parking position");
97 yError() <<
"ParametricCalibratorEth " << deviceName <<
": <position> parameter not found for sequence " << sequence_name;
102 Bottle &vels = seq_i.findGroup(
"velocity",
"desired parking velocities");
105 yError() <<
"ParametricCalibratorEth " << deviceName <<
": <velocity> parameter not found for sequence " << sequence_name;
109 if(( poss.size() -1 != n_joints) || (vels.size() -1 != n_joints))
111 yError() <<
"ParametricCalibratorEth " << deviceName <<
": <position> or <velocity> parameter size for sequence " << sequence_name <<
" doesn not match the number of joint being calibrated.\n" << \
112 "Part joint number is " << n_joints <<
" while <position> size is " << poss.size()-1 <<
" and <velocity> size is " << vels.size()-1 <<
"; joint number is " << n_joints;
117 seqList[seq_idx].seq_num = seq_idx;
118 seqList[seq_idx].positions.reserve(n_joints);
119 seqList[seq_idx].velocities.reserve(n_joints);
121 for (
int j = 1; j <n_joints+1; j++)
123 seqList[seq_idx].positions .push_back(poss.get(j).asFloat64());
124 seqList[seq_idx].velocities.push_back(vels.get(j).asFloat64());
131 calibParams(nullptr),
132 original_max_pwm(nullptr),
133 limited_max_pwm(nullptr),
134 startupMaxPWM(nullptr),
138 startupPosThreshold(0),
141 skipCalibration(false),
143 skipReCalibration(false),
145 timeout_goToZero(nullptr),
146 timeout_calibration(nullptr),
147 disableHomeAndPark(nullptr),
148 disableStartupPosCheck(nullptr),
149 totJointsToCalibrate(0),
150 useLegacyParking(true),
151 currentParkingSeq_step(0)
165 p.fromString(config.toString());
167 if (
p.check(
"GENERAL")==
false)
169 yError() <<
"Parametric calibrator: missing [GENERAL] section";
173 if(
p.findGroup(
"GENERAL").check(
"deviceName"))
175 deviceName =
p.findGroup(
"GENERAL").find(
"deviceName").asString();
179 yError() <<
"Parametric calibrator: missing deviceName parameter";
184 if(config.findGroup(
"GENERAL").find(
"verbose").asInt32())
186 str=config.toString().c_str();
187 yTrace() << deviceName.c_str() << str;
191 Value val_clearHwFault = config.findGroup(
"GENERAL").find(
"clearHwFaultBeforeCalibration");
192 if(val_clearHwFault.isNull())
194 clearHwFault =
false;
198 if(!val_clearHwFault.isBool())
200 yError() << deviceName.c_str() <<
": clearHwFaultBeforeCalibration bool param is different from accepted values (true / false). Assuming false";
201 clearHwFault =
false;
205 clearHwFault = val_clearHwFault.asBool();
207 yInfo() << deviceName.c_str() <<
": clearHwFaultBeforeCalibration option enabled\n";
212 Value use_raw = config.findGroup(
"GENERAL").find(
"useRawEncoderData");
213 bool useRawEncoderData;
217 useRawEncoderData =
false;
221 if(!use_raw.isBool())
223 yError() << deviceName.c_str() <<
": useRawEncoderData bool param is different from accepted values (true / false). Assuming false";
224 useRawEncoderData =
false;
228 useRawEncoderData = use_raw.asBool();
229 if(useRawEncoderData)
230 yWarning() << deviceName.c_str() <<
": MotionControl is using raw data from encoders! Be careful. \n" <<
231 "\t forcing to skip the calibration";
235 if(useRawEncoderData)
237 skipCalibration =
true;
242 Value checkSkipCalib = config.findGroup(
"GENERAL").find(
"skipCalibration");
243 if(checkSkipCalib.isNull())
245 skipCalibration =
false;
249 if(!checkSkipCalib.isBool())
251 yWarning() << deviceName <<
": skipCalibration bool param is different from accepted values (true / false). Assuming false";
252 skipCalibration =
false;
256 skipCalibration = checkSkipCalib.asBool();
259 yWarning() << deviceName <<
": skipping calibration!! This option was set in general.xml file.";
260 yWarning() << deviceName <<
": BE CAREFUL USING THE ROBOT IN THIS CONFIGURATION! See 'skipCalibration' param in config file";
267 Value checkSkipReCalib = config.findGroup(
"MAINTENANCE").find(
"skipRecalibration");
268 if(checkSkipReCalib.isNull())
270 skipReCalibration =
false;
274 if(!checkSkipReCalib.isBool())
276 yError() << deviceName <<
": skipRecalibration bool param is different from accepted values (true / false). Assuming false";
277 skipReCalibration =
false;
281 skipReCalibration = checkSkipReCalib.asBool();
282 if(skipReCalibration)
284 yWarning() << deviceName <<
": skipping recalibration at each yri restart!! This option was set in MAINTENANCE group in general.xml file.";
285 yWarning() << deviceName <<
": BE CAREFUL USING THE ROBOT IN THIS CONFIGURATION! See 'skipRecalibration' param in config file";
290 if(
p.findGroup(
"GENERAL").check(
"joints"))
292 n_joints =
p.findGroup(
"GENERAL").find(
"joints").asInt32();
294 else if(
p.findGroup(
"GENERAL").check(
"Joints"))
297 n_joints =
p.findGroup(
"GENERAL").find(
"Joints").asInt32();
301 yError() << deviceName.c_str() <<
": missing joints parameter" ;
305 calibParams =
new CalibrationParameters[n_joints];
306 startupMaxPWM =
new int[n_joints];
308 legacyStartupPosition.seq_num = 0;
309 legacyStartupPosition.positions.resize(n_joints);
310 legacyStartupPosition.velocities.resize(n_joints);
311 currPos =
new double[n_joints];
312 currVel =
new double[n_joints];
313 legacyParkingPosition.seq_num = 0;
314 legacyParkingPosition.positions.resize(n_joints);
315 legacyParkingPosition.velocities.resize(n_joints);
318 timeout_goToZero =
new int[n_joints];
319 timeout_calibration =
new int[n_joints];
320 startupPosThreshold =
new double[n_joints];
321 disableHomeAndPark =
new int[n_joints];
322 disableStartupPosCheck =
new int[n_joints];
323 original_max_pwm =
new double[n_joints];
324 limited_max_pwm =
new double[n_joints];
326 for (
int i = 0; i < n_joints; i++) timeout_goToZero[i] = 10;
327 for (
int i = 0; i < n_joints; i++) timeout_calibration[i] = 20;
328 for (
int i = 0; i < n_joints; i++) disableHomeAndPark[i] =
false;
329 for (
int i = 0; i < n_joints; i++) disableStartupPosCheck[i] =
false;
333 Bottle& xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration1");
334 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration1 params " << xtmp.size()<<
" " << n_joints;
return false;}
335 for (i = 1; i < xtmp.size(); i++) calibParams[i-1].param1 = xtmp.get(i).asFloat64();
337 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration2");
338 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration2 params";
return false;}
339 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param2 = xtmp.get(i).asFloat64();
341 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration3");
342 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration3 params";
return false;}
343 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param3 = xtmp.get(i).asFloat64();
345 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration4");
346 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of Calibration4 params";
return false; }
347 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param4 = xtmp.get(i).asFloat64();
349 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration5");
350 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of Calibration5 params";
return false; }
351 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param5 = xtmp.get(i).asFloat64();
353 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationType");
354 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration3 params";
return false;}
355 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].type = (
unsigned char)xtmp.get(i).asFloat64();
357 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationZero");
358 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of calibrationZero params";
return false; }
359 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].paramZero = xtmp.get(i).asFloat64();
361 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationDelta");
362 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of calibrationDelta params";
return false; }
363 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].paramZero += xtmp.get(i).asFloat64();
365 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationTimeout");
366 if (xtmp.size() - 1 != n_joints) { }
367 else {
for (i = 1; i < xtmp.size(); i++) timeout_calibration[i - 1] = (
int)xtmp.get(i).asFloat64(); }
369 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupPosition");
370 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupPosition params";
return false;}
371 for (i = 1; i < xtmp.size(); i++) legacyStartupPosition.positions[i-1] = xtmp.get(i).asFloat64();
373 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupVelocity");
374 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupVelocity params";
return false;}
375 for (i = 1; i < xtmp.size(); i++) legacyStartupPosition.velocities[i - 1] = xtmp.get(i).asFloat64();
378 useLegacyParking = ! parseSequenceGroup(
p,
"PARKING_SEQUENCE", parkingSequence);
380 Bottle homeGroup =
p.findGroup(
"HOME");
383 if( homeGroup.isNull())
385 yError() <<
"Parking position not found. Either <HOME> or <PARKING_SEQUENCE> must be specified in config file";
394 xtmp = homeGroup.findGroup(
"positionHome");
395 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of PositionHome params";
return false;}
396 legacyParkingPosition.positions.resize(n_joints);
397 for (i = 1; i < xtmp.size(); i++)
398 legacyParkingPosition.positions[i-1] = xtmp.get(i).asFloat64();
400 xtmp = homeGroup.findGroup(
"velocityHome");
401 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of VelocityHome params";
return false;}
402 legacyParkingPosition.velocities.resize(n_joints);
403 for (i = 1; i < xtmp.size(); i++)
404 legacyParkingPosition.velocities[i-1] = xtmp.get(i).asFloat64();
408 xtmp = homeGroup.findGroup(
"disableHomeAndPark");
409 if (xtmp.size() - 1 != n_joints) { }
410 else {
for (i = 1; i < xtmp.size(); i++) disableHomeAndPark[i - 1] = xtmp.get(i).asInt32(); }
412 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupMaxPwm");
413 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupMaxPwm params";
return false;}
414 for (i = 1; i < xtmp.size(); i++) startupMaxPWM[i-1] = xtmp.get(i).asInt32();
416 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupPosThreshold");
417 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupPosThreshold params";
return false;}
418 for (i = 1; i < xtmp.size(); i++) startupPosThreshold[i-1] = xtmp.get(i).asFloat64();
420 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupDisablePosCheck");
421 if (xtmp.size() - 1 != n_joints) { }
422 else {
for (i = 1; i < xtmp.size(); i++) disableStartupPosCheck[i - 1] = xtmp.get(i).asInt32(); }
424 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupTimeout");
425 if (xtmp.size() - 1 != n_joints) {}
426 else {
for (i = 1; i < xtmp.size(); i++) timeout_goToZero[i - 1] = xtmp.get(i).asFloat64(); }
428 xtmp =
p.findGroup(
"CALIB_ORDER");
429 int calib_order_size = xtmp.size();
430 if (calib_order_size <= 1) {yError() << deviceName <<
": invalid number CALIB_ORDER params";
return false;}
434 for(
int i=1; i<xtmp.size(); i++)
438 set= xtmp.get(i).asList();
440 for(
int j=0; j<set->size(); j++)
442 tmp.push_back(set->get(j).asInt32() );
444 joints.push_back(tmp);
452 if (calibParams != NULL) {
453 delete[] calibParams;
457 if (startupMaxPWM != NULL) {
458 delete[] startupMaxPWM;
459 startupMaxPWM = NULL;
461 if (original_max_pwm != NULL) {
462 delete[] original_max_pwm;
463 original_max_pwm = NULL;
465 if (limited_max_pwm != NULL) {
466 delete[] limited_max_pwm;
467 limited_max_pwm = NULL;
470 if (timeout_goToZero != NULL) {
471 delete[] timeout_goToZero;
472 timeout_goToZero = NULL;
475 if (timeout_calibration != NULL) {
476 delete[] timeout_calibration;
477 timeout_calibration = NULL;
480 if (currPos != NULL) {
484 if (currVel != NULL) {
489 if (disableHomeAndPark != NULL) {
490 delete[] disableHomeAndPark;
491 disableHomeAndPark = NULL;
494 if (disableStartupPosCheck != NULL) {
495 delete[] disableStartupPosCheck;
496 disableStartupPosCheck = NULL;
502bool parametricCalibratorEth::calibrate(DeviceDriver *device)
504 yInfo() << deviceName <<
": starting calibration";
510 yError() << deviceName <<
": invalid device driver";
514 yarp::dev::PolyDriver *
p =
dynamic_cast<yarp::dev::PolyDriver *
>(device);
522 p->view(iControlMode);
531 yWarning() << deviceName <<
": using parametricCalibrator on an old iCubInterface system. Upgrade to robotInterface is recommended.";
532 device->view(iCalibrate);
533 device->view(iEncoders);
534 device->view(iPosition);
536 device->view(iControlMode);
540 if (!(iCalibrate && iEncoders && iPosition && iPids && iControlMode)) {
541 yError() << deviceName <<
": interface not found" << iCalibrate << iPosition << iPids << iControlMode;
502bool parametricCalibratorEth::calibrate(DeviceDriver *device) {
…}
548bool parametricCalibratorEth::calibrate()
550 int setOfJoint_idx = 0;
551 totJointsToCalibrate = 0;
554 if (dev2calibrate==0)
556 yError() << deviceName <<
": not able to find a valid device to calibrate";
560 int n_joints_board{0};
561 if ( !iEncoders->getAxes(&n_joints_board))
563 yError() << deviceName <<
": error getting number of axes" ;
566 if(n_joints_board != n_joints)
568 yError() <<
"ParametricCalibratorEth: " << deviceName <<
": number of joints of device to calibrate (" << n_joints_board << \
569 ") does not match the number of joints in calibrator config file ("<< n_joints <<
")";
573 std::list<int> currentSetList;
574 std::list<std::list<int> >::iterator Bit=joints.begin();
575 std::list<std::list<int> >::iterator Bend=joints.end();
580 currentSetList.clear();
581 currentSetList = (*Bit);
582 std::list<int>::iterator lit = currentSetList.begin();
583 std::list<int>::iterator lend = currentSetList.end();
584 totJointsToCalibrate += currentSetList.size();
588 calibJoints.push_back(*lit);
589 calibJointsString.addInt32(*lit);
595 yDebug() << deviceName <<
": Joints calibration order:" << calibJointsString.toString();
597 if (totJointsToCalibrate > n_joints)
599 yError() << deviceName <<
": too much axis to calibrate for this part..." << totJointsToCalibrate <<
" bigger than " << n_joints;
607 if (totJointsToCalibrate < n_joints)
609 yWarning() << deviceName <<
" is calibrating only a subset of the robot part. Calibrating " << totJointsToCalibrate <<
" over a total of " << n_joints;
614 yWarning() << deviceName <<
": skipCalibration flag is on! Setting safe pid but skipping calibration.";
617 std::list<int>::iterator lit;
618 while( (Bit != Bend) && (!abortCalib) )
622 currentSetList.clear();
623 currentSetList = (*Bit);
626 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
628 if ( ((*lit) <0) || ((*lit) >= n_joints) )
630 yError() << deviceName <<
": asked to calibrate joint" << (*lit) <<
", which is negative OR bigger than the number of axes for this part ("<< n_joints <<
")";
635 if(!iAmp->getPWMLimit((*lit), &original_max_pwm[(*lit)]) )
637 yError() << deviceName <<
": getPid joint " << (*lit) <<
"failed... aborting calibration";
642 limited_max_pwm[(*lit)] = original_max_pwm[(*lit)];
644 if (startupMaxPWM[(*lit)]==0)
646 yDebug() << deviceName <<
": skipping startupMaxPWM=0 of joint " << (*lit);
647 iAmp->setPWMLimit((*lit),original_max_pwm[(*lit)]);
651 if (startupMaxPWM[(*lit)]<limited_max_pwm[(*lit)])
653 limited_max_pwm[(*lit)]=startupMaxPWM[(*lit)];
654 iAmp->setPWMLimit((*lit), limited_max_pwm[(*lit)]);
658 yDebug() << deviceName <<
": joint " << (*lit) <<
" has max_output already limited to a safe value: " << limited_max_pwm[(*lit)];
677 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
681 calibrateJoint((*lit));
686 for(lit = currentSetList.begin(); lit != currentSetList.end(); lit++)
688 iEncoders->getEncoder((*lit), &currPos[(*lit)]);
689 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
"j" << (*lit) <<
": Calibrating... enc values just before starting low-level calibration: " << currPos[(*lit)];
699 std::list<int> failedJoints = {};
700 if(checkCalibrateJointEnded(*Bit, failedJoints ))
702 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
": Calibration ended, going to zero!";
706 yError() << deviceName <<
": set" << setOfJoint_idx <<
": Detected errors during calibration! Idling failed joints and set on those safe PWM limits";
707 for (lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
709 auto it = std::find_if(failedJoints.begin(), failedJoints.end(),
710 [lit](
int id) { return id == *lit; });
712 if (it != failedJoints.end())
714 yError() << deviceName <<
": joint # " << *lit <<
" failed the calibration. Idling it and keeping safe PWM limits";
716 iControlMode->setControlMode((*it),VOCAB_CM_IDLE);
731 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
734 goToStartupPosition((*lit));
746 bool goneToZero =
true;
747 failedJoints.clear();
749 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
751 goneToZero &= checkGoneToZeroThreshold(*lit, failedJoints);
762 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
": Reached zero position!";
763 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
765 iAmp->setPWMLimit((*lit),original_max_pwm[(*lit)]);
770 yError() << deviceName <<
": set" << setOfJoint_idx <<
": some axis got timeout while reaching zero position. Idling failed joints and set on those safe PWM limits";
772 for (lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
774 auto it = std::find_if(failedJoints.begin(), failedJoints.end(),
775 [lit](
int id) { return id == *lit; });
777 if (it != failedJoints.end())
779 yError() << deviceName <<
": joint # " << *lit <<
" failed reaching zero position. Idling it and keeping safe PWM limits";
780 iControlMode->setControlMode((*it),VOCAB_CM_IDLE);
784 yDebug() << deviceName <<
": joint # " << *lit <<
" reached zero position. Setting original max PWM limits";
785 iAmp->setPWMLimit((*it),original_max_pwm[(*it)]);
796 yError() << deviceName <<
": calibration has been aborted!I'm going to disable all joints..." ;
797 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
799 iControlMode->setControlMode(*lit, VOCAB_CM_IDLE);
807bool parametricCalibratorEth::calibrateJoint(
int j)
809 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
811 yError(
"%s cannot perform 'calibration' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
814 yDebug() << deviceName <<
": Calling calibrateJoint on joint " << j <<
": type "<< calibParams[j].type <<
" with params: " << calibParams[j].param1 << calibParams[j].param2 << calibParams[j].param3 << calibParams[j].param4 << calibParams[j].param5;
815 bool b = iCalibrate->setCalibrationParameters(j, calibParams[j]);
819bool parametricCalibratorEth::checkCalibrateJointEnded(std::list<int> set, std::list<int> &failedJoints)
821 bool calibration_ok =
true;
824 std::list<int>::iterator lit;
825 std::list<int>::iterator lend;
826 failedJoints.clear();
835 yWarning() << deviceName <<
": calibration aborted\n";
838 if (iCalibrate->calibrationDone(*lit))
840 yDebug() << deviceName <<
": calib joint " << (*lit) <<
"ended";
846 if (timeout > timeout_calibration[*lit])
848 yError() << deviceName <<
": Timeout while calibrating joint" << (*lit);
849 failedJoints.push_back(*lit);
850 calibration_ok =
false;
855 yarp::os::Time::delay(1.0);
860 return calibration_ok;
863bool parametricCalibratorEth::checkHwFault()
865 for(
auto j : calibJoints)
868 iControlMode->getControlMode(j,&mode);
869 if (mode == VOCAB_CM_HW_FAULT)
873 iControlMode->setControlMode(j,VOCAB_CM_FORCE_IDLE);
874 yWarning() << deviceName <<
": detected an hardware fault on joint " << j <<
". An attempt will be made to clear it.";
876 iControlMode->getControlMode(j,&mode);
877 if (mode == VOCAB_CM_HW_FAULT)
879 yError() << deviceName <<
": unable to clear the hardware fault detected on joint " << j <<
" before starting the calibration procedure!";
882 else if (mode == VOCAB_CM_IDLE)
884 yWarning() << deviceName <<
": hardware fault on joint " << j <<
" successfully cleared.";
889 yError() << deviceName <<
": an unknown error occured while trying the hardware fault on joint " << j ;
895 yError() << deviceName <<
": detected an hardware fault on joint " << j <<
" before starting the calibration procedure!";
904bool parametricCalibratorEth::goToStartupPosition(
int j)
906 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
908 yError(
"%s cannot perform 'go to zero' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
914 if (disableStartupPosCheck[j])
916 yWarning() << deviceName <<
": goToZero, joint " << j <<
" is disabled on user request";
920 if (abortCalib)
return true;
921 iControlMode->getControlMode(j, &mode);
923 if((mode == VOCAB_CM_IDLE) && (skipReCalibration))
925 yWarning() << deviceName <<
": goToZero, joint " << j <<
" is idle and skipRecalibration is requested, skipping!";
929 yDebug() << deviceName <<
": Sending positionMove to joint" << j <<
" (desired pos: " << legacyStartupPosition.positions[j] << \
930 "desired speed: " << legacyStartupPosition.velocities[j] <<
" )";
931 ret = iPosition->setRefSpeed(j, legacyStartupPosition.velocities[j]);
932 ret &= iPosition->positionMove(j, legacyStartupPosition.positions[j]);
936bool parametricCalibratorEth::checkGoneToZeroThreshold(
int j, std::list<int> &failedJoints)
938 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
940 yError(
"%s cannot perform 'check gone to zero' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
944 if (disableStartupPosCheck[j])
946 yWarning() << deviceName <<
": checkGoneToZeroThreshold, joint " << j <<
" is disabled on user request";
951 yWarning() << deviceName <<
": checkGoneToZeroThreshold, joint " << j <<
" is set with safe PWM limits on user request (skipCalibration flag is on)";
952 failedJoints.push_back(j);
957 bool finished =
false;
965 double start_time = yarp::os::Time::now();
966 while ( (!finished) && (!abortCalib))
968 iEncoders->getEncoder(j, &angj);
969 iPosition->checkMotionDone(j, &
done);
970 iControlMode->getControlMode(j, &mode);
971 iPids->getPidOutput(VOCAB_PIDTYPE_POSITION,j, &output);
973 if((skipReCalibration) && (mode == VOCAB_CM_IDLE))
975 yDebug() << deviceName <<
": checkGoneToZeroThreshold, joint " << j <<
" is IDLE and skipRecalibration is requested, return completed!";
979 delta = fabs(angj-legacyStartupPosition.positions[j]);
980 yDebug(
"%s: checkGoneToZeroThreshold: joint: %d curr: %.3f des: %.3f -> delta: %.3f threshold: %.3f output: %.3f mode: %s" , \
981 deviceName.c_str(), j, angj, legacyStartupPosition.positions[j], delta, startupPosThreshold[j], output, yarp::os::Vocab32::decode(mode).c_str());
983 if (delta < startupPosThreshold[j] &&
done)
985 yDebug(
"%s: checkGoneToZeroThreshold: joint: %d completed with delta: %.3f over: %.3f" ,deviceName.c_str(),j,delta, startupPosThreshold[j]);
989 if (yarp::os::Time::now() - start_time > timeout_goToZero[j])
991 yError() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" Timeout while going to zero!";
994 if (mode == VOCAB_CM_IDLE)
996 yError() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" is idle, skipping!";
999 if (mode == VOCAB_CM_HW_FAULT)
1001 yError() << deviceName <<
": checkGoneToZeroThreshold: hardware fault on joint " << j <<
", skipping!";
1006 yWarning() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" Aborting wait while going to zero!\n";
1014 failedJoints.push_back(j);
1025 std::list<int>::iterator joint;
1028 if (useLegacyParking)
1030 bool allJointsCanParkSimultaneously =
true;
1031 for (
int i = 0; i < n_joints; i++)
1033 if (disableHomeAndPark[i]) allJointsCanParkSimultaneously =
false;
1036 if(allJointsCanParkSimultaneously ==
false)
1038 yWarning() << deviceName <<
"Joints will be parked separately, since some of them have the disableHomeAndPark flag set";
1040 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1051 yWarning() << deviceName <<
": Calling park without calibration... skipping";
1057 yWarning() << deviceName <<
": skipCalibration flag is on!! Faking park!!";
1061 int * currentControlModes =
new int[n_joints];
1062 std::vector<bool> cannotPark(n_joints);
1063 bool res = iControlMode->getControlModes(currentControlModes);
1066 yError() << deviceName <<
": error getting control mode during parking";
1069 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1071 switch(currentControlModes[(*joint)])
1075 yError() << deviceName <<
": joint " << (*joint) <<
" is idle, skipping park";
1076 cannotPark[(*joint)] =
true;
1080 case VOCAB_CM_HW_FAULT:
1082 yError() << deviceName <<
": joint " << (*joint) <<
" has an hardware fault, skipping park";
1083 cannotPark[(*joint)] =
true;
1087 case VOCAB_CM_NOT_CONFIGURED:
1089 yError() << deviceName <<
": joint " << (*joint) <<
" is not configured, skipping park";
1090 cannotPark[(*joint)] =
true;
1094 case VOCAB_CM_UNKNOWN:
1096 yError() << deviceName <<
": joint " << (*joint) <<
" is in unknown state, skipping park";
1097 cannotPark[(*joint)] =
true;
1102 iControlMode->setControlMode((*joint), VOCAB_CM_POSITION);
1103 cannotPark[(*joint)] =
false;
1108 bool parkSequenceDone{
false};
1109 if(useLegacyParking)
1111 moveAndCheck_legacy(legacyParkingPosition, cannotPark, wait);
1113 parkSequenceDone =
true;
1119 bool stepDone =
true;
1120 if(parkingSequence.size() > 0)
1122 stepDone = moveAndCheck(parkingSequence.at(currentParkingSeq_step));
1126 yDebug() <<
"ParametricCalibratorEth: park sequence step num " << currentParkingSeq_step <<
" ended with " << \
1127 (abortParking ?
"failure" :
"success");
1130 abortParking =
true;
1132 currentParkingSeq_step++;
1135 if( (currentParkingSeq_step >= parkingSequence.size()) || stepDone ==
false)
1136 parkSequenceDone =
true;
1140 if(parkSequenceDone)
1142 yDebug() << deviceName.c_str() <<
": Park " << (abortParking ?
"aborted" :
"completed");
1143 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1145 switch(currentControlModes[(*joint)])
1148 case VOCAB_CM_HW_FAULT:
1149 case VOCAB_CM_NOT_CONFIGURED:
1150 case VOCAB_CM_UNKNOWN:
1155 iControlMode->setControlMode((*joint), VOCAB_CM_IDLE);
1163bool parametricCalibratorEth::moveAndCheck(PositionSequence &
data)
1165 iPosition->setRefSpeeds(
data.velocities.data());
1166 iPosition->positionMove(
data.positions.data());
1174 iPosition->checkMotionDone(&
done);
1180 yError() <<
"ParametricCalibratorEth: parking " << deviceName <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1186bool parametricCalibratorEth::moveAndCheck_legacy(PositionSequence &
data, std::vector<bool> &cannotPark,
bool wait)
1190 for(
auto joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1192 if (cannotPark[(*joint)] ==
false)
1194 iPosition->setRefSpeed((*joint),
data.velocities[(*joint)]);
1195 iPosition->positionMove((*joint),
data.positions[(*joint)]);
1202 for(
auto joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1205 if (cannotPark[(*joint)] ==
false)
1207 yDebug() << deviceName.c_str() <<
": Moving to park position, joint:" << (*joint);
1209 iPosition->checkMotionDone((*joint), &
done);
1214 iPosition->checkMotionDone((*joint), &
done);
1218 yError() << deviceName <<
": joint " << (*joint) <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1228 yDebug() << deviceName.c_str() <<
": Quitting calibrate\n";
1235 yDebug() << deviceName.c_str() <<
": Quitting parking\n";
1247 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1249 yError(
"%s cannot perform 'calibration' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1253 return calibrateJoint(j);
1264 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1266 yError(
"%s cannot perform 'homing' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1270 if (disableHomeAndPark[j])
1272 yWarning() << deviceName <<
": homingSingleJoint, joint " << j <<
" is disabled on user request";
1275 return goToStartupPosition(j);
1282 std::list<int>::iterator lit;
1283 for(lit = calibJoints.begin(); lit != calibJoints.end() && !abortCalib; lit++)
1293 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1295 yError(
"%s cannot perform 'park' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1299 if(useLegacyParking)
1301 if (disableHomeAndPark[j])
1303 yWarning() << deviceName <<
": parkSingleJoint, joint " << j <<
" is disabled on user request";
1312 yWarning() << deviceName <<
": Calling park without calibration... skipping";
1318 yWarning() << deviceName <<
": skipCalibration flag is on!! Faking park!!";
1322 int currentControlMode;
1324 bool res = iControlMode->getControlMode(j, ¤tControlMode);
1327 yError() << deviceName <<
": error getting control mode during parking";
1330 if(currentControlMode != VOCAB_CM_IDLE &&
1331 currentControlMode != VOCAB_CM_HW_FAULT)
1333 iControlMode->setControlMode(j, VOCAB_CM_POSITION);
1336 else if (currentControlMode == VOCAB_CM_IDLE)
1338 yError() << deviceName <<
": joint " << j <<
" is idle, skipping park";
1341 else if (currentControlMode == VOCAB_CM_HW_FAULT)
1343 yError() << deviceName <<
": joint " << j <<
" has an hardware fault, skipping park";
1347 if(useLegacyParking)
1349 iPosition->setRefSpeed (j, legacyStartupPosition.velocities[j]);
1350 iPosition->positionMove(j, legacyStartupPosition.positions[j]);
1355 iPosition->setRefSpeed (j, parkingSequence.rbegin()->velocities[j]);
1356 iPosition->positionMove(j, parkingSequence.rbegin()->positions[j]);
1361 if (cannotPark ==
false)
1364 yDebug() << deviceName.c_str() <<
": Moving to park position, joint:" << j;
1366 iPosition->checkMotionDone(j, &
done);
1371 iPosition->checkMotionDone(j, &
done);
1375 yError() << deviceName <<
": joint " << j <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1380 yDebug() << deviceName.c_str() <<
": Park " << (abortParking ?
"aborted" :
"completed");
1381 iControlMode->setControlMode(j,VOCAB_CM_IDLE);
1392 yError() <<
"Device is not calibrated therefore cannot be parked";
1396 return park(dev2calibrate);
virtual bool park(DeviceDriver *dd, bool wait=true) override
virtual bool open(yarp::os::Searchable &config) override
Open the device driver.
virtual bool homingSingleJoint(int j) override
virtual bool parkWholePart() override
virtual bool calibrateSingleJoint(int j) override
virtual bool parkSingleJoint(int j, bool _wait=true) override
virtual bool quitPark() override
virtual bool close() override
Close the device driver.
~parametricCalibratorEth()
Destructor.
virtual bool calibrateWholePart() override
parametricCalibratorEth()
Default constructor.
virtual yarp::dev::IRemoteCalibrator * getCalibratorDevice() override
virtual bool quitCalibrate() override
bool calibrate(DeviceDriver *device) override
Calibrate method.
virtual bool homingWholePart() override
const double GO_TO_ZERO_TIMEOUT
const int CALIBRATE_JOINT_TIMEOUT
static bool extractGroup(Bottle &input, Bottle &out, const std::string &key1, const std::string &txt, int size)
static bool extractGroup(Bottle &input, Bottle &out, const std::string &key1, const std::string &txt, int size)