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 }