00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 #include <CANOpen_driver.h>
00059 
00060 
00061 #include <stdlib.h> 
00062 
00063     
00064     
00065     
00066 
00067 
00068 CANOpenMaster::CANOpenMaster()
00069 {               
00070         
00071         CANObj = new CANOpenCiA401ObjDirectory();
00072         
00073         m_CanBaseAddress = 0x0c;
00074 
00075         TxSDO = 0x580 + m_CanBaseAddress;
00076         RxSDO = 0x600 + m_CanBaseAddress;
00077         TxPDO1 = 0x180 + m_CanBaseAddress;
00078         RxPDO1 = 0x200 + m_CanBaseAddress;
00079         TxPDO2 = 0x280 + m_CanBaseAddress;
00080         RxPDO2 = 0x300 + m_CanBaseAddress;
00081         TxPDO3 = 0x380 + m_CanBaseAddress;
00082         RxPDO3 = 0x400 + m_CanBaseAddress;
00083         TxPDO4 = 0x480 + m_CanBaseAddress;
00084         RxPDO4 = 0x500 + m_CanBaseAddress;      
00085         SYNC = 0x080; 
00086         EMCY = 0x080 + m_CanBaseAddress; 
00087         NMT = 0x000; 
00088         HEARTBEAT = 0x700 + m_CanBaseAddress; 
00089         
00090         NodeState = 0x05; 
00091         ControlerState = 0; 
00092         
00093         
00094         SWITCH_ON = 0x07; 
00095         SHUTDOWN = 0x06; 
00096         DISABLE_VOLTAGE = 0x00; 
00097         QUICKSTOP = 0x02;
00098         DISABLE_OPERATION = 0x07;
00099         ENABLE_OPERATION = 0x0F; 
00100         FAULT_RESET = 0x0080;  
00101         
00102         
00103         Not_Ready_To_Switch_On = 0x0000;
00104         Switch_On_Disabled = 0x0040;
00105         Ready_To_Switch_On = 0x0021;
00106         Switched_On = 0x0023; 
00107         Operation_Enable = 0x0027; 
00108         Fault = 0x0008; 
00109         Fault_Reaction_Active = 0x000F;
00110         Quick_Stop_Active = 0x0007;     
00111         
00112         
00113         IS_HOMED = false; 
00114         FAULT_WAS_ACTIVE = true; 
00115         
00116         
00117         const int ciInitDownloadReq = 0x20;
00118         const int ciNrBytesNoData = 0x00;
00119         const int ciExpedited = 0x02;
00120         const int ciDataSizeInd = 0x01;
00121 
00122         CANDownloadHeader = ciInitDownloadReq | (ciNrBytesNoData << 2) | ciExpedited | ciDataSizeInd;
00123 
00124         Lin_Axis_max_speed = 83; 
00125 }
00126 
00127 
00128 
00129 CANOpenMaster::~CANOpenMaster() 
00130 {
00131         delete can_itf; 
00132         delete CANObj;
00133 }
00134 
00135 
00136 
00137 int CANOpenMaster::Init()
00138 {       
00139         
00140         usleep(500000);
00141         
00142 
00143 
00144 
00145 
00146       
00147         
00148         SendNMT(m_CanBaseAddress,0x01);         
00149 
00150         usleep(500000);
00151 
00152         
00153 
00154         usleep(100000);
00155         
00156         
00157 
00158         usleep(100000);
00159         
00160 
00161                 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188         
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214         
00215 
00216         usleep(100000);
00217 
00218         
00219 
00220         usleep(100000);
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00238 
00239 
00240         
00241         
00242 
00243         usleep(100000);
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260       
00261         
00262         SendNMT(m_CanBaseAddress,0x01);         
00263         
00264         usleep(100000);
00265         
00266         return 0; 
00267 }
00268 
00269 
00270 
00271 int CANOpenMaster::Homing()
00272 {       
00273         int timer = 0; 
00274         int referenced = 0; 
00275 
00276         
00277         try{std::cout << "mode: " << ReadObject(&CANObj->mode_of_operation_display) << std::endl;}
00278                         catch(int error) 
00279                         {ROS_INFO("Error on reading: %i",       error);return -1;}
00280         
00281         usleep(500000);
00282         
00283         
00284         if (WriteObject(&CANObj->mode_of_operation, CANObj->HOMING_MODE)!=0){return -2;}
00285 
00286         usleep(500000);
00287 
00288         
00289         try{std::cout << "mode: " << ReadObject(&CANObj->mode_of_operation_display) << std::endl;}
00290                         catch(int error) 
00291                         {ROS_INFO("Error on reading: %i",       error);return -3;}
00292 
00293 
00294         
00295         while(timer<50)
00296         {       
00297                 try{
00298                         referenced = ReadObject(&CANObj->mode_of_operation_display); 
00299                         }
00300                         catch(int error) 
00301                         {ROS_INFO("Error on reading: %i",       error);return -4;}
00302                 
00303                 if(referenced == CANObj->HOMING_MODE){break;}
00304                 
00305                 timer++;
00306                 usleep(10000);
00307         }
00308 
00309         
00310         if (WriteObject(&CANObj->controlword, SHUTDOWN)!=0){return -5;}
00311         usleep(200000);
00312         
00313         if (WriteObject(&CANObj->controlword, SWITCH_ON)!=0){return -6;}
00314         usleep(200000);
00315         
00316         if (WriteObject(&CANObj->controlword, ENABLE_OPERATION)!=0){return -7;}
00317         usleep(200000);
00318         
00319         if (WriteObject(&CANObj->controlword, (0x0010 | ENABLE_OPERATION))!=0){return -8;}
00320         
00321         ROS_INFO("Homing Start");
00322         
00323         
00324         while(timer<100)
00325         {       
00326                 try{
00327                         referenced = ReadObject(&CANObj->statusword); 
00328                         }
00329                         catch(int error) 
00330                         {ROS_INFO("Error on reading: %i",       error);return -9;}
00331                 
00332                 if((referenced & 0x1000) == 0x1000)
00333                 {       
00334                         break; 
00335                 }
00336                 
00337                 timer++;
00338                 usleep(100000);
00339         }
00340 
00341         
00342         if (WriteObject(&CANObj->mode_of_operation, CANObj->IP_MODE)!=0){return -10;}
00343         
00344         
00345         while(timer<500)
00346         {       
00347                 try{
00348                         referenced = ReadObject(&CANObj->mode_of_operation_display); 
00349                         }
00350                         catch(int error) 
00351                         {ROS_INFO("Error on reading: %i",       error);return -11;}
00352                 
00353                 if(referenced == CANObj->IP_MODE)
00354                 {
00355                         
00356                         try{std::cout << "mode: " << ReadObject(&CANObj->mode_of_operation_display) << std::endl;}
00357                         catch(int error) 
00358                         {ROS_INFO("Error on reading: %i",       error);return -12;}
00359                         
00360                         
00361                         if (WriteObject(&CANObj->controlword, ( FAULT_RESET | 0x0010 | ENABLE_OPERATION))!=0){return -13;}
00362                         usleep(500000);
00363 
00364                         std::cout << "Status: " << (ReadObject(&CANObj->statusword)) << std::endl; 
00365 
00366                         return 0;
00367                 }
00368                 
00369                 timer++;
00370                 usleep(1000);
00371         }
00372         
00373         return -14; 
00374         
00375 }
00376 
00377 
00378 
00379 void CANOpenMaster::SendSYNC()
00380 {       
00381         CanMsg CMsgTr;
00382         
00383         CMsgTr.m_iLen = 0;
00384         CMsgTr.m_iID = SYNC;
00385 
00386         can_itf->transmitMsg(CMsgTr);
00387         
00388         
00389         
00390 }
00391 
00392 
00393 
00394 int CANOpenMaster::SetSpeed(int SpeedCmdMS)
00395 {       
00396         if (SpeedCmdMS > Lin_Axis_max_speed){SpeedCmdMS = Lin_Axis_max_speed;}
00397         if (SpeedCmdMS < -Lin_Axis_max_speed){SpeedCmdMS = -Lin_Axis_max_speed;}
00398         
00399         if (WriteObject(&CANObj->target_velocity, SpeedCmdMS)!=0){return -1;}
00400         return 0;
00401 }
00402 
00403 
00404 
00405 int CANOpenMaster::GetSpeed()
00406 {       
00407         int SpeedMS; 
00408         try{SpeedMS = ReadObject(&CANObj->velocity_actual_value);}
00409         catch(int error){ROS_INFO("Error on reading: %i",error);return -1;}
00410         return SpeedMS;
00411 }
00412 
00413 
00414 
00415 int CANOpenMaster::GetDIn()
00416 {       
00417         int DIn; 
00418         try{DIn = ReadObject(&CANObj->digital_inputs);}
00419         catch(int error){ROS_INFO("Error on reading: %i",error);return -1;}
00420         return DIn;
00421 }
00422 
00423 
00424 
00425 int CANOpenMaster::Recover()
00426 {       
00427         int nErr = 0, timer=0; 
00428         
00429         EvaluateControlerState();
00430         
00431         while((ControlerState == Fault) || (ControlerState == Fault_Reaction_Active) || (ControlerState == Quick_Stop_Active))
00432         {       
00433                 
00434                 if (WriteObject(&CANObj->controlword, 0x00)!=0){return -1;}
00435                 usleep(500000);
00436         
00437                 if (WriteObject(&CANObj->controlword, FAULT_RESET)!=0){return -1;}
00438                 usleep(500000);
00439         
00440                 
00441                 EvaluateControlerState();
00442                 
00443                 
00444                 if (timer>10)
00445                 {return -1;}
00446                 else 
00447                 {timer++;}
00448         }
00449                 
00450         if (ControlerState != Switch_On_Disabled)
00451         {ROS_INFO("error on transition to Switch_On_Disabled.Controllerstate = %i",ControlerState); 
00452                 try{
00453                 nErr = (0x0000FF00 & ReadObject(&CANObj->pre_defined_error_field[0])); 
00454                 }
00455                 catch(int error) 
00456                 {       std::cout << "Error on reading: " << error << std::endl;}
00457                 if (nErr != 0) 
00458                 {       std::cout << "There are Errors: " << std::endl; 
00459                         for (int i=0;i<nErr;i++)
00460                         {       try{std::cout << "Error" << i <<": " << ReadObject(&CANObj->pre_defined_error_field[i]) << std::endl;} 
00461                                 catch(int error) 
00462                                 {std::cout << "Error on reading: " << error << std::endl; return -1;}
00463                         }
00464                 }else{std::cout << "No Errors saved" << std::endl;}
00465                 return -1;
00466         }
00467         
00468         usleep(100000);
00469         
00470         
00471         if (WriteObject(&CANObj->controlword, SHUTDOWN)!=0){return -1;}
00472         
00473         usleep(100000);
00474         
00475         
00476         if(EvaluateControlerState()!=0){return -1;} 
00477         if (ControlerState != Ready_To_Switch_On)
00478         {ROS_INFO("error on transition to Ready_To_Switch_On. Controllerstate = %i",ControlerState); return -1;}
00479         
00480         usleep(100000);
00481                 
00482         
00483         WriteObject(&CANObj->controlword, SWITCH_ON);
00484         
00485         usleep(100000);
00486         
00487         
00488         if(EvaluateControlerState()!=0){return -1;} 
00489         if (ControlerState != Switched_On)
00490         {ROS_INFO("error on transition to Switched_On.Controllerstate = %i",ControlerState); return -1;}
00491         
00492         usleep(200000);
00493                 
00494         
00495         WriteObject(&CANObj->controlword, ENABLE_OPERATION);
00496         
00497         usleep(500000);
00498         
00499         
00500         EvaluateControlerState(); 
00501         if (ControlerState != Operation_Enable)
00502         {ROS_INFO("error on transition to Operation_Enable."); return -1;}
00503         
00504         FAULT_WAS_ACTIVE = false; 
00505         
00506         return 0; 
00507 }
00508 
00509 
00510 
00511 int CANOpenMaster::GetNodeState()
00512 {       
00513         unsigned int status; 
00514         
00515         try{status = ReadObject(&CANObj->manufacturer_status_register);} 
00516         catch(int error){ std::cout << "Error: " << error << std::endl; return -1;}
00517         
00518         
00519                 
00520                 if ((status & 1)==1)
00521                         {       std::cout << "Homing active" << std::endl; }
00522                 
00523                 if ((status & 2)==2)
00524                         {       std::cout << "Homingswitch reached" << std::endl; }
00525                 
00526                 if ((status & 4)==4)
00527                         {       std::cout << "negative endswitch reached" << std::endl; }
00528                 
00529                 if ((status & 8)==8)
00530                         {       std::cout << "positive endswitch reached" << std::endl; }
00531                 
00532                 if ((status & 16)==16)
00533                         {       std::cout << "positioning successfull" << std::endl; }          
00534                 
00535                 if ((status & 32)==32)
00536                         {       std::cout << "target reached" << std::endl; }           
00537                 
00538                 if ((status & 64)==64)
00539                         {       std::cout << "rest of positioning distance reached" << std::endl; }     
00540                 
00541                 if ((status & 128)==128)
00542                         {       std::cout << "reversive mode" << std::endl; }   
00543                 
00544                 if ((status & 256)==256)
00545                         {       std::cout << "rpm reached n_ist=(n_mel +/-n_mel_hyst)" << std::endl; }          
00546                 
00547                 if ((status & 512)==512)
00548                         {       std::cout << "rpm reached n_ist=(n_soll +/-n_mel_hyst)" << std::endl; } 
00549                 
00550                 if ((status & 1024)==1024)
00551                         {       std::cout << "Positioning started" << std::endl; }      
00552                 
00553                 if ((status & 2048)==2048)
00554                         {       std::cout << "I²t, Current-limiting active" << std::endl; }    
00555                 
00556                 if ((status & 4096)==4096)
00557                         {       std::cout << "SinCos producer active" << std::endl; }   
00558                 
00559                 if ((status & 8192)==8192)
00560                         {       std::cout << "rpm reached n_ist=(0 +/-n_mel_hyst)" << std::endl; }      
00561                 
00562                 if ((status & 16384)==16384)
00563                         {       std::cout << "rpm reached n_ist=(0 +/-n_mel_hyst)" << std::endl; }      
00564                 
00565                 if ((status & 32768)==32768)
00566                         {       std::cout << "rpm reached n_ist=(0 +/-n_mel_hyst)" << std::endl; }      
00567                 
00568                 if ((status & 65536)==65536)
00569                         {       std::cout << "Warning" << std::endl; }  
00570                 
00571                 if ((status & 131072)==131072)
00572                         {       std::cout << "General Error present" << std::endl; }            
00573                 
00574                 if ((status & 262144)==262144)
00575                         {       std::cout << "negative direction resticted" << std::endl; }                     
00576                 
00577                 if ((status & 524288)==524288)
00578                         {       std::cout << "positiv direction resticted" << std::endl; }      
00579                 
00580                 if ((status & 1048576)==1048576)
00581                         {       std::cout << "Homeing done" << std::endl; }     
00582                 
00583                 if ((status & 2097152)==2097152)
00584                         {       std::cout << "automatic syncronization activ" << std::endl; }   
00585                 
00586                 if ((status & 4194304)==4194304)
00587                         {       std::cout << "MMC initiated" << std::endl; }    
00588                 
00589                 if ((status & 8388608)==8388608)
00590                         {       std::cout << "Amps enabled" << std::endl; }     
00591                 
00592                 if ((status & 16777216)==16777216)
00593                         {       std::cout << "controler and amps enabled" << std::endl; }       
00594                 
00595                 if ((status & 33554432)==33554432)
00596                         {       std::cout << "rpm desired value enabled" << std::endl; }                                
00597                 
00598                 if ((status & 67108864)==67108864)
00599                         {       std::cout << "emergency stop without positioinsensor" << std::endl; }           
00600                 
00601                 if ((status & 134217728)==134217728)
00602                         {       std::cout << "MOTID-Mode" << std::endl; }       
00603                 
00604                 if ((status & 268435456)==268435456)
00605                         {       std::cout << "write permission" << std::endl; }
00606                 
00607                 if ((status & 536870912)==536870912)
00608                         {       std::cout << "Technologiemodul present" << std::endl; }
00609                 
00610                 if ((status & 1073741824)==1073741824)
00611                         {       std::cout << "MMC pluged in" << std::endl; }
00612                 
00613                 if ((status & (unsigned int) 2147483648)== (unsigned int) 2147483648)
00614                         {       std::cout << "safe stop pluged in" << std::endl; }
00615                 
00616         return 0; 
00617 }
00618 
00619 
00620 void CANOpenMaster::PrintMotorStatus()
00621 {
00622         CanMsg CMsgTr;
00623         const int ciInitUploadReq = 0x40;
00624 
00625         CMsgTr.m_iLen = 6;
00626         CMsgTr.m_iID = RxSDO;
00627 
00628         unsigned char cMsg[8];
00629 
00630         cMsg[0] = ciInitUploadReq;
00631         cMsg[1] = 0x41;
00632         cMsg[2] = 0x60;
00633         cMsg[3] = 0x00;
00634         cMsg[4] = 0x00;
00635         cMsg[5] = 0x00;
00636         cMsg[6] = 0x00;
00637         cMsg[7] = 0x00;
00638 
00639         CMsgTr.set(cMsg[0], cMsg[1], cMsg[2], cMsg[3], cMsg[4], cMsg[5], cMsg[6], cMsg[7]);
00640         can_itf->transmitMsg(CMsgTr);
00641 
00642         while (can_itf->receiveMsg(&CMsgTr)==0)
00643         {       
00644                 
00645                 CMsgTr.print();
00646                 usleep(500);
00647         }
00648         CMsgTr.print();
00649         if (CMsgTr.getAt(0) == 0x80)
00650         {       std::cout << "Error on status request. SDO Errorcode: " << std::hex << CMsgTr.getAt(7) << " " << std::hex << CMsgTr.getAt(6) << " " << std::hex << CMsgTr.getAt(5) << " " << std::hex << CMsgTr.getAt(4) << std::endl;
00651         }
00652         else
00653         {
00654                 short CurrState = ((CMsgTr.getAt(7)<<8)|CMsgTr.getAt(6)); 
00655                 
00656 
00657                 
00658 
00659                         
00660                         if ((CurrState & 0x004F)==0)
00661                         {       std::cout << "MotorState: Not_Ready_To_Switch_On" << std::endl; }
00662         
00663                         
00664                         if ((CurrState & 0x004F)==0x0040)
00665                         {       std::cout << "MotorState: Switch_On_Disabled" << std::endl; }
00666         
00667                         
00668                         if ((CurrState & 0x006F)==0x0021)
00669                         {       std::cout << "MotorState: Ready_To_Switch_On" << std::endl; }
00670         
00671                         
00672                         if ((CurrState & 0x006F)==0x0023)
00673                         {       std::cout << "MotorState: Switched_On" << std::endl; }
00674         
00675                         
00676                         if ((CurrState & 0x006F)==0x0027)
00677                         {       std::cout << "MotorState: Operation_Enable" << std::endl; }
00678         
00679                         
00680                         if ((CurrState & 0x004F)==0x0008)
00681                         {       std::cout << "MotorState: Fault" << std::endl; }
00682 
00683                         
00684                         if ((CurrState & 0x004F)==0x00F)
00685                         {       std::cout << "MotorState: Fault_Reaction_Active" << std::endl; }
00686         
00687                         
00688                         if ((CurrState & 0x006F)==0x0007)
00689                         {       std::cout << "MotorState: Quick_Stop_Active" << std::endl; }
00690         
00691                 
00692                 if ((CurrState & 0x0010)==0x0010)
00693                 {       std::cout << "voltage_enabled" << std::endl; } 
00694 
00695                 
00696                 if ((CurrState & 0x0080)==0x0080)
00697                 {       std::cout << "There are Warnings! Check!" << std::endl; } 
00698 
00699                 
00700                 if ((CurrState & 0x0100)==0x0100)
00701                 {       std::cout << "drive moves" << std::endl; } 
00702 
00703                 
00704                 if ((CurrState & 0x0200)==0x0200)
00705                 {       std::cout << "voltage_enabled" << std::endl; } 
00706 
00707                 
00708                 
00709                 if ((CurrState & 0x0400)==0x0400)
00710                 {       std::cout << "target reached" << std::endl; }
00711 
00712                 
00713                 if ((CurrState & 0x0800)==0x0800)
00714                 {       std::cout << "internal limits reached" << std::endl; } 
00715 
00716                 
00717                 if ((CurrState & 0x1000)==0x1000)
00718                 {       std::cout << "set_point_acknowladge / speed_0 / homing_attained / ip_mode_active" << std::endl; }  
00719 
00720                 
00721                 if ((CurrState & 0x2000)==0x2000)
00722                 {       std::cout << "following_error / homing_error" << std::endl; } 
00723 
00724                 
00725 
00726                 
00727                 if ((CurrState & 0x8000)==0x8000)
00728                 {       std::cout << "drive referenced" << std::endl; } 
00729         }
00730 }
00731 
00732     
00733     
00734     
00735 
00736 
00737 
00738 
00739 
00740 bool CANOpenMaster::CANError(CanMsg* CMsgTr)
00741 {       
00742         
00743         if (CMsgTr->getAt(0) == 0x80) 
00744         {
00745                 ROS_INFO("Error on CAN request: %i %i %i %i", CMsgTr->getAt(4), CMsgTr->getAt(5), CMsgTr->getAt(6), CMsgTr->getAt(7));
00746                 return true; 
00747         }
00748         
00749         return false;  
00750 }
00751 
00752 
00753 bool CANOpenMaster::NodeStateError(CanMsg* CMsgTr)
00754 {       
00755         
00756         if (CMsgTr->m_iID == HEARTBEAT)  
00757         {       
00758                 
00759                 if (CMsgTr->getAt(0) != NodeState)
00760                 {
00761                         ROS_INFO("Error! CAN-Node %i not operational. State: %i", m_CanBaseAddress, CMsgTr->getAt(0));
00762                         return true;
00763                 } 
00764                 
00765                 can_itf->receiveMsg(CMsgTr);
00766         }
00767         
00768         return false;  
00769 }
00770 
00771 
00772 unsigned int CANOpenMaster::ReadObject(CANOpenCiA401ObjDirectory::CANOpenObj* obj)
00773 {       
00774         CanMsg CMsgTr;
00775         
00776         int i, result = 0, timer = 0; 
00777         
00778         switch (obj->Format)
00779         {       case 0x2F : CMsgTr.m_iLen = 5;
00780                 case 0x2b : CMsgTr.m_iLen = 6;
00781                 case 0x23 : CMsgTr.m_iLen = 8;
00782         }
00783         
00784         CMsgTr.m_iID = RxSDO;
00785 
00786         unsigned char cMsg[8];
00787 
00788         cMsg[0] = 0x40; 
00789         cMsg[1] = obj->Index;           
00790         cMsg[2] = obj->Index >> 8;      
00791         cMsg[3] = obj->SubIndex;
00792         cMsg[4] = 0x00; 
00793         cMsg[5] = 0x00;
00794         cMsg[6] = 0x00;
00795         cMsg[7] = 0x00;
00796 
00797         CMsgTr.set(cMsg[0], cMsg[1], cMsg[2], cMsg[3], cMsg[4], cMsg[5], cMsg[6], cMsg[7]);
00798         
00799         if (can_itf->transmitMsg(CMsgTr) == 0)
00800         {throw -1; } 
00801 
00802         while(timer<1000)
00803         {               
00804                 can_itf->receiveMsg(&CMsgTr);
00805                 
00806                 if (NodeStateError(&CMsgTr)) {throw -2;}
00807                 
00808                 if (CANError(&CMsgTr)) {throw -3;}
00809                  
00810                 if((CMsgTr.getAt(0) == (obj->Format+0x20) ) && (CMsgTr.getAt(1)==cMsg[1]) && (CMsgTr.getAt(2)==cMsg[2]) && (CMsgTr.getAt(3)==cMsg[3]))
00811                 {
00812                         for(i=4;i<CMsgTr.m_iLen;i++)
00813                         {
00814                                 result += (CMsgTr.getAt(i) << (8*(i-4))); 
00815                         } 
00816                         return  result;  
00817                 }
00818                 timer++;
00819                 usleep(1000);
00820         }
00821         CMsgTr.print();
00822         throw -4; 
00823 }
00824 
00825 
00826 
00827 int CANOpenMaster::WriteObject(CANOpenCiA401ObjDirectory::CANOpenObj* obj, int val)
00828 {       
00829         CanMsg CMsgTr;
00830         
00831         int timer = 0; 
00832         
00833         switch (obj->Format)
00834         {       case 0x2F : CMsgTr.m_iLen = 5;
00835                 case 0x2b : CMsgTr.m_iLen = 6;
00836                 case 0x23 : CMsgTr.m_iLen = 8;
00837         }
00838         
00839         CMsgTr.m_iID = RxSDO;
00840 
00841         unsigned char cMsg[8];
00842 
00843         cMsg[0] = obj->Format;  
00844         cMsg[1] = obj->Index;           
00845         cMsg[2] = obj->Index >> 8;      
00846         cMsg[3] = obj->SubIndex;
00847         cMsg[4] = val; 
00848         if (CMsgTr.m_iLen > 5){cMsg[5] = val >> 8;}else{cMsg[5] = 0;}
00849         if (CMsgTr.m_iLen > 6){cMsg[6] = val >> 16; cMsg[7] = val >> 24;}else{cMsg[6] = 0,cMsg[7] = 0;}
00850 
00851         CMsgTr.set(cMsg[0], cMsg[1], cMsg[2], cMsg[3], cMsg[4], cMsg[5], cMsg[6], cMsg[7]);
00852         
00853         if (can_itf->transmitMsg(CMsgTr) == 0)
00854         {return -1; } 
00855 
00856         
00857         while(timer<1000)
00858         {       
00859                 can_itf->receiveMsg(&CMsgTr);
00860                 
00861                 if (NodeStateError(&CMsgTr)) {return -2;}
00862                 
00863                 if (CANError(&CMsgTr)) {return -3;}
00864                 
00865                 if((CMsgTr.getAt(0) == 0x60) && (CMsgTr.getAt(1)==cMsg[1]) && (CMsgTr.getAt(2)==cMsg[2]) && (CMsgTr.getAt(3)==cMsg[3]))
00866                 {
00867                         
00868                         return  0;  
00869                 }
00870                 timer++;
00871                 usleep(1000);
00872         }
00873         CMsgTr.print(); 
00874         return -4; 
00875 }
00876 
00877 
00878 
00879 int CANOpenMaster::WritePDO(CanMsg CMsgTr)
00880 {               
00881         
00882         if (can_itf->transmitMsg(CMsgTr) == 0)
00883         {return -1; } 
00884         
00885         return 0; 
00886 }
00887 
00888 
00889 
00890 int CANOpenMaster::WritePDO(int ControlWord, int IP_command)
00891 {       
00892         CanMsg CMsgTr;
00893         
00894         CMsgTr.m_iID = RxPDO1;
00895         CMsgTr.m_iLen = 8;
00896 
00897         unsigned char cMsg[8];
00898 
00899         cMsg[0] = (ControlWord >> 0); 
00900         cMsg[1] = (ControlWord >> 8);
00901         cMsg[2] = 0;
00902         cMsg[3] = 0;    
00903         cMsg[4] = (IP_command >> 0);
00904         cMsg[5] = (IP_command >> 8);
00905         cMsg[6] = (IP_command >> 16);
00906         cMsg[7] = (IP_command >> 24);
00907         
00908         CMsgTr.set(cMsg[0], cMsg[1], cMsg[2], cMsg[3], cMsg[4], cMsg[5], cMsg[6], cMsg[7]);
00909         
00910         
00911         if (can_itf->transmitMsg(CMsgTr) == 0)
00912         {return -1; } 
00913         
00914         
00915 
00916         if(can_itf->receiveMsg(&CMsgTr)!=0)
00917         {CMsgTr.print();}
00918 
00919         return 0; 
00920 }
00921 
00922 
00923 
00924 
00925 void CANOpenMaster::SendNMT(unsigned char NodeID, unsigned char NMT_Command)
00926 {
00927         CanMsg CMsgTr;
00928 
00929         CMsgTr.m_iLen = 2;
00930         CMsgTr.m_iID = 0x000;
00931 
00932         unsigned char cMsg[2];
00933 
00934         cMsg[0] = NMT_Command;
00935         cMsg[1] = NodeID; 
00936 
00937         CMsgTr.set(cMsg[0], cMsg[1]);
00938         can_itf->transmitMsg(CMsgTr);
00939 }
00940 
00941 
00945         int CANOpenMaster::WaitForHeartbeat()
00946         {
00947                 CanMsg CMsgTr;
00948                 int timer = 0; 
00949                 
00950                 while(timer<100)
00951                 {       can_itf->receiveMsg(&CMsgTr);
00952                         if(CMsgTr.m_iID == HEARTBEAT)
00953                         {return CMsgTr.getAt(0);}
00954                         timer++;
00955                         usleep(10000);
00956                 }
00957                 return -1; 
00958         }
00959 
00960 
00961         
00962         int CANOpenMaster::EvaluateControlerState()
00963         {       
00964                 int CurrState; 
00965                 
00966                 try {CurrState = ReadObject(&CANObj->statusword);}
00967                 catch(int error){return error;}
00968                 
00969                 
00970 
00971                         
00972                         if ((CurrState & 0x004F)==Not_Ready_To_Switch_On)
00973                         {       ControlerState = Not_Ready_To_Switch_On;
00974                                 std::cout << "MotorState: Not_Ready_To_Switch_On" << std::endl; }
00975         
00976                         
00977                         if ((CurrState & 0x004F)==Switch_On_Disabled)
00978                         {       ControlerState = Switch_On_Disabled;
00979                                 std::cout << "MotorState: Switch_On_Disabled" << std::endl; }
00980         
00981                         
00982                         if ((CurrState & 0x006F)==Ready_To_Switch_On)
00983                         {       ControlerState = Ready_To_Switch_On;
00984                                 std::cout << "MotorState: Ready_To_Switch_On" << std::endl; }
00985         
00986                         
00987                         if ((CurrState & 0x006F)==Switched_On)
00988                         {       ControlerState = Switched_On;
00989                                 std::cout << "MotorState: Switched_On" << std::endl; }
00990         
00991                         
00992                         if ((CurrState & 0x006F)==Operation_Enable)
00993                         {       ControlerState = Operation_Enable;
00994                                 std::cout << "MotorState: Operation_Enable" << std::endl; }
00995         
00996                         
00997                         if ((CurrState & 0x004F)==Fault)
00998                         {       ControlerState = Fault;
00999                                 std::cout << "MotorState: Fault" << std::endl; }
01000 
01001                         
01002                         if ((CurrState & 0x004F)==Fault_Reaction_Active)
01003                         {       ControlerState = Fault_Reaction_Active;
01004                                 std::cout << "MotorState: Fault_Reaction_Active" << std::endl; }
01005         
01006                         
01007                         if ((CurrState & 0x006F)==Quick_Stop_Active)
01008                         {       ControlerState = Quick_Stop_Active;
01009                                 std::cout << "MotorState: Quick_Stop_Active" << std::endl; }
01010         
01011                 
01012                 if ((CurrState & 0x0010)==0x0010)
01013                 {       std::cout << "voltage_enabled" << std::endl; } 
01014 
01015                 
01016                 if ((CurrState & 0x0080)==0x0080)
01017                 {       std::cout << "There are Warnings! Check!" << std::endl; } 
01018 
01019                 
01020                 if ((CurrState & 0x0100)==0x0100)
01021                 {       std::cout << "drive moves" << std::endl; } 
01022 
01023                 
01024                 if ((CurrState & 0x0200)==0x0200)
01025                 {       std::cout << "voltage_enabled" << std::endl; } 
01026 
01027                 
01028                 
01029                 if ((CurrState & 0x0400)==0x0400)
01030                 {       std::cout << "target reached" << std::endl; }
01031 
01032                 
01033                 if ((CurrState & 0x0800)==0x0800)
01034                 {       std::cout << "internal limits reached" << std::endl; } 
01035 
01036                 
01037                 if ((CurrState & 0x1000)==0x1000)
01038                 {       std::cout << "set_point_acknowladge / speed_0 / homing_attained / ip_mode_active" << std::endl; }  
01039 
01040                 
01041                 if ((CurrState & 0x2000)==0x2000)
01042                 {       std::cout << "following_error / homing_error" << std::endl; } 
01043 
01044                 
01045 
01046                 
01047                 if ((CurrState & 0x8000)==0x8000)
01048                 {       std::cout << "drive referenced" << std::endl; } 
01049                 
01050         return 0;
01051         }