00001 /**************************************************************** 00002 * 00003 * Copyright (c) 2011 00004 * All rights reserved. 00005 * 00006 * Hochschule Bonn-Rhein-Sieg 00007 * University of Applied Sciences 00008 * Computer Science Department 00009 * 00010 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00011 * 00012 * Author: 00013 * Jan Paulus, Nico Hochgeschwender, Michael Reckhaus, Azamat Shakhimardanov 00014 * Supervised by: 00015 * Gerhard K. Kraetzschmar 00016 * 00017 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00018 * 00019 * This sofware is published under a dual-license: GNU Lesser General Public 00020 * License LGPL 2.1 and BSD license. The dual-license implies that users of this 00021 * code may choose which terms they prefer. 00022 * 00023 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00024 * 00025 * Redistribution and use in source and binary forms, with or without 00026 * modification, are permitted provided that the following conditions are met: 00027 * 00028 * * Redistributions of source code must retain the above copyright 00029 * notice, this list of conditions and the following disclaimer. 00030 * * Redistributions in binary form must reproduce the above copyright 00031 * notice, this list of conditions and the following disclaimer in the 00032 * documentation and/or other materials provided with the distribution. 00033 * * Neither the name of the Hochschule Bonn-Rhein-Sieg nor the names of its 00034 * contributors may be used to endorse or promote products derived from 00035 * this software without specific prior written permission. 00036 * 00037 * This program is free software: you can redistribute it and/or modify 00038 * it under the terms of the GNU Lesser General Public License LGPL as 00039 * published by the Free Software Foundation, either version 2.1 of the 00040 * License, or (at your option) any later version or the BSD license. 00041 * 00042 * This program is distributed in the hope that it will be useful, 00043 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00044 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00045 * GNU Lesser General Public License LGPL and the BSD license for more details. 00046 * 00047 * You should have received a copy of the GNU Lesser General Public 00048 * License LGPL and BSD license along with this program. 00049 * 00050 ****************************************************************/ 00051 #include <youbot_driver/youbot/YouBotGripperBar.hpp> 00052 namespace youbot 00053 { 00054 00055 YouBotGripperBar::YouBotGripperBar(const unsigned int barNo, const unsigned int jointNo, 00056 const std::string& configFilePath) 00057 { 00058 // Bouml preserved body begin 000E0371 00059 this->jointNumber = jointNo; 00060 this->mailboxMsgRetries = 200; 00061 this->timeTillNextMailboxUpdate = 1; //ms 00062 this->barNo = barNo; 00063 this->maxTravelDistance = 0.0115 * meter; 00064 this->maxEncoderValue = 67000; 00065 this->barSpacingOffset = 0 * meter; 00066 00067 ethercatMaster = &(EthercatMaster::getInstance("youbot-ethercat.cfg", configFilePath)); 00068 // Bouml preserved body end 000E0371 00069 } 00070 00071 YouBotGripperBar::~YouBotGripperBar() 00072 { 00073 // Bouml preserved body begin 000E03F1 00074 // Bouml preserved body end 000E03F1 00075 } 00076 00077 void YouBotGripperBar::setConfigurationParameter(const MaxEncoderValue& parameter) 00078 { 00079 // Bouml preserved body begin 00061E71 00080 this->maxEncoderValue = parameter.value; 00081 // Bouml preserved body end 00061E71 00082 } 00083 00084 void YouBotGripperBar::getConfigurationParameter(MaxEncoderValue& parameter) const 00085 { 00086 // Bouml preserved body begin 000D7871 00087 parameter.value = this->maxEncoderValue; 00088 // Bouml preserved body end 000D7871 00089 } 00090 00091 void YouBotGripperBar::getConfigurationParameter(MaxTravelDistance& parameter) const 00092 { 00093 // Bouml preserved body begin 000D77F1 00094 parameter.value = this->maxTravelDistance; 00095 // Bouml preserved body end 000D77F1 00096 } 00097 00098 void YouBotGripperBar::setConfigurationParameter(const MaxTravelDistance& parameter) 00099 { 00100 // Bouml preserved body begin 00061DF1 00101 this->maxTravelDistance = parameter.value; 00102 // Bouml preserved body end 00061DF1 00103 } 00104 00105 void YouBotGripperBar::setConfigurationParameter(const BarSpacingOffset& parameter) 00106 { 00107 // Bouml preserved body begin 00061871 00108 this->barSpacingOffset = parameter.value; 00109 // Bouml preserved body end 00061871 00110 } 00111 00112 void YouBotGripperBar::getConfigurationParameter(BarSpacingOffset& parameter) const 00113 { 00114 // Bouml preserved body begin 000D7771 00115 parameter.value = this->barSpacingOffset; 00116 // Bouml preserved body end 000D7771 00117 } 00118 00119 void YouBotGripperBar::setConfigurationParameter(const GripperBarName& parameter) 00120 { 00121 // Bouml preserved body begin 0010A271 00122 this->name = parameter.value; 00123 // Bouml preserved body end 0010A271 00124 } 00125 00126 void YouBotGripperBar::getConfigurationParameter(GripperBarName& parameter) const 00127 { 00128 // Bouml preserved body begin 0010A1F1 00129 parameter.value = this->name; 00130 // Bouml preserved body end 0010A1F1 00131 } 00132 00133 void YouBotGripperBar::getConfigurationParameter(YouBotGripperParameter& parameter) const 00134 { 00135 // Bouml preserved body begin 000E05F1 00136 00137 if (parameter.getType() == MOTOR_CONTOLLER_PARAMETER) 00138 { 00139 00140 YouBotSlaveMailboxMsg message; 00141 parameter.getYouBotMailboxMsg(message); 00142 message.stctOutput.commandNumber = GAP; 00143 message.stctOutput.moduleAddress = GRIPPER; 00144 message.stctOutput.motorNumber = this->barNo; 00145 message.parameterName = parameter.getName(); 00146 00147 if (retrieveValueFromMotorContoller(message)) 00148 { 00149 parameter.setYouBotMailboxMsg(message); 00150 } 00151 else 00152 { 00153 throw JointParameterException("Unable to get parameter: " + parameter.getName() + " from the gripper"); 00154 } 00155 } 00156 else 00157 { 00158 throw JointParameterException( 00159 "Parameter " + parameter.getName() + " is not a motor controller parameter of the gripper"); 00160 } 00161 // Bouml preserved body end 000E05F1 00162 } 00163 00164 void YouBotGripperBar::setConfigurationParameter(const YouBotGripperParameter& parameter) 00165 { 00166 // Bouml preserved body begin 000E0671 00167 if (parameter.getType() == MOTOR_CONTOLLER_PARAMETER) 00168 { 00169 00170 YouBotSlaveMailboxMsg message; 00171 parameter.getYouBotMailboxMsg(message); 00172 message.stctOutput.commandNumber = SAP; 00173 message.stctOutput.moduleAddress = GRIPPER; 00174 message.stctOutput.motorNumber = this->barNo; 00175 message.parameterName = parameter.getName(); 00176 00177 if (!setValueToMotorContoller(message)) 00178 { 00179 throw JointParameterException("Unable to set parameter: " + parameter.getName() + " to the gripper"); 00180 } 00181 } 00182 else 00183 { 00184 throw JointParameterException( 00185 "Parameter " + parameter.getName() + " is not a motor controller parameter of the gripper"); 00186 } 00187 // Bouml preserved body end 000E0671 00188 } 00189 00190 void YouBotGripperBar::getConfigurationParameter(YouBotSlaveMailboxMsg& parameter) const 00191 { 00192 // Bouml preserved body begin 000E0A71 00193 if (!retrieveValueFromMotorContoller(parameter)) 00194 { 00195 throw JointParameterException("Unable to get parameter from the gripper"); 00196 } 00197 this->parseMailboxStatusFlags(parameter); 00198 // Bouml preserved body end 000E0A71 00199 } 00200 00201 void YouBotGripperBar::setData(const GripperBarEncoderSetpoint& encoderSetpoint) 00202 { 00203 // Bouml preserved body begin 000E0CF1 00204 YouBotSlaveMailboxMsg message; 00205 message.stctOutput.moduleAddress = GRIPPER; 00206 message.stctOutput.commandNumber = MVP; 00207 message.stctOutput.typeNumber = 0; //move gripper absolute 00208 message.stctOutput.motorNumber = this->barNo; 00209 message.stctOutput.value = encoderSetpoint.barEncoder * -1; 00210 00211 setValueToMotorContoller(message); 00212 00213 // Bouml preserved body end 000E0CF1 00214 } 00215 00216 void YouBotGripperBar::getData(GripperSensedVelocity& barVelocity) const 00217 { 00218 // Bouml preserved body begin 000E0DF1 00219 YouBotSlaveMailboxMsg message; 00220 message.stctOutput.moduleAddress = GRIPPER; 00221 message.stctOutput.commandNumber = GAP; 00222 message.stctOutput.typeNumber = 3; //actual velocity 00223 message.stctOutput.value = 0; 00224 00225 message.stctOutput.motorNumber = this->barNo; 00226 00227 retrieveValueFromMotorContoller(message); 00228 //std::cout << message.stctInput.value << std::endl; 00229 00230 barVelocity.barVelocity = message.stctInput.value; 00231 00232 // Bouml preserved body end 000E0DF1 00233 } 00234 00235 void YouBotGripperBar::getData(GripperSensedBarPosition& barPosition) const 00236 { 00237 // Bouml preserved body begin 000F9171 00238 int valueBar = 0; 00239 ActualPosition actualPoseBar; 00240 this->getConfigurationParameter(actualPoseBar); 00241 actualPoseBar.getParameter(valueBar); 00242 00243 barPosition.barPosition = (((double)valueBar / this->maxEncoderValue) * this->maxTravelDistance) 00244 + this->barSpacingOffset; 00245 00246 // Bouml preserved body end 000F9171 00247 } 00248 00249 void YouBotGripperBar::setData(GripperBarPositionSetPoint& barPosition) 00250 { 00251 // Bouml preserved body begin 000F91F1 00252 00253 if (barPosition.barPosition > (this->maxTravelDistance + this->barSpacingOffset) 00254 || barPosition.barPosition < this->barSpacingOffset) 00255 { 00256 std::stringstream errorMessageStream; 00257 errorMessageStream << "The bar position is not allowed to be less than " << this->barSpacingOffset 00258 << " or higher than " << (this->maxTravelDistance + this->barSpacingOffset) << ". You set " 00259 << barPosition.barPosition; 00260 throw std::out_of_range(errorMessageStream.str()); 00261 } 00262 00263 quantity<si::length> setpoint; 00264 ; 00265 setpoint = (barPosition.barPosition - this->barSpacingOffset); 00266 00267 GripperBarEncoderSetpoint setpointBar; 00268 setpointBar.barEncoder = setpoint / this->maxTravelDistance * this->maxEncoderValue; 00269 this->setData(setpointBar); 00270 00271 // Bouml preserved body end 000F91F1 00272 } 00273 00274 void YouBotGripperBar::parseGripperErrorFlags(const unsigned int& errosFlags) 00275 { 00276 // Bouml preserved body begin 00103CF1 00277 if (errosFlags & STALL_GUARD_STATUS) 00278 { 00279 // LOG(warning) << "Gripper " << "stallguard2 threshold reached"; 00280 } 00281 if (errosFlags & GRIPPER_OVER_TEMPERATURE) 00282 { 00283 LOG(error) << "Gripper " << "over temperature"; 00284 } 00285 if (errosFlags & PRE_WARNING_OVER_TEMPERATURE) 00286 { 00287 LOG(warning) << "Gripper " << "pre warning over temperature"; 00288 } 00289 if (errosFlags & SHORT_TO_GROUND_A) 00290 { 00291 LOG(error) << "Gripper " << "short to ground A"; 00292 } 00293 if (errosFlags & SHORT_TO_GROUND_B) 00294 { 00295 LOG(error) << "Gripper " << "short to ground B"; 00296 } 00297 if (errosFlags & OPEN_LOAD_A) 00298 { 00299 LOG(warning) << "Gripper " << "open load A"; 00300 } 00301 if (errosFlags & OPEN_LOAD_B) 00302 { 00303 LOG(warning) << "Gripper " << "open load B"; 00304 } 00305 if (errosFlags & STAND_STILL) 00306 { 00307 // LOG(info) << "Gripper " << "stand still"; 00308 } 00309 if (!(errosFlags & STAND_STILL) && (errosFlags & STALL_GUARD_STATUS)) 00310 { 00311 LOG(info) << "Gripper " << "motor stall"; 00312 } 00313 // Bouml preserved body end 00103CF1 00314 } 00315 00316 void YouBotGripperBar::parseMailboxStatusFlags(const YouBotSlaveMailboxMsg& mailboxMsg) const 00317 { 00318 // Bouml preserved body begin 000E0E71 00319 std::stringstream errorMessageStream; 00320 errorMessageStream << "Joint " << this->jointNumber << ": "; 00321 std::string errorMessage; 00322 errorMessage = errorMessageStream.str(); 00323 00324 switch (mailboxMsg.stctInput.status) 00325 { 00326 case NO_ERROR: 00327 break; 00328 case INVALID_COMMAND: 00329 LOG(error) << errorMessage << "Parameter name: " << mailboxMsg.parameterName << "; Command no: " 00330 << mailboxMsg.stctOutput.commandNumber << " is an invalid command!"; 00331 // throw JointParameterException(errorMessage + "invalid command"); 00332 break; 00333 case WRONG_TYPE: 00334 LOG(error) << errorMessage << "Parameter name: " << mailboxMsg.parameterName << " has a wrong type!"; 00335 // throw JointParameterException(errorMessage + "wrong type"); 00336 break; 00337 case INVALID_VALUE: 00338 LOG(error) << errorMessage << "Parameter name: " << mailboxMsg.parameterName << " Value: " 00339 << mailboxMsg.stctOutput.value << " is a invalid value!"; 00340 // throw JointParameterException(errorMessage + "invalid value"); 00341 break; 00342 case CONFIGURATION_EEPROM_LOCKED: 00343 LOG(error) << errorMessage << "Parameter name: " << mailboxMsg.parameterName << " Configuration EEPROM locked"; 00344 // throw JointParameterException(errorMessage + "configuration EEPROM locked"); 00345 break; 00346 case COMMAND_NOT_AVAILABLE: 00347 LOG(error) << errorMessage << "Parameter name: " << mailboxMsg.parameterName << "; Command no: " 00348 << mailboxMsg.stctOutput.commandNumber << "Command is not available!"; 00349 // throw JointParameterException(errorMessage + "command not available"); 00350 break; 00351 } 00352 00353 // Bouml preserved body end 000E0E71 00354 } 00355 00356 bool YouBotGripperBar::setValueToMotorContoller(const YouBotSlaveMailboxMsg& mailboxMsg) const 00357 { 00358 // Bouml preserved body begin 000E0EF1 00359 00360 YouBotSlaveMailboxMsg mailboxMsgBuffer; 00361 mailboxMsgBuffer = mailboxMsg; 00362 bool unvalid = true; 00363 unsigned int retry = 0; 00364 00365 ethercatMaster->setMailboxMsgBuffer(mailboxMsgBuffer, this->jointNumber); 00366 // LOG(trace) << "set Output CommandNumber " << (int) mailboxMsgBuffer.stctOutput.commandNumber 00367 // << " moduleAddress " << (int) mailboxMsgBuffer.stctOutput.moduleAddress 00368 // << " motorNumber " << (int) mailboxMsgBuffer.stctOutput.motorNumber 00369 // << " typeNumber " << (int) mailboxMsgBuffer.stctOutput.typeNumber 00370 // << " value " << mailboxMsgBuffer.stctOutput.value; 00371 00372 SLEEP_MILLISEC(timeTillNextMailboxUpdate); 00373 00374 do 00375 { 00376 00377 if (ethercatMaster->getMailboxMsgBuffer(mailboxMsgBuffer, this->jointNumber) 00378 && mailboxMsgBuffer.stctInput.status == NO_ERROR) 00379 { 00380 unvalid = false; 00381 } 00382 else 00383 { 00384 SLEEP_MILLISEC(timeTillNextMailboxUpdate); 00385 retry++; 00386 } 00387 // LOG(trace) << "set Input CommandNumber " << (int) mailboxMsgBuffer.stctInput.commandNumber 00388 // << " moduleAddress " << (int) mailboxMsgBuffer.stctInput.moduleAddress 00389 // << " replyAddress " << (int) mailboxMsgBuffer.stctInput.replyAddress 00390 // << " status " << (int) mailboxMsgBuffer.stctInput.status 00391 // << " value " << mailboxMsgBuffer.stctInput.value; 00392 } while (retry < mailboxMsgRetries && unvalid); 00393 00394 if (unvalid) 00395 { 00396 this->parseMailboxStatusFlags(mailboxMsgBuffer); 00397 return false; 00398 } 00399 else 00400 { 00401 return true; 00402 } 00403 00404 // Bouml preserved body end 000E0EF1 00405 } 00406 00407 bool YouBotGripperBar::retrieveValueFromMotorContoller(YouBotSlaveMailboxMsg& message) const 00408 { 00409 // Bouml preserved body begin 000E0F71 00410 00411 bool unvalid = true; 00412 unsigned int retry = 0; 00413 00414 ethercatMaster->setMailboxMsgBuffer(message, this->jointNumber); 00415 // LOG(trace) << "get Output CommandNumber " << (int) message.stctOutput.commandNumber 00416 // << " moduleAddress " << (int) message.stctOutput.moduleAddress 00417 // << " motorNumber " << (int) message.stctOutput.motorNumber 00418 // << " typeNumber " << (int) message.stctOutput.typeNumber 00419 // << " value " << message.stctOutput.value 00420 // << " No " << this->jointNumber; 00421 00422 SLEEP_MILLISEC(timeTillNextMailboxUpdate); 00423 00424 do 00425 { 00426 00427 if (ethercatMaster->getMailboxMsgBuffer(message, this->jointNumber) && message.stctInput.status == NO_ERROR) 00428 { 00429 unvalid = false; 00430 } 00431 else 00432 { 00433 SLEEP_MILLISEC(timeTillNextMailboxUpdate); 00434 retry++; 00435 } 00436 // LOG(trace) << "get input CommandNumber " << (int) message.stctInput.commandNumber 00437 // << " moduleAddress " << (int) message.stctInput.moduleAddress 00438 // << " replyAddress " << (int) message.stctInput.replyAddress 00439 // << " status " << (int) message.stctInput.status 00440 // << " value " << message.stctInput.value 00441 // << " No " << this->jointNumber; 00442 00443 } while (retry < mailboxMsgRetries && unvalid); 00444 00445 if (unvalid) 00446 { 00447 this->parseMailboxStatusFlags(message); 00448 return false; 00449 } 00450 else 00451 { 00452 return true; 00453 } 00454 00455 // Bouml preserved body end 000E0F71 00456 } 00457 00458 } // namespace youbot