00001 /**************************************************************** 00002 * 00003 * Copyright (c) 2012 00004 * 00005 * Fraunhofer Institute for Manufacturing Engineering 00006 * and Automation (IPA) 00007 * 00008 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00009 * 00010 * Project name: Generic_CANOpen 00011 * ROS stack name: cob_drivers 00012 * ROS package name: cob_generic_can 00013 * Description: 00014 * 00015 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00016 * 00017 * Author: 00018 * Supervised by: 00019 * 00020 * Date of creation: Jan 2012 00021 * 00022 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00023 * 00024 * Redistribution and use in source and binary forms, with or without 00025 * modification, are permitted provided that the following conditions are met: 00026 * 00027 * * Redistributions of source code must retain the above copyright 00028 * notice, this list of conditions and the following disclaimer. 00029 * * Redistributions in binary form must reproduce the above copyright 00030 * notice, this list of conditions and the following disclaimer in the 00031 * documentation and/or other materials provided with the distribution. 00032 * * Neither the name of the Fraunhofer Institute for Manufacturing 00033 * Engineering and Automation (IPA) 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 3 of the 00040 * License, or (at your option) any later version. 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 for more details. 00046 * 00047 * You should have received a copy of the GNU Lesser General Public 00048 * License LGPL along with this program. 00049 * If not, see <http://www.gnu.org/licenses/>. 00050 * 00051 ****************************************************************/ 00052 00053 // includes 00054 #include <CANOpenMaster.h> 00055 00056 /*---------------------------------------------------------------*/ 00057 // starts SYNC Thread 00058 void InitMaster() 00059 { 00060 // access CAN hardware 00061 // TODO get rid of *.ini 00062 can_itf = new CANPeakSysUSB("/home/tim/git/care-o-bot/schunk_modular_robotics/CANOpen_driver/CanCtrl.ini"); 00063 00064 // Init Buffer 00065 PDO_buffer = new CANOpen_buffer(); 00066 } 00067 00068 /*---------------------------------------------------------------*/ 00069 // starts SYNC Thread 00070 void StartMasterThread(double SYNC_Freq_HZ) 00071 { 00072 // init threads 00073 pthread_t thread_Master; 00074 int thread_Master_ret; 00075 00076 TD_Master.Cycle_Freq_HZ = SYNC_Freq_HZ; 00077 00078 thread_Master_ret = pthread_create( &thread_Master, NULL, MasterThreadFunc,(void*) &TD_Master); 00079 } 00080 00081 /*---------------------------------------------------------------*/ 00082 // activate the PDO 00083 void AcitvatePDO(int CAN_ID, int number, double SYNC_Freq_HZ) 00084 { 00085 if (PDO_buffer->IsActive(number)) 00086 { PDO_buffer->RegMsg(CAN_ID, number, SYNC_Freq_HZ); } 00087 } 00088 00089 /*---------------------------------------------------------------*/ 00090 // set new value to PDO 00091 void AssignValue2PDO(int number,char* Msg) 00092 { 00093 // Msg array has fixed lenght of 8 00094 PDO_buffer->SetMsg(number, Msg); 00095 } 00096 00097 /*---------------------------------------------------------------*/ 00098 // get Msg buffer 00099 int GetRecievedMsgs(CanMsg* Msgs) 00100 { 00101 int Msg_Counter = 0; 00102 00103 for(int i=0; i<MAX_InBuffer_Lenght; i++) 00104 { 00105 if(!InBuffer.empty()) 00106 { Msgs[i] = InBuffer.front(); 00107 InBuffer.pop(); 00108 Msg_Counter++; 00109 } 00110 } 00111 return Msg_Counter; 00112 } 00113 00114 /*=============================================*/ 00115 00116 /*---------------------------------------------------------------*/ 00117 // starts SYNC Thread 00118 void *MasterThreadFunc(void* TD_Master) 00119 { 00120 // cast Data struct 00121 Thread_data* m_TD = (Thread_data*) TD_Master; 00122 00123 // init threads 00124 pthread_t thread_WorkBuffer; 00125 int thread_WorkBuffer_ret; 00126 Mutex* mtx; 00127 00128 mtx = new Mutex(); 00129 00130 for(;;) 00131 { 00132 mtx->lock(); 00133 // TODO scaduling of the worker 00134 thread_WorkBuffer_ret = pthread_create( &thread_WorkBuffer, NULL,EvaluateBuffers,(void*) TD_Master); 00135 00136 mtx->unlock(); 00137 00138 usleep(1000000/(double)m_TD->Cycle_Freq_HZ); 00139 } 00140 pthread_exit(0); 00141 } 00142 00143 /*---------------------------------------------------------------*/ 00144 // Loop for buffer workout 00145 void *EvaluateBuffers(void* TD) 00146 { 00147 int Msg_Counter = 0; 00148 CanMsg cMsg; 00149 00150 Thread_data* m_TD = (Thread_data*) TD; 00151 00152 00153 00154 // 1. send all PDOs on the bus 00155 for (int i=0;i<MAX_PDOS;i++) 00156 { 00157 if(PDO_buffer->IsActive(i)) 00158 { 00159 // send PDO value 00160 //WritePDO(PDO_buffer->data[i].CMsg); 00161 } 00162 } 00163 00164 // 2. send SYNC msg and start synchronous motion 00165 SendSYNC(); 00166 00167 // 3. send 1 SDO form que 00168 00169 // 4. evaluate recieve buffer 00170 while ((can_itf->receiveMsg(&cMsg)!=0) || (Msg_Counter>=MAX_InBuffer_Lenght)) 00171 { 00172 InBuffer.push(cMsg); 00173 Msg_Counter++; 00174 } 00175 //std::cout << "SYNC ID: " << std::hex << CANOpenMasterObj->TxSDO << std::endl; 00176 00177 // ??? nötig 00178 pthread_exit(0); 00179 } 00180 00181 /*---------------------------------------------------------------*/ 00182 // send SYNC msg 00183 void SendSYNC() 00184 { 00185 CanMsg CMsgTr; 00186 00187 CMsgTr.m_iLen = 0; 00188 CMsgTr.m_iID = CANObj.SYNC; 00189 00190 can_itf->transmitMsg(CMsgTr); 00191 00192 //if(can_itf->receiveMsg(&CMsgTr)!=0) 00193 //{CMsgTr.print();} 00194 }