11 #include <yarp/os/Time.h>
12 #include <yarp/dev/PolyDriver.h>
18 #include <yarp/os/LogStream.h>
20 using namespace yarp::os;
28 static 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.";
50 bool 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());
130 parametricCalibratorEth::parametricCalibratorEth() :
131 calibParams(nullptr),
132 original_max_pwm(nullptr),
133 limited_max_pwm(nullptr),
134 startupMaxPWM(nullptr),
138 startupPosThreshold(0),
141 skipCalibration(false),
144 timeout_goToZero(nullptr),
145 timeout_calibration(nullptr),
146 disableHomeAndPark(nullptr),
147 disableStartupPosCheck(nullptr),
148 totJointsToCalibrate(0),
149 useLegacyParking(true),
150 currentParkingSeq_step(0)
164 p.fromString(config.toString());
166 if (
p.check(
"GENERAL")==
false)
168 yError() <<
"Parametric calibrator: missing [GENERAL] section";
172 if(
p.findGroup(
"GENERAL").check(
"deviceName"))
174 deviceName =
p.findGroup(
"GENERAL").find(
"deviceName").asString();
178 yError() <<
"Parametric calibrator: missing deviceName parameter";
183 if(config.findGroup(
"GENERAL").find(
"verbose").asInt32())
185 str=config.toString().c_str();
186 yTrace() << deviceName.c_str() << str;
190 Value val_clearHwFault = config.findGroup(
"GENERAL").find(
"clearHwFaultBeforeCalibration");
191 if(val_clearHwFault.isNull())
193 clearHwFault =
false;
197 if(!val_clearHwFault.isBool())
199 yError() << deviceName.c_str() <<
": clearHwFaultBeforeCalibration bool param is different from accepted values (true / false). Assuming false";
200 clearHwFault =
false;
204 clearHwFault = val_clearHwFault.asBool();
206 yInfo() << deviceName.c_str() <<
": clearHwFaultBeforeCalibration option enabled\n";
211 Value use_raw = config.findGroup(
"GENERAL").find(
"useRawEncoderData");
212 bool useRawEncoderData;
216 useRawEncoderData =
false;
220 if(!use_raw.isBool())
222 yError() << deviceName.c_str() <<
": useRawEncoderData bool param is different from accepted values (true / false). Assuming false";
223 useRawEncoderData =
false;
227 useRawEncoderData = use_raw.asBool();
228 if(useRawEncoderData)
229 yWarning() << deviceName.c_str() <<
": MotionControl is using raw data from encoders! Be careful. \n" <<
230 "\t forcing to skip the calibration";
236 if(useRawEncoderData)
238 skipCalibration =
true;
243 Value checkSkipCalib = config.findGroup(
"GENERAL").find(
"skipCalibration");
244 if(checkSkipCalib.isNull())
246 skipCalibration =
false;
250 if(!checkSkipCalib.isBool())
252 yWarning() << deviceName <<
": skipCalibration bool param is different from accepted values (true / false). Assuming false";
253 skipCalibration =
false;
257 skipCalibration = checkSkipCalib.asBool();
260 yWarning() << deviceName <<
": skipping calibration!! This option was set in general.xml file.";
261 yWarning() << deviceName <<
": BE CAREFUL USING THE ROBOT IN THIS CONFIGURATION! See 'skipCalibration' param in config file";
267 if(
p.findGroup(
"GENERAL").check(
"joints"))
269 n_joints =
p.findGroup(
"GENERAL").find(
"joints").asInt32();
271 else if(
p.findGroup(
"GENERAL").check(
"Joints"))
274 n_joints =
p.findGroup(
"GENERAL").find(
"Joints").asInt32();
278 yError() << deviceName.c_str() <<
": missing joints parameter" ;
282 calibParams =
new CalibrationParameters[n_joints];
283 startupMaxPWM =
new int[n_joints];
285 legacyStartupPosition.seq_num = 0;
286 legacyStartupPosition.positions.resize(n_joints);
287 legacyStartupPosition.velocities.resize(n_joints);
288 currPos =
new double[n_joints];
289 currVel =
new double[n_joints];
290 legacyParkingPosition.seq_num = 0;
291 legacyParkingPosition.positions.resize(n_joints);
292 legacyParkingPosition.velocities.resize(n_joints);
295 timeout_goToZero =
new int[n_joints];
296 timeout_calibration =
new int[n_joints];
297 startupPosThreshold =
new double[n_joints];
298 disableHomeAndPark =
new int[n_joints];
299 disableStartupPosCheck =
new int[n_joints];
300 original_max_pwm =
new double[n_joints];
301 limited_max_pwm =
new double[n_joints];
303 for (
int i = 0; i < n_joints; i++) timeout_goToZero[i] = 10;
304 for (
int i = 0; i < n_joints; i++) timeout_calibration[i] = 20;
305 for (
int i = 0; i < n_joints; i++) disableHomeAndPark[i] =
false;
306 for (
int i = 0; i < n_joints; i++) disableStartupPosCheck[i] =
false;
310 Bottle& xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration1");
311 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration1 params " << xtmp.size()<<
" " << n_joints;
return false;}
312 for (i = 1; i < xtmp.size(); i++) calibParams[i-1].param1 = xtmp.get(i).asFloat64();
314 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration2");
315 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration2 params";
return false;}
316 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param2 = xtmp.get(i).asFloat64();
318 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration3");
319 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration3 params";
return false;}
320 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param3 = xtmp.get(i).asFloat64();
322 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration4");
323 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of Calibration4 params";
return false; }
324 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param4 = xtmp.get(i).asFloat64();
326 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibration5");
327 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of Calibration5 params";
return false; }
328 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].param5 = xtmp.get(i).asFloat64();
330 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationType");
331 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of Calibration3 params";
return false;}
332 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].type = (
unsigned char)xtmp.get(i).asFloat64();
334 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationZero");
335 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of calibrationZero params";
return false; }
336 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].paramZero = xtmp.get(i).asFloat64();
338 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationDelta");
339 if (xtmp.size() - 1 != n_joints) { yError() << deviceName <<
": invalid number of calibrationDelta params";
return false; }
340 for (i = 1; i < xtmp.size(); i++) calibParams[i - 1].paramZero += xtmp.get(i).asFloat64();
342 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"calibrationTimeout");
343 if (xtmp.size() - 1 != n_joints) { }
344 else {
for (i = 1; i < xtmp.size(); i++) timeout_calibration[i - 1] = (
int)xtmp.get(i).asFloat64(); }
346 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupPosition");
347 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupPosition params";
return false;}
348 for (i = 1; i < xtmp.size(); i++) legacyStartupPosition.positions[i-1] = xtmp.get(i).asFloat64();
350 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupVelocity");
351 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupVelocity params";
return false;}
352 for (i = 1; i < xtmp.size(); i++) legacyStartupPosition.velocities[i - 1] = xtmp.get(i).asFloat64();
355 useLegacyParking = ! parseSequenceGroup(
p,
"PARKING_SEQUENCE", parkingSequence);
357 Bottle homeGroup =
p.findGroup(
"HOME");
360 if( homeGroup.isNull())
362 yError() <<
"Parking position not found. Either <HOME> or <PARKING_SEQUENCE> must be specified in config file";
371 xtmp = homeGroup.findGroup(
"positionHome");
372 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of PositionHome params";
return false;}
373 legacyParkingPosition.positions.resize(n_joints);
374 for (i = 1; i < xtmp.size(); i++)
375 legacyParkingPosition.positions[i-1] = xtmp.get(i).asFloat64();
377 xtmp = homeGroup.findGroup(
"velocityHome");
378 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of VelocityHome params";
return false;}
379 legacyParkingPosition.velocities.resize(n_joints);
380 for (i = 1; i < xtmp.size(); i++)
381 legacyParkingPosition.velocities[i-1] = xtmp.get(i).asFloat64();
385 xtmp = homeGroup.findGroup(
"disableHomeAndPark");
386 if (xtmp.size() - 1 != n_joints) { }
387 else {
for (i = 1; i < xtmp.size(); i++) disableHomeAndPark[i - 1] = xtmp.get(i).asInt32(); }
389 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupMaxPwm");
390 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupMaxPwm params";
return false;}
391 for (i = 1; i < xtmp.size(); i++) startupMaxPWM[i-1] = xtmp.get(i).asInt32();
393 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupPosThreshold");
394 if (xtmp.size()-1!=n_joints) {yError() << deviceName <<
": invalid number of startupPosThreshold params";
return false;}
395 for (i = 1; i < xtmp.size(); i++) startupPosThreshold[i-1] = xtmp.get(i).asFloat64();
397 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupDisablePosCheck");
398 if (xtmp.size() - 1 != n_joints) { }
399 else {
for (i = 1; i < xtmp.size(); i++) disableStartupPosCheck[i - 1] = xtmp.get(i).asInt32(); }
401 xtmp =
p.findGroup(
"CALIBRATION").findGroup(
"startupTimeout");
402 if (xtmp.size() - 1 != n_joints) {}
403 else {
for (i = 1; i < xtmp.size(); i++) timeout_goToZero[i - 1] = xtmp.get(i).asFloat64(); }
405 xtmp =
p.findGroup(
"CALIB_ORDER");
406 int calib_order_size = xtmp.size();
407 if (calib_order_size <= 1) {yError() << deviceName <<
": invalid number CALIB_ORDER params";
return false;}
411 for(
int i=1; i<xtmp.size(); i++)
415 set= xtmp.get(i).asList();
417 for(
int j=0; j<set->size(); j++)
419 tmp.push_back(set->get(j).asInt32() );
421 joints.push_back(
tmp);
429 if (calibParams != NULL) {
430 delete[] calibParams;
434 if (startupMaxPWM != NULL) {
435 delete[] startupMaxPWM;
436 startupMaxPWM = NULL;
438 if (original_max_pwm != NULL) {
439 delete[] original_max_pwm;
440 original_max_pwm = NULL;
442 if (limited_max_pwm != NULL) {
443 delete[] limited_max_pwm;
444 limited_max_pwm = NULL;
447 if (timeout_goToZero != NULL) {
448 delete[] timeout_goToZero;
449 timeout_goToZero = NULL;
452 if (timeout_calibration != NULL) {
453 delete[] timeout_calibration;
454 timeout_calibration = NULL;
457 if (currPos != NULL) {
461 if (currVel != NULL) {
466 if (disableHomeAndPark != NULL) {
467 delete[] disableHomeAndPark;
468 disableHomeAndPark = NULL;
471 if (disableStartupPosCheck != NULL) {
472 delete[] disableStartupPosCheck;
473 disableStartupPosCheck = NULL;
479 bool parametricCalibratorEth::calibrate(DeviceDriver *device)
481 yInfo() << deviceName <<
": starting calibration";
487 yError() << deviceName <<
": invalid device driver";
491 yarp::dev::PolyDriver *
p =
dynamic_cast<yarp::dev::PolyDriver *
>(device);
499 p->view(iControlMode);
508 yWarning() << deviceName <<
": using parametricCalibrator on an old iCubInterface system. Upgrade to robotInterface is recommended.";
509 device->view(iCalibrate);
510 device->view(iEncoders);
511 device->view(iPosition);
513 device->view(iControlMode);
517 if (!(iCalibrate && iEncoders && iPosition && iPids && iControlMode)) {
518 yError() << deviceName <<
": interface not found" << iCalibrate << iPosition << iPids << iControlMode;
525 bool parametricCalibratorEth::calibrate()
527 int setOfJoint_idx = 0;
528 totJointsToCalibrate = 0;
531 if (dev2calibrate==0)
533 yError() << deviceName <<
": not able to find a valid device to calibrate";
537 int n_joints_board{0};
538 if ( !iEncoders->getAxes(&n_joints_board))
540 yError() << deviceName <<
": error getting number of axes" ;
543 if(n_joints_board != n_joints)
545 yError() <<
"ParametricCalibratorEth: " << deviceName <<
": number of joints of device to calibrate (" << n_joints_board << \
546 ") does not match the number of joints in calibrator config file ("<< n_joints <<
")";
550 std::list<int> currentSetList;
551 std::list<std::list<int> >::iterator Bit=joints.begin();
552 std::list<std::list<int> >::iterator Bend=joints.end();
557 currentSetList.clear();
558 currentSetList = (*Bit);
559 std::list<int>::iterator lit = currentSetList.begin();
560 std::list<int>::iterator lend = currentSetList.end();
561 totJointsToCalibrate += currentSetList.size();
565 calibJoints.push_back(*lit);
566 calibJointsString.addInt32(*lit);
572 yDebug() << deviceName <<
": Joints calibration order:" << calibJointsString.toString();
574 if (totJointsToCalibrate > n_joints)
576 yError() << deviceName <<
": too much axis to calibrate for this part..." << totJointsToCalibrate <<
" bigger than " << n_joints;
584 if (totJointsToCalibrate < n_joints)
586 yWarning() << deviceName <<
" is calibrating only a subset of the robot part. Calibrating " << totJointsToCalibrate <<
" over a total of " << n_joints;
591 yWarning() << deviceName <<
": skipCalibration flag is on! Setting safe pid but skipping calibration.";
594 std::list<int>::iterator lit;
595 while( (Bit != Bend) && (!abortCalib) )
599 currentSetList.clear();
600 currentSetList = (*Bit);
603 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
605 if ( ((*lit) <0) || ((*lit) >= n_joints) )
607 yError() << deviceName <<
": asked to calibrate joint" << (*lit) <<
", which is negative OR bigger than the number of axes for this part ("<< n_joints <<
")";
612 if(!iAmp->getPWMLimit((*lit), &original_max_pwm[(*lit)]) )
614 yError() << deviceName <<
": getPid joint " << (*lit) <<
"failed... aborting calibration";
619 limited_max_pwm[(*lit)] = original_max_pwm[(*lit)];
621 if (startupMaxPWM[(*lit)]==0)
623 yDebug() << deviceName <<
": skipping startupMaxPWM=0 of joint " << (*lit);
624 iAmp->setPWMLimit((*lit),original_max_pwm[(*lit)]);
628 if (startupMaxPWM[(*lit)]<limited_max_pwm[(*lit)])
630 limited_max_pwm[(*lit)]=startupMaxPWM[(*lit)];
631 iAmp->setPWMLimit((*lit), limited_max_pwm[(*lit)]);
635 yDebug() << deviceName <<
": joint " << (*lit) <<
" has max_output already limited to a safe value: " << limited_max_pwm[(*lit)];
669 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
673 calibrateJoint((*lit));
678 for(lit = currentSetList.begin(); lit != currentSetList.end(); lit++)
680 iEncoders->getEncoder((*lit), &currPos[(*lit)]);
681 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
"j" << (*lit) <<
": Calibrating... enc values AFTER calib: " << currPos[(*lit)];
691 if(checkCalibrateJointEnded((*Bit)) )
693 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
": Calibration ended, going to zero!\n";
697 yError() << deviceName <<
": set" << setOfJoint_idx <<
": Calibration went wrong! Disabling axes and keeping safe pid limit\n";
699 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
701 iControlMode->setControlMode((*lit),VOCAB_CM_IDLE);
728 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
731 goToStartupPosition((*lit));
742 bool goneToZero =
true;
743 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
745 goneToZero &= checkGoneToZeroThreshold(*lit);
756 yDebug() << deviceName <<
": set" << setOfJoint_idx <<
": Reached zero position!\n";
757 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
759 iAmp->setPWMLimit((*lit),original_max_pwm[(*lit)]);
764 yError() << deviceName <<
": set" << setOfJoint_idx <<
": some axis got timeout while reaching zero position... disabling this set of axes\n";
765 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
767 iControlMode->setControlMode((*lit),VOCAB_CM_IDLE);
777 yError() << deviceName <<
": calibration has been aborted!I'm going to disable all joints..." ;
778 for(lit = currentSetList.begin(); lit != currentSetList.end() && !abortCalib; lit++)
780 iControlMode->setControlMode(*lit, VOCAB_CM_IDLE);
788 bool parametricCalibratorEth::calibrateJoint(
int j)
790 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
792 yError(
"%s cannot perform 'calibration' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
795 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;
796 bool b = iCalibrate->setCalibrationParameters(j, calibParams[j]);
800 bool parametricCalibratorEth::checkCalibrateJointEnded(std::list<int> set)
802 bool calibration_ok =
true;
805 std::list<int>::iterator lit;
806 std::list<int>::iterator lend;
815 yWarning() << deviceName <<
": calibration aborted\n";
818 if (iCalibrate->calibrationDone(*lit))
820 yDebug() << deviceName <<
": calib joint " << (*lit) <<
"ended";
826 if (timeout > timeout_calibration[*lit])
828 yError() << deviceName <<
": Timeout while calibrating joint" << (*lit);
829 calibration_ok =
false;
834 yarp::os::Time::delay(1.0);
839 return calibration_ok;
842 bool parametricCalibratorEth::checkHwFault()
844 for(
auto j : calibJoints)
847 iControlMode->getControlMode(j,&mode);
848 if (mode == VOCAB_CM_HW_FAULT)
852 iControlMode->setControlMode(j,VOCAB_CM_FORCE_IDLE);
853 yWarning() << deviceName <<
": detected an hardware fault on joint " << j <<
". An attempt will be made to clear it.";
855 iControlMode->getControlMode(j,&mode);
856 if (mode == VOCAB_CM_HW_FAULT)
858 yError() << deviceName <<
": unable to clear the hardware fault detected on joint " << j <<
" before starting the calibration procedure!";
861 else if (mode == VOCAB_CM_IDLE)
863 yWarning() << deviceName <<
": hardware fault on joint " << j <<
" successfully cleared.";
868 yError() << deviceName <<
": an unknown error occured while trying the hardware fault on joint " << j ;
874 yError() << deviceName <<
": detected an hardware fault on joint " << j <<
" before starting the calibration procedure!";
883 bool parametricCalibratorEth::goToStartupPosition(
int j)
885 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
887 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());
892 if (disableStartupPosCheck[j])
894 yWarning() << deviceName <<
": goToZero, joint " << j <<
" is disabled on user request";
898 if (abortCalib)
return true;
899 yDebug() << deviceName <<
": Sending positionMove to joint" << j <<
" (desired pos: " << legacyStartupPosition.positions[j] << \
900 "desired speed: " << legacyStartupPosition.velocities[j] <<
" )";
901 ret = iPosition->setRefSpeed(j, legacyStartupPosition.velocities[j]);
902 ret &= iPosition->positionMove(j, legacyStartupPosition.positions[j]);
906 bool parametricCalibratorEth::checkGoneToZeroThreshold(
int j)
908 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
910 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());
914 if (disableStartupPosCheck[j])
916 yWarning() << deviceName <<
": checkGoneToZeroThreshold, joint " << j <<
" is disabled on user request";
919 if (skipCalibration)
return false;
922 bool finished =
false;
930 double start_time = yarp::os::Time::now();
931 while ( (!finished) && (!abortCalib))
933 iEncoders->getEncoder(j, &angj);
934 iPosition->checkMotionDone(j, &
done);
935 iControlMode->getControlMode(j, &mode);
936 iPids->getPidOutput(VOCAB_PIDTYPE_POSITION,j, &output);
938 delta = fabs(angj-legacyStartupPosition.positions[j]);
939 yDebug(
"%s: checkGoneToZeroThreshold: joint: %d curr: %.3f des: %.3f -> delta: %.3f threshold: %.3f output: %.3f mode: %s" , \
940 deviceName.c_str(), j, angj, legacyStartupPosition.positions[j], delta, startupPosThreshold[j], output, yarp::os::Vocab32::decode(mode).c_str());
942 if (delta < startupPosThreshold[j] &&
done)
944 yDebug(
"%s: checkGoneToZeroThreshold: joint: %d completed with delta: %.3f over: %.3f" ,deviceName.c_str(),j,delta, startupPosThreshold[j]);
948 if (yarp::os::Time::now() - start_time > timeout_goToZero[j])
950 yError() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" Timeout while going to zero!";
953 if (mode == VOCAB_CM_IDLE)
955 yError() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" is idle, skipping!";
958 if (mode == VOCAB_CM_HW_FAULT)
960 yError() << deviceName <<
": checkGoneToZeroThreshold: hardware fault on joint " << j <<
", skipping!";
965 yWarning() << deviceName <<
": checkGoneToZeroThreshold: joint " << j <<
" Aborting wait while going to zero!\n";
979 std::list<int>::iterator joint;
982 if (useLegacyParking)
984 bool allJointsCanParkSimultaneously =
true;
985 for (
int i = 0; i < n_joints; i++)
987 if (disableHomeAndPark[i]) allJointsCanParkSimultaneously =
false;
990 if(allJointsCanParkSimultaneously ==
false)
992 yWarning() << deviceName <<
"Joints will be parked separately, since some of them have the disableHomeAndPark flag set";
994 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1005 yWarning() << deviceName <<
": Calling park without calibration... skipping";
1011 yWarning() << deviceName <<
": skipCalibration flag is on!! Faking park!!";
1015 int * currentControlModes =
new int[n_joints];
1016 std::vector<bool> cannotPark(n_joints);
1017 bool res = iControlMode->getControlModes(currentControlModes);
1020 yError() << deviceName <<
": error getting control mode during parking";
1023 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1025 switch(currentControlModes[(*joint)])
1029 yError() << deviceName <<
": joint " << (*joint) <<
" is idle, skipping park";
1030 cannotPark[(*joint)] =
true;
1034 case VOCAB_CM_HW_FAULT:
1036 yError() << deviceName <<
": joint " << (*joint) <<
" has an hardware fault, skipping park";
1037 cannotPark[(*joint)] =
true;
1041 case VOCAB_CM_NOT_CONFIGURED:
1043 yError() << deviceName <<
": joint " << (*joint) <<
" is not configured, skipping park";
1044 cannotPark[(*joint)] =
true;
1048 case VOCAB_CM_UNKNOWN:
1050 yError() << deviceName <<
": joint " << (*joint) <<
" is in unknown state, skipping park";
1051 cannotPark[(*joint)] =
true;
1056 iControlMode->setControlMode((*joint), VOCAB_CM_POSITION);
1057 cannotPark[(*joint)] =
false;
1062 bool parkSequenceDone{
false};
1063 if(useLegacyParking)
1065 moveAndCheck_legacy(legacyParkingPosition, cannotPark, wait);
1067 parkSequenceDone =
true;
1073 bool stepDone =
true;
1074 if(parkingSequence.size() > 0)
1076 stepDone = moveAndCheck(parkingSequence.at(currentParkingSeq_step));
1080 yDebug() <<
"ParametricCalibratorEth: park sequence step num " << currentParkingSeq_step <<
" ended with " << \
1081 (abortParking ?
"failure" :
"success");
1084 abortParking =
true;
1086 currentParkingSeq_step++;
1089 if( (currentParkingSeq_step >= parkingSequence.size()) || stepDone ==
false)
1090 parkSequenceDone =
true;
1094 if(parkSequenceDone)
1096 yDebug() << deviceName.c_str() <<
": Park " << (abortParking ?
"aborted" :
"completed");
1097 for(joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1099 switch(currentControlModes[(*joint)])
1102 case VOCAB_CM_HW_FAULT:
1103 case VOCAB_CM_NOT_CONFIGURED:
1104 case VOCAB_CM_UNKNOWN:
1109 iControlMode->setControlMode((*joint), VOCAB_CM_IDLE);
1117 bool parametricCalibratorEth::moveAndCheck(PositionSequence &
data)
1119 iPosition->setRefSpeeds(
data.velocities.data());
1120 iPosition->positionMove(
data.positions.data());
1128 iPosition->checkMotionDone(&
done);
1134 yError() <<
"ParametricCalibratorEth: parking " << deviceName <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1140 bool parametricCalibratorEth::moveAndCheck_legacy(PositionSequence &
data, std::vector<bool> &cannotPark,
bool wait)
1144 for(
auto joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1146 if (cannotPark[(*joint)] ==
false)
1148 iPosition->setRefSpeed((*joint),
data.velocities[(*joint)]);
1149 iPosition->positionMove((*joint),
data.positions[(*joint)]);
1156 for(
auto joint = calibJoints.begin(); joint != calibJoints.end() && !abortCalib; joint++)
1159 if (cannotPark[(*joint)] ==
false)
1161 yDebug() << deviceName.c_str() <<
": Moving to park position, joint:" << (*joint);
1163 iPosition->checkMotionDone((*joint), &
done);
1168 iPosition->checkMotionDone((*joint), &
done);
1172 yError() << deviceName <<
": joint " << (*joint) <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1182 yDebug() << deviceName.c_str() <<
": Quitting calibrate\n";
1189 yDebug() << deviceName.c_str() <<
": Quitting parking\n";
1201 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1203 yError(
"%s cannot perform 'calibration' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1207 return calibrateJoint(j);
1218 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1220 yError(
"%s cannot perform 'homing' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1224 if (disableHomeAndPark[j])
1226 yWarning() << deviceName <<
": homingSingleJoint, joint " << j <<
" is disabled on user request";
1229 return goToStartupPosition(j);
1236 std::list<int>::iterator lit;
1237 for(lit = calibJoints.begin(); lit != calibJoints.end() && !abortCalib; lit++)
1247 if(std::find(calibJoints.begin(), calibJoints.end(), j) == calibJoints.end())
1249 yError(
"%s cannot perform 'park' operation because joint number %d is out of range [%s].", deviceName.c_str(), j, calibJointsString.toString().c_str());
1253 if(useLegacyParking)
1255 if (disableHomeAndPark[j])
1257 yWarning() << deviceName <<
": parkSingleJoint, joint " << j <<
" is disabled on user request";
1266 yWarning() << deviceName <<
": Calling park without calibration... skipping";
1272 yWarning() << deviceName <<
": skipCalibration flag is on!! Faking park!!";
1276 int currentControlMode;
1278 bool res = iControlMode->getControlMode(j, ¤tControlMode);
1281 yError() << deviceName <<
": error getting control mode during parking";
1284 if(currentControlMode != VOCAB_CM_IDLE &&
1285 currentControlMode != VOCAB_CM_HW_FAULT)
1287 iControlMode->setControlMode(j, VOCAB_CM_POSITION);
1290 else if (currentControlMode == VOCAB_CM_IDLE)
1292 yError() << deviceName <<
": joint " << j <<
" is idle, skipping park";
1295 else if (currentControlMode == VOCAB_CM_HW_FAULT)
1297 yError() << deviceName <<
": joint " << j <<
" has an hardware fault, skipping park";
1301 if(useLegacyParking)
1303 iPosition->setRefSpeed (j, legacyStartupPosition.velocities[j]);
1304 iPosition->positionMove(j, legacyStartupPosition.positions[j]);
1309 iPosition->setRefSpeed (j, parkingSequence.rbegin()->velocities[j]);
1310 iPosition->positionMove(j, parkingSequence.rbegin()->positions[j]);
1315 if (cannotPark ==
false)
1318 yDebug() << deviceName.c_str() <<
": Moving to park position, joint:" << j;
1320 iPosition->checkMotionDone(j, &
done);
1325 iPosition->checkMotionDone(j, &
done);
1329 yError() << deviceName <<
": joint " << j <<
" not in position after a timeout of" <<
PARK_TIMEOUT <<
" seconds";
1334 yDebug() << deviceName.c_str() <<
": Park " << (abortParking ?
"aborted" :
"completed");
1335 iControlMode->setControlMode(j,VOCAB_CM_IDLE);
1346 yError() <<
"Device is not calibrated therefore cannot be parked";
1350 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
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)