///calibrate the reference position of the arm joints void YouBotManipulator::calibrateManipulator(const bool forceCalibration) { // Bouml preserved body begin 000A9C71 //Calibrate all manipulator joints std::vector<JointRoundsPerMinuteSetpoint> calibrationVel; JointRoundsPerMinuteSetpoint tempdummy; tempdummy.rpm = 0; calibrationVel.assign(numberArmJoints, tempdummy); std::vector<quantity<si::current> > maxCurrent; quantity<si::current> tempdummy2; maxCurrent.assign(numberArmJoints, tempdummy2); std::vector<bool> doCalibration; doCalibration.assign(numberArmJoints, true); std::string jointName; double dummy = 0; char index = 16; // Parameter 0 to 15 of bank 2 are password protected YouBotSlaveMailboxMsg IsCalibratedReadMessage; IsCalibratedReadMessage.stctOutput.moduleAddress = DRIVE; IsCalibratedReadMessage.stctOutput.commandNumber = GGP; IsCalibratedReadMessage.stctOutput.typeNumber = index; IsCalibratedReadMessage.stctOutput.motorNumber = USER_VARIABLE_BANK; IsCalibratedReadMessage.stctOutput.value = 0; IsCalibratedReadMessage.stctInput.value = 0; YouBotSlaveMailboxMsg IsCalibratedSetMessage; IsCalibratedSetMessage.stctOutput.moduleAddress = DRIVE; IsCalibratedSetMessage.stctOutput.commandNumber = SGP; IsCalibratedSetMessage.stctOutput.typeNumber = index; IsCalibratedSetMessage.stctOutput.motorNumber = USER_VARIABLE_BANK; IsCalibratedSetMessage.stctOutput.value = 1; //get parameters for calibration for (unsigned int i = 0; i < numberArmJoints; i++) { std::stringstream jointNameStream; jointNameStream << "Joint_" << i + 1; jointName = jointNameStream.str(); bool calib = true; configfile->readInto(calib, jointName, "DoCalibration"); doCalibration[i] = calib; joints[i].getConfigurationParameter(IsCalibratedReadMessage); if (IsCalibratedReadMessage.stctInput.value == 1) { doCalibration[i] = false; } if (forceCalibration) { doCalibration[i] = true; } configfile->readInto(dummy, jointName, "CalibrationMaxCurrent_[ampere]"); maxCurrent[i] = dummy * ampere; std::string direction; configfile->readInto(direction, jointName, "CalibrationDirection"); GearRatio gearRatio; joints[i].getConfigurationParameter(gearRatio); double gearratio = 1; gearRatio.getParameter(gearratio); if (direction == "POSITIV") { calibrationVel[i].rpm = 1 / gearratio; } else if (direction == "NEGATIV") { calibrationVel[i].rpm = -1 / gearratio; } else { throw std::runtime_error("Wrong calibration direction for " + jointName); } } LOG(info) << "Calibrate Manipulator Joints "; std::vector<bool> finished; finished.assign(numberArmJoints, false); int numberUnfinished = numberArmJoints; JointSensedCurrent sensedCurrent; //move the joints slowly in calibration direction for (unsigned int i = 0; i < numberArmJoints; i++) { if (doCalibration[i] == true) { joints[i].setData(calibrationVel[i]); if(!ethercatMaster.isThreadActive()){ ethercatMaster.sendProcessData(); ethercatMaster.receiveProcessData(); } } else { if (!finished[i]) { finished[i] = true; numberUnfinished--; } } } //monitor the current to find end stop while (numberUnfinished > 0) { for (unsigned int i = 0; i < numberArmJoints; i++) { if(!ethercatMaster.isThreadActive()){ ethercatMaster.sendProcessData(); ethercatMaster.receiveProcessData(); } joints[i].getData(sensedCurrent); //turn till a max current is reached if (abs(sensedCurrent.current) > abs(maxCurrent[i])) { //stop movement youbot::JointCurrentSetpoint currentStopMovement; currentStopMovement.current = 0 * ampere; joints[i].setData(currentStopMovement); if(!ethercatMaster.isThreadActive()){ ethercatMaster.sendProcessData(); ethercatMaster.receiveProcessData(); } if (!finished[i]) { finished[i] = true; numberUnfinished--; } } } SLEEP_MILLISEC(1); } // wait to let the joint stop the motion SLEEP_MILLISEC(100); for (unsigned int i = 0; i < numberArmJoints; i++) { if (doCalibration[i] == true) { //set encoder reference position joints[i].setEncoderToZero(); if(!ethercatMaster.isThreadActive()){ ethercatMaster.sendProcessData(); ethercatMaster.receiveProcessData(); } // set a flag in the user variable to remember that it is calibrated joints[i].setConfigurationParameter(IsCalibratedSetMessage); // LOG(info) << "Calibration finished for joint: " << this->jointName; } } //setting joint Limits JointLimits jLimits; for (unsigned int i = 0; i < numberArmJoints; i++) { long upperlimit = 0, lowerlimit = 0; std::stringstream jointNameStream; bool inverted = false; jointNameStream << "Joint_" << i + 1; jointName = jointNameStream.str(); JointEncoderSetpoint minEncoderValue; configfile->readInto(lowerlimit, jointName, "LowerLimit_[encoderTicks]"); configfile->readInto(upperlimit, jointName, "UpperLimit_[encoderTicks]"); configfile->readInto(inverted, jointName, "InverseMovementDirection"); if(inverted){ minEncoderValue.encoderTicks = lowerlimit + 1000; }else{ minEncoderValue.encoderTicks = upperlimit - 1000; } jLimits.setParameter(lowerlimit, upperlimit, true); joints[i].setConfigurationParameter(jLimits); // joints[i].setData(minEncoderValue); } // Bouml preserved body end 000A9C71 }