00001 #ifndef YOUBOT_ETHERCATMASTERWITHTHREAD_H 00002 #define YOUBOT_ETHERCATMASTERWITHTHREAD_H 00003 00004 /**************************************************************** 00005 * 00006 * Copyright (c) 2011 00007 * All rights reserved. 00008 * 00009 * Hochschule Bonn-Rhein-Sieg 00010 * University of Applied Sciences 00011 * Computer Science Department 00012 * 00013 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00014 * 00015 * Author: 00016 * Jan Paulus, Nico Hochgeschwender, Michael Reckhaus, Azamat Shakhimardanov 00017 * Supervised by: 00018 * Gerhard K. Kraetzschmar 00019 * 00020 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00021 * 00022 * This sofware is published under a dual-license: GNU Lesser General Public 00023 * License LGPL 2.1 and BSD license. The dual-license implies that users of this 00024 * code may choose which terms they prefer. 00025 * 00026 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00027 * 00028 * Redistribution and use in source and binary forms, with or without 00029 * modification, are permitted provided that the following conditions are met: 00030 * 00031 * * Redistributions of source code must retain the above copyright 00032 * notice, this list of conditions and the following disclaimer. 00033 * * Redistributions in binary form must reproduce the above copyright 00034 * notice, this list of conditions and the following disclaimer in the 00035 * documentation and/or other materials provided with the distribution. 00036 * * Neither the name of the Hochschule Bonn-Rhein-Sieg nor the names of its 00037 * contributors may be used to endorse or promote products derived from 00038 * this software without specific prior written permission. 00039 * 00040 * This program is free software: you can redistribute it and/or modify 00041 * it under the terms of the GNU Lesser General Public License LGPL as 00042 * published by the Free Software Foundation, either version 2.1 of the 00043 * License, or (at your option) any later version or the BSD license. 00044 * 00045 * This program is distributed in the hope that it will be useful, 00046 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00047 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00048 * GNU Lesser General Public License LGPL and the BSD license for more details. 00049 * 00050 * You should have received a copy of the GNU Lesser General Public 00051 * License LGPL and BSD license along with this program. 00052 * 00053 ****************************************************************/ 00054 #include <vector> 00055 #include <sstream> 00056 #include <string> 00057 #include <cstdio> 00058 #include <stdexcept> 00059 #include <iostream> 00060 #include <boost/thread.hpp> 00061 #include <boost/date_time/posix_time/posix_time.hpp> 00062 #include "generic/dataobjectlockfree/DataObjectLockFree.hpp" 00063 #include "generic/Logger.hpp" 00064 #include "generic/Units.hpp" 00065 #include "generic/Time.hpp" 00066 #include "generic/Exceptions.hpp" 00067 #include "generic/ConfigFile.hpp" 00068 #include "youbot/ProtocolDefinitions.hpp" 00069 #include "youbot/YouBotSlaveMsg.hpp" 00070 #include "youbot/YouBotSlaveMailboxMsg.hpp" 00071 #include "youbot/EthercatMaster.hpp" 00072 #include "youbot/JointTrajectoryController.hpp" 00073 #include "youbot/JointLimitMonitor.hpp" 00074 00075 extern "C"{ 00076 #include <ethercattype.h> 00077 #include <ethercatmain.h> 00078 } 00079 00080 namespace youbot { 00081 00082 /////////////////////////////////////////////////////////////////////////////// 00083 /// The Ethercat Master is managing the whole ethercat communication 00084 /// It have to be a singleton in the system 00085 /////////////////////////////////////////////////////////////////////////////// 00086 class EthercatMasterWithThread : public EthercatMasterInterface { 00087 friend class EthercatMaster; 00088 friend class YouBotJoint; 00089 friend class YouBotGripper; 00090 friend class YouBotGripperBar; 00091 private: 00092 EthercatMasterWithThread(const std::string& configFile, const std::string& configFilePath); 00093 00094 ~EthercatMasterWithThread(); 00095 00096 00097 public: 00098 bool isThreadActive(); 00099 00100 ///return the quantity of ethercat slave which have an input/output buffer 00101 unsigned int getNumberOfSlaves() const; 00102 00103 void AutomaticSendOn(const bool enableAutomaticSend); 00104 00105 void AutomaticReceiveOn(const bool enableAutomaticReceive); 00106 00107 ///provides all ethercat slave informations from the SOEM driver 00108 ///@param ethercatSlaveInfos ethercat slave informations 00109 void getEthercatDiagnosticInformation(std::vector<ec_slavet>& ethercatSlaveInfos); 00110 00111 ///sends ethercat messages to the motor controllers 00112 /// returns a true if everything it OK and returns false if something fail 00113 bool sendProcessData(); 00114 00115 /// receives ethercat messages from the motor controllers 00116 /// returns a true if everything it OK and returns false if something fail 00117 bool receiveProcessData(); 00118 00119 /// checks if an error has occurred in the soem driver 00120 /// returns a true if an error has occurred 00121 bool isErrorInSoemDriver(); 00122 00123 void registerJointTrajectoryController(JointTrajectoryController* object, const unsigned int JointNumber); 00124 00125 void deleteJointTrajectoryControllerRegistration(const unsigned int JointNumber); 00126 00127 unsigned int getNumberOfThreadCyclesPerSecond(); 00128 00129 bool isEtherCATConnectionEstablished(); 00130 00131 void registerJointLimitMonitor(JointLimitMonitor* object, const unsigned int JointNumber); 00132 00133 void registerDataTrace(void* object, const unsigned int JointNumber); 00134 00135 void deleteDataTraceRegistration(const unsigned int JointNumber); 00136 00137 00138 private: 00139 ///establishes the ethercat connection 00140 void initializeEthercat(); 00141 00142 ///closes the ethercat connection 00143 bool closeEthercat(); 00144 00145 ///stores a ethercat message to the buffer 00146 ///@param msgBuffer ethercat message 00147 ///@param jointNumber joint number of the sender joint 00148 void setMsgBuffer(const YouBotSlaveMsg& msgBuffer, const unsigned int jointNumber); 00149 00150 ///get a ethercat message form the buffer 00151 ///@param msgBuffer ethercat message 00152 ///@param jointNumber joint number of the receiver joint 00153 void getMsgBuffer(const unsigned int jointNumber, YouBotSlaveMsg& returnMsg); 00154 00155 ///stores a mailbox message in a buffer which will be sent to the motor controllers 00156 ///@param msgBuffer ethercat mailbox message 00157 ///@param jointNumber joint number of the sender joint 00158 void setMailboxMsgBuffer(const YouBotSlaveMailboxMsg& msgBuffer, const unsigned int jointNumber); 00159 00160 ///gets a mailbox message form the buffer which came form the motor controllers 00161 ///@param msgBuffer ethercat mailbox message 00162 ///@param jointNumber joint number of the receiver joint 00163 bool getMailboxMsgBuffer(YouBotSlaveMailboxMsg& mailboxMsg, const unsigned int jointNumber); 00164 00165 ///sends the mailbox Messages which have been stored in the buffer 00166 ///@param mailboxMsg ethercat mailbox message 00167 bool sendMailboxMessage(const YouBotSlaveMailboxMsg& mailboxMsg); 00168 00169 ///receives mailbox messages and stores them in the buffer 00170 ///@param mailboxMsg ethercat mailbox message 00171 bool receiveMailboxMessage(YouBotSlaveMailboxMsg& mailboxMsg); 00172 00173 ///sends and receives ethercat messages and mailbox messages to and from the motor controllers 00174 ///this method is executed in a separate thread 00175 void updateSensorActorValues(); 00176 00177 void parseYouBotErrorFlags(const YouBotSlaveMsg& messageBuffer); 00178 00179 std::string ethernetDevice; 00180 00181 char IOmap_[4096]; 00182 00183 ec_mbxbuft mailboxBuffer; 00184 00185 unsigned int nrOfSlaves; 00186 00187 std::vector<SlaveMessageOutput*> ethercatOutputBufferVector; 00188 00189 std::vector<SlaveMessageInput*> ethercatInputBufferVector; 00190 00191 std::vector<YouBotSlaveMsgThreadSafe> slaveMessages; 00192 00193 std::vector<ec_slavet> ethercatSlaveInfo; 00194 00195 unsigned int ethercatTimeout; 00196 00197 //in microseconds 00198 unsigned int timeTillNextEthercatUpdate; 00199 00200 boost::thread_group threads; 00201 00202 volatile bool stopThread; 00203 00204 ec_mbxbuft mailboxBufferSend; 00205 00206 ec_mbxbuft mailboxBufferReceive; 00207 00208 std::vector<YouBotSlaveMsg> automaticSendOffBufferVector; 00209 00210 std::vector<YouBotSlaveMsg> automaticReceiveOffBufferVector; 00211 00212 std::vector<YouBotSlaveMailboxMsgThreadSafe> mailboxMessages; 00213 00214 unsigned int mailboxTimeout; 00215 00216 std::vector<bool> newInputMailboxMsgFlag; 00217 00218 std::vector<bool> outstandingMailboxMsgFlag; 00219 00220 std::vector<bool> pendingMailboxMsgsReply; 00221 00222 ConfigFile* configfile; 00223 00224 static std::string configFileName; 00225 00226 static std::string configFilepath; 00227 00228 bool automaticSendOn; 00229 00230 bool automaticReceiveOn; 00231 00232 bool ethercatConnectionEstablished; 00233 00234 long int communicationErrors; 00235 00236 long int maxCommunicationErrors; 00237 00238 std::vector<JointTrajectoryController*> trajectoryControllers; 00239 00240 boost::mutex trajectoryControllerVectorMutex; 00241 00242 std::vector<JointLimitMonitor*> jointLimitMonitors; 00243 00244 boost::mutex jointLimitMonitorVectorMutex; 00245 00246 std::vector<void*> dataTraces; 00247 00248 boost::mutex dataTracesMutex; 00249 00250 }; 00251 00252 } // namespace youbot 00253 #endif