ElmoCtrl.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2010
00004  *
00005  * Fraunhofer Institute for Manufacturing Engineering   
00006  * and Automation (IPA)
00007  *
00008  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009  *
00010  * Project name: care-o-bot
00011  * ROS stack name: cob3_driver
00012  * ROS package name: cob_camera_axis
00013  *                                                              
00014  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00015  *                      
00016  * Author: Ulrich Reiser, email:ulrich.reiser@ipa.fhg.de
00017  *
00018  * Date of creation: Jul 2010
00019  * ToDo:
00020  *
00021  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00022  *
00023  * Redistribution and use in source and binary forms, with or without
00024  * modification, are permitted provided that the following conditions are met:
00025  *
00026  *     * Redistributions of source code must retain the above copyright
00027  *       notice, this list of conditions and the following disclaimer.
00028  *     * Redistributions in binary form must reproduce the above copyright
00029  *       notice, this list of conditions and the following disclaimer in the
00030  *       documentation and/or other materials provided with the distribution.
00031  *     * Neither the name of the Fraunhofer Institute for Manufacturing 
00032  *       Engineering and Automation (IPA) nor the names of its
00033  *       contributors may be used to endorse or promote products derived from
00034  *       this software without specific prior written permission.
00035  *
00036  * This program is free software: you can redistribute it and/or modify
00037  * it under the terms of the GNU Lesser General Public License LGPL as 
00038  * published by the Free Software Foundation, either version 3 of the 
00039  * License, or (at your option) any later version.
00040  * 
00041  * This program is distributed in the hope that it will be useful,
00042  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00043  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00044  * GNU Lesser General Public License LGPL for more details.
00045  * 
00046  * You should have received a copy of the GNU Lesser General Public 
00047  * License LGPL along with this program. 
00048  * If not, see <http://www.gnu.org/licenses/>.
00049  *
00050  ****************************************************************/
00051 
00052 
00053 #include <cob_camera_axis/ElmoCtrl.h>
00054 
00055 #include <iostream>
00056 
00057 using namespace std;
00058 
00059 void Sleep(int msecs){usleep(1000*msecs);}
00060 
00061 bool ElmoCtrl::sendNetStartCanOpen(CanItf* canCtrl) {
00062         bool ret = false;       
00063 
00064         CanMsg msg;
00065 
00066         msg.m_iID  = 0;
00067         msg.m_iLen = 2;
00068         msg.set(1,0,0,0,0,0,0,0);
00069         ret = canCtrl->transmitMsg(msg, false);
00070 
00071         usleep(100000);
00072 
00073         return ret;
00074 }
00075 
00076 
00077 ElmoCtrl::ElmoCtrl() {
00078         m_Joint = NULL;
00079         m_JointParams = NULL;
00080         m_CanCtrl = NULL;
00081         m_CanBaseAddress = 0;
00082         m_MotionCtrlType = POS_CTRL;
00083         m_MaxVel = 2.0;
00084         m_Params = NULL;
00085 }
00086 
00087 ElmoCtrl::~ElmoCtrl() {
00088         if (m_Joint)
00089                 m_Joint->shutdown();
00090                 delete m_Joint;
00091         if (m_JointParams)
00092                 delete m_JointParams;
00093         if (m_CanCtrl)
00094                 delete m_CanCtrl;
00095 }
00096 
00097 bool ElmoCtrl::Home()
00098 {
00099         bool success = false;
00100         if (m_Joint != NULL) {
00101                 //THIS is needed for head_axis on cob3-2!
00102                 //set input logic to 'general purpose'
00103                 m_Joint->IntprtSetInt(8, 'I', 'L', 2, 7);                      
00104                 usleep(20000);  
00105                 
00106                 //THIS is needed for cob3-3 (it's using DIN1):
00107                 //set input logic to 'general purpose'
00108                 m_Joint->IntprtSetInt(8, 'I', 'L', 1, 6);                       
00109                 usleep(20000);  
00110                 
00111                 m_Joint->initHoming();
00112         }
00113 
00114         //ToDo: UHR: necessary?
00115         Sleep(10);
00116         printf("ElmoCtrl: Home(): Homing Vel = %f\n",m_HomingDir*0.3);
00117         m_Joint->setGearVelRadS(m_HomingDir*0.3);
00118         //cpc-pk: removed this sleep, it's not necessary to leave home-sensor during homing
00119         //Sleep(750);
00120         success = m_Joint->execHoming();
00121         m_Joint->setGearVelRadS(0.0);
00122 
00123         return success;
00124 }
00125 
00126 
00127 int ElmoCtrl::evalCanBuffer() {
00128         bool bRet;
00129         
00130         //pthread_mutex_lock(&(m_Mutex));
00131 
00132         // as long as there is something in the can buffer -> read out next message
00133         while(m_CanCtrl->receiveMsg(&m_CanMsgRec) == true) {
00134                 bRet = false;
00135                 // check if the message belongs to camera_axis motor
00136                 bRet |= m_Joint->evalReceivedMsg(m_CanMsgRec);
00137 
00138                 if (bRet == true) {
00139                 } else std::cout << "cob_camera_axis: Unknown CAN-msg: " << m_CanMsgRec.m_iID << "  " << (int)m_CanMsgRec.getAt(0) << " " << (int)m_CanMsgRec.getAt(1) << std::endl;
00140         }
00141         
00142         //pthread_mutex_unlock(&(m_Mutex));
00143 
00144         return 0;
00145 }
00146 
00147 bool ElmoCtrl::RecoverAfterEmergencyStop() {
00148         
00149         bool success = false;
00150         printf("Resetting motor ...\n");
00151         success = m_Joint->start();
00152         if (!success) {
00153                 printf("failed!\n");
00154         } else {        
00155                 printf("successful\n");
00156                 m_Joint->setGearVelRadS(0);
00157         }
00158         Sleep(1000);
00159         return success;
00160 }
00161 
00162 
00163 bool ElmoCtrl::Init(ElmoCtrlParams * params, bool home) { //home = true by default
00164         bool success = false;
00165         string CanIniFile;
00166         string CanDevice;
00167         int baudrate = 0;
00168         
00169         m_Params = params;
00170 
00171         if (params == NULL) {
00172                 printf("ElmoCtrlParams:Error:%s:%d:, invalid parameters!\n",__FILE__,__LINE__);
00173                 success = false;
00174         } else {
00175                 success = true;
00176         }
00177 
00178         if (success) {
00179                 printf( "------------ ElmoCtrl Init ---------------\n");
00180                 
00181                 //Allocate memory and read params e.g. gotten from ROS parameter server
00182                 m_Joint = new CanDriveHarmonica();
00183                 m_JointParams = new DriveParam();
00184                 m_CanBaseAddress = params->GetModuleID();
00185                 CanIniFile = params->GetCanIniFile();   
00186                 m_MaxVel = params->GetMaxVel();
00187                 m_HomingDir = params->GetHomingDir();
00188                 m_HomingDigIn = params->GetHomingDigIn();
00189                 
00190                 m_EncIncrPerRevMot = params->GetEncoderIncrements();
00191                 m_MotorDirection = params->GetMotorDirection();
00192                 m_GearRatio = params->GetGearRatio();
00193                 
00194                 if (CanIniFile.length() == 0) { 
00195                         printf("%s,%d:Error: Parameter 'CanIniFile' not given!\n",__FILE__,__LINE__);
00196                         success = false;
00197                 }
00198                 
00199                 CanDevice = params->GetCanDevice();
00200                 if (CanDevice.length() == 0) {  
00201                         printf("%s,%d:Error: Parameter 'Can-Device' not given!\n",__FILE__,__LINE__);
00202                         success = false;
00203                 }
00204                 
00205                 baudrate = params->GetBaudRate();
00206                 if (baudrate == 0) {    
00207                         printf("%s,%d:Error: Parameter 'Baud-Rate' not given!\n",__FILE__,__LINE__);
00208                         success = false;
00209                 }
00210                 
00211                 //Setting motor model data              
00212                 if (success) {
00213                         m_JointOffset = params->GetAngleOffset();
00214                         m_UpperLimit = params->GetUpperLimit();
00215                         m_LowerLimit = params->GetLowerLimit();
00216                 }
00217 
00218                 if (success) {
00219                         printf("The following parameters were successfully read from the parameter server (given through *params): \n");
00220                         printf("CanIniFile:     %s\n",CanIniFile.c_str());
00221                         printf("CanDieODvice:   %s\n",CanDevice.c_str());
00222                         printf("Baudrate:       %d\n",baudrate);
00223                         printf("Module ID: %d\n",m_CanBaseAddress);
00224                         printf("Max Vel: %f\n",m_MaxVel);
00225                         printf("Homing Dir: %d\n",m_HomingDir);
00226                         printf("HomingDigIn: %d\n",m_HomingDigIn);
00227                         printf("Offset/Limit(min/max)  %f/(%f,%f)\n",m_JointOffset,m_LowerLimit,m_UpperLimit);
00228                 }
00229         }
00230         
00231         //Setting up CAN interface
00232         
00233         if (success) {
00234           //m_CanCtrl = new CanESD(CanIniFile.c_str(), false);
00235                 m_CanCtrl = new CANPeakSysUSB(CanIniFile.c_str());
00236                 if (m_CanCtrl == NULL) {
00237                         printf("%s,%d:Error: Could not open Can Device!\n",__FILE__,__LINE__);
00238                         success = false;
00239                 }
00240           }
00241         
00242         if (success) {
00243                         /* WRONG CAN-identifiers
00244                         //m_CanBaseAddress = params->GetModulID(i);
00245                         m_CanAddress.TxPDO1 = 0x181 + m_CanBaseAddress -1;
00246                         m_CanAddress.TxPDO2 = 0x285 + m_CanBaseAddress -1;
00247                         m_CanAddress.RxPDO2 = 0x301 + m_CanBaseAddress -1;
00248                         m_CanAddress.TxSDO = 0x491 + m_CanBaseAddress -1;
00249                         m_CanAddress.RxSDO = 0x511 + m_CanBaseAddress -1;
00250                         */
00251                         m_CanAddress.TxPDO1 = 0x181 + m_CanBaseAddress -1;
00252                         m_CanAddress.TxPDO2 = 0x281 + m_CanBaseAddress -1;
00253                         m_CanAddress.RxPDO2 = 0x301 + m_CanBaseAddress -1;
00254                         m_CanAddress.TxSDO = 0x581 + m_CanBaseAddress -1;
00255                         m_CanAddress.RxSDO = 0x601 + m_CanBaseAddress -1;
00256                         m_Joint->setCanItf(m_CanCtrl);
00257                         m_Joint->setCanOpenParam(m_CanAddress.TxPDO1, 
00258                                                         m_CanAddress.TxPDO2, 
00259                                                         m_CanAddress.RxPDO2, 
00260                                                         m_CanAddress.TxSDO, 
00261                                                         m_CanAddress.RxSDO );
00262                                                         
00263                         printf("CanAdresses set to %d (Base), %x, %x, %x, %x, %x...\n", m_CanBaseAddress,
00264                                                                                                                                                 m_CanAddress.TxPDO1,
00265                                                                                                                                                 m_CanAddress.TxPDO2,
00266                                                                                                                                                 m_CanAddress.RxPDO2,
00267                                                                                                                                                 m_CanAddress.TxSDO,
00268                                                                                                                                                 m_CanAddress.RxSDO);
00269                 
00270           }
00271           
00272           if (success) {
00273                 success = sendNetStartCanOpen(m_CanCtrl);
00274           }
00275           
00276           if (success) {
00277                 //ToDo: Read from File!
00278                 /*
00279                 int iDriveIdent,
00280                 int iEncIncrPerRevMot,
00281                 double dVelMeasFrqHz,
00282                 double dBeltRatio,
00283                 double dGearRatio,
00284                 int iSign,
00285                 double dVelMaxEncIncrS,
00286                 double dAccIncrS2,
00287                 double dDecIncrS2,
00288                 int iEncOffsetIncr,
00289                 bool bIsSteer,
00290         double dCurrToTorque,
00291                 double dCurrMax,
00292                 int iHomingDigIn
00293                 */
00294 
00295 /*
00296                 m_JointParams->setParam( //parameters taken from CanCtrl.ini
00297                                                         0, //int iDriveIdent,
00298                                                         4096,//int iEncIncrPerRevMot,
00299                                                         1,//double dVelMeasFrqHz,
00300                                                         1,//double dBeltRatio,
00301                                                         47.77,//double dGearRatio,
00302                                                         -1.0,//int iSign,
00303                                                         740000,//double dVelMaxEncIncrS,
00304                                                         1000000,//80000,//double dAccIncrS2,
00305                                                         1000000,//80000//double dDecIncrS2),
00306                                                         0, //int iEncOffsetIncr
00307                                                         true, // bool bIsSteer
00308                                                         0, // double dCurrToTorque
00309                                                         0, // double dCurrMax
00310                                                         m_HomingDigIn // int iHomingDigIn //cob3-2->11, cob3-1->9
00311                                           );
00312 */
00313 
00314                 m_JointParams->setParam( //parameters taken from CanCtrl.ini
00315                                                         0, //int iDriveIdent,
00316                                                         m_EncIncrPerRevMot,//int iEncIncrPerRevMot,
00317                                                         1,//double dVelMeasFrqHz,
00318                                                         1,//double dBeltRatio,
00319                                                         m_GearRatio,//double dGearRatio,
00320                                                         m_MotorDirection,//int iSign,
00321                                                         74000000,//double dVelMaxEncIncrS,
00322                                                         1000000,//80000,//double dAccIncrS2,
00323                                                         1000000,//80000//double dDecIncrS2),
00324                                                         0, //int iEncOffsetIncr
00325                                                         true, // bool bIsSteer
00326                                                         0, // double dCurrToTorque
00327                                                         0, // double dm_HomingDigInCurrMax
00328                                                         m_HomingDigIn // int iHomingDigIn //cob3-2->11, cob3-1->9
00329                                           );
00330                 
00331                           
00332                 m_Joint->setDriveParam(*m_JointParams);
00333                 }
00334 
00335           if (success)
00336           {
00337                           printf("Init motor ...\n");
00338                           success = m_Joint->init();
00339                           if (!success)
00340                           {
00341                                           printf("failed!\n");
00342                           }
00343                           else
00344                           {     
00345                                           printf("successful\n");
00346                           }
00347           }
00348           
00349           if (success)
00350                           success = SetMotionCtrlType(m_MotionCtrlType);
00351                           if(!success) std::cout << "Failed to SetMotionCtrlType to " << m_MotionCtrlType << std::endl;
00352 
00353           if (success)
00354           {
00355                           printf("Starting motor ..\n");
00356                           success = m_Joint->start();
00357                           if (!success)
00358                           {
00359                                           printf("failed!\n");
00360                           }
00361                           else
00362                           {     
00363                                           printf("successful\n");
00364                                           m_Joint->setGearVelRadS(0);
00365                           }
00366           }
00367           //ToDo: UHR: necessary?
00368           Sleep(1000);
00369 
00370           if (success && home)
00371           {
00372                 std::cout << "Start homing procedure now.." << std::endl;
00373                           success = Home();
00374           }
00375           //Thread init
00376           if (success)
00377           {
00378                           pthread_mutex_init(&m_Mutex,NULL);
00379           }
00380 
00381 
00382           return success;
00383 }
00384 
00385 bool ElmoCtrl::SetMotionCtrlType(int type)
00386 {
00387         m_MotionCtrlType = type;
00388         bool success = false; 
00389         if (type == POS_CTRL)
00390         {
00391                         success = m_Joint->shutdown();
00392                         if (success)
00393                                         success = m_Joint->setTypeMotion(CanDriveHarmonica::MOTIONTYPE_POSCTRL);
00394                                                 
00395                         //ToDo: necessary?
00396                         Sleep(100);
00397                         success = m_Joint->start();
00398         
00399         }
00400         else if (type == VEL_CTRL)
00401         {
00402                 //UHR: ToDo
00403                 printf("%s%d:Error: Velocity control not implemented yet!\n",__FILE__,__LINE__);
00404                 success = false;
00405         }
00406         return success;
00407 };
00408 
00409 
00410 int ElmoCtrl::GetMotionCtrlType() 
00411 {
00412         return m_MotionCtrlType;
00413 }
00414 
00415 int ElmoCtrl::getGearPosVelRadS( double* pdAngleGearRad, double* pdVelGearRadS)
00416 {
00417 
00418         // init default outputs
00419         *pdAngleGearRad = 0;
00420         *pdVelGearRadS = 0;
00421 
00422         m_Joint->getGearPosVelRadS(pdAngleGearRad, pdVelGearRadS);
00423         *pdAngleGearRad = *pdAngleGearRad - m_JointOffset;
00424         
00425         return 0;
00426 }
00427 
00428 //-----------------------------------------------
00429 
00430 int ElmoCtrl:: setGearPosVelRadS(double dPosRad, double dVelRadS)
00431 {
00432 
00433         if(dPosRad< m_LowerLimit) {
00434                 std::cout << "Position under LowerBound -> set up" << std::endl;
00435                 dPosRad = m_LowerLimit;
00436         } else if(dPosRad > m_UpperLimit) {
00437                 std::cout << "Position over UpperBound -> set down" << std::endl;
00438                 dPosRad = m_UpperLimit;
00439         }
00440                 
00441         if(dVelRadS > m_MaxVel)
00442                 dVelRadS = m_MaxVel;
00443         else if(dVelRadS < -m_MaxVel)
00444                 dVelRadS = -m_MaxVel;
00445 
00446         //COB3-2: m_Joint->setGearPosVelRadS(dPosRad + m_JointOffset, dVelRadS);
00447         
00448         //COB3-1: m_Joint->setGearPosVelRadS(-3.141592654 - dPosRad + m_JointOffset, dVelRadS);
00449         printf("ElmoCtrl:setGearPosVelRadS: dPosRad %f with vel %f\n",dPosRad, dVelRadS);
00450         m_Joint->setGearPosVelRadS(m_HomingDir * dPosRad + m_JointOffset, dVelRadS);
00451         return 0;
00452 }
00453 
00454 bool ElmoCtrl::Stop()
00455 {
00456                 //UHR: ToDo: what happens exactly in this method? Sudden stop?
00457                 double pos = 0.0;
00458                 double vel = 0.0;
00459                 m_Joint->getGearPosVelRadS(&pos,&vel);
00460                 m_Joint->setGearPosVelRadS(pos,0);
00461 
00462                 return true;
00463                 //m_Joint[i]->shutdown();
00464 
00465 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


cob_head_axis
Author(s): Ulrich Reiser
autogenerated on Fri Mar 1 2013 17:48:28