mavContainer.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * @Brief     Deal with modules message transportation. ROS-free singleton
00003  * @Version   0.3.0
00004  * @Author    Chris Liu
00005  * @Created   2015/12/21
00006  * @Modified  2015/12/22
00007  *****************************************************************************/
00008 
00009 #ifndef _DJI2MAV_MAVCONTAINER_H_
00010 #define _DJI2MAV_MAVCONTAINER_H_
00011 
00012 
00013 #ifndef DEFAULT_RECV_LIST_SIZE
00014 #define DEFAULT_RECV_LIST_SIZE 4
00015 #endif
00016 
00017 #include <mavlink/common/mavlink.h>
00018 #include <new>
00019 #include <string>
00020 #include <cstdarg>
00021 #include <algorithm>
00022 
00023 #include "mavHandler.h"
00024 #include "modules/mavModule.h"
00025 #include "log.h"
00026 
00027 namespace dji2mav{
00028 
00029     class MavContainer{
00030         public:
00036             MavContainer(MavHandler &handler, uint16_t maxModuleNum = 8) {
00037                 DJI2MAV_DEBUG("Going to construct Container with moduleNum " 
00038                         "%u...", maxModuleNum);
00039 
00040                 m_hdlr = &handler;
00041                 m_maxListSize = maxModuleNum;
00042                 m_currListSize = 0;
00043 
00044                 try {
00045                     m_moduleList = new MavModule*[m_maxListSize];
00046                     memset(m_moduleList, 0, m_maxListSize * sizeof(MavModule*));
00047                     m_moduleMOI = new uint8_t*[m_maxListSize];
00048                     memset(m_moduleMOI, 0, m_maxListSize * sizeof(uint8_t*));
00049                 } catch(std::bad_alloc &m) {
00050                     DJI2MAV_FATAL("Fail to allocate memory for moduleList and " 
00051                             "moduleMIO! Exception: %s!", m.what());
00052                     exit(EXIT_FAILURE);
00053                 }
00054 
00055                 DJI2MAV_DEBUG("...finish constructing Container.");
00056             }
00057 
00058 
00059             ~MavContainer() {
00060                 DJI2MAV_DEBUG("Going to destruct Container...");
00061                 if(NULL != m_moduleList) {
00062                     for(uint16_t i = 0; i < m_maxListSize; ++i) {
00063                         if(NULL != m_moduleList[i]) {
00064                             //delete m_moduleList[i];
00065                             m_moduleList[i] = NULL;
00066                         }
00067                     }
00068                     delete []m_moduleList;
00069                     m_moduleList = NULL;
00070                 }
00071                 if(NULL != m_moduleMOI) {
00072                     for(uint16_t i = 0; i < m_maxListSize; ++i) {
00073                         if(NULL != m_moduleMOI[i]) {
00074                             delete m_moduleMOI[i];
00075                             m_moduleMOI[i] = NULL;
00076                         }
00077                     }
00078                     delete []m_moduleMOI;
00079                     m_moduleMOI = NULL;
00080                 }
00081                 DJI2MAV_DEBUG("...finish destructing Container.");
00082             }
00083 
00084 
00092             bool registerModule(MavModule &module, uint16_t size, ...) {
00093                 if(m_currListSize == m_maxListSize) {
00094                     DJI2MAV_ERROR("Fail to register module %s because " 
00095                             "currListSize %u reaches the limit %u!", 
00096                             module.getName().c_str(), m_currListSize, 
00097                             m_maxListSize);
00098                     return false;
00099                 }
00100 
00101                 /*if(size >= 64) {
00102                     DJI2MAV_WARN("The size %u of MOI seems too long. This " 
00103                             "affects the performance of the program.", size);
00104                 }*/
00105 
00106                 try {
00107                     //one more element for storing the list size
00108                     m_moduleMOI[m_currListSize] = new uint8_t[size + 1];
00109                     memset( m_moduleMOI[m_currListSize], 0, 
00110                             (size + 1) * sizeof(uint8_t) );
00111                 } catch(std::bad_alloc &m) {
00112                     DJI2MAV_FATAL( "Fail to allocate memory for moduleMOI! " 
00113                             "Exception: %s!", m.what() );
00114                     exit(EXIT_FAILURE);
00115                 }
00116                 //first position is used to store the size
00117                 m_moduleMOI[m_currListSize][0] = size;
00118 
00119                 va_list arg;
00120                 va_start(arg, size);
00121 
00122                 m_moduleList[m_currListSize] = &module;
00123                 for(uint16_t i = 1; i <= size; ++i) {
00124                     uint8_t msgid = (uint8_t)va_arg(arg, int);
00125                     m_moduleMOI[m_currListSize][i] = msgid;
00126                     DJI2MAV_DEBUG( "Add msgid #%u to MOI of module %s.", msgid, 
00127                             module.getName().c_str() );
00128                 }
00129                 std::sort( m_moduleMOI[m_currListSize] + 1, 
00130                         m_moduleMOI[m_currListSize] + size + 1 );
00131 
00132                 ++m_currListSize;
00133                 va_end(arg);
00134                 DJI2MAV_INFO( "Succeed in registering module %s.", 
00135                         module.getName().c_str() );
00136                 return true;
00137             }
00138 
00139 
00145             int getModuleIdx(std::string moduleName) {
00146                 for(uint16_t i = 0; i < m_currListSize; ++i) {
00147                     if( moduleName == m_moduleList[i]->getName() ) {
00148                         return i;
00149                     }
00150                 }
00151                 DJI2MAV_ERROR( "No module is named %s!", moduleName.c_str() );
00152                 return -1;
00153             }
00154 
00155 
00162             bool hasMOI(uint16_t moduleIdx, uint8_t msgid) {
00163                 if(moduleIdx >= m_currListSize) {
00164                     DJI2MAV_ERROR("The index of module %u exceeds the current " 
00165                             "list size %u!", moduleIdx, m_currListSize);
00166                     return false;
00167                 }
00168 
00169                 //binary search
00170                 uint8_t *begin = m_moduleMOI[moduleIdx] + 1;
00171                 uint8_t *end = m_moduleMOI[moduleIdx] + 
00172                         m_moduleMOI[moduleIdx][0] + 1;
00173                 uint8_t *mid;
00174                 while(begin <= end) {
00175                     mid = begin + (end - begin) / 2;
00176                     if(msgid < *mid)
00177                         end = mid - 1;
00178                     else if(msgid > *mid)
00179                         begin = mid +1;
00180                     else
00181                         return true;
00182                 }
00183 
00184                 DJI2MAV_TRACE( "Cannot find out msgid %u in module %s.", msgid, 
00185                         m_moduleList[moduleIdx]->getName().c_str() );
00186                 return false;
00187             }
00188 
00189 
00196             bool hasMOI(std::string moduleName, uint8_t msgid) {
00197                 int idx = getModuleIdx(moduleName);
00198                 if(-1 == idx) {
00199                     DJI2MAV_ERROR( "Fail to execute MOI check process because " 
00200                             "module name %s does not exist!", 
00201                             moduleName.c_str() );
00202                     return false;
00203                 }
00204                 return hasMOI( (uint16_t)idx, msgid );
00205             }
00206 
00207 
00216             inline int fetchMsgFromMng(uint16_t mngIdx, 
00217                     mavlink_message_t* recvMsgList, 
00218                     mavlink_status_t* recvStatusList, uint16_t listSize) {
00219 
00220                 return m_hdlr->recvFromMng(mngIdx, recvMsgList, recvStatusList, 
00221                         listSize);
00222 
00223             }
00224 
00225 
00233             inline int fetchMsgFromAll(mavlink_message_t* recvMsgList, 
00234                     mavlink_status_t* recvStatusList, uint16_t listSize) {
00235 
00236                 return m_hdlr->recvFromAll(recvMsgList, recvStatusList, 
00237                         listSize);
00238 
00239             }
00240 
00241 
00248             bool deliverMsg(uint16_t moduleIdx, 
00249                     const mavlink_message_t &msg) {
00250 
00251                 if( hasMOI(moduleIdx, msg.msgid) ) {
00252                     m_moduleList[moduleIdx]->pushMsg(moduleIdx, msg);
00253                     return true;
00254                 }
00255                 DJI2MAV_TRACE( "Fail to deliver message to module %s!", 
00256                         m_moduleList[moduleIdx]->getName().c_str() );
00257                 return false;
00258 
00259             }
00260 
00261 
00268             bool deliverMsg(std::string moduleName, 
00269                     const mavlink_message_t &msg) {
00270 
00271                 int idx = getModuleIdx(moduleName);
00272                 if(-1 == idx) {
00273                     DJI2MAV_ERROR( "Module name %s is not matched!", 
00274                             moduleName.c_str() );
00275                     return false;
00276                 }
00277                 if( hasMOI(idx, msg.msgid) ) {
00278                     m_moduleList[idx]->pushMsg(idx, msg);
00279                     return true;
00280                 }
00281                 return false;
00282 
00283             }
00284 
00285 
00291             bool deliverMsgToAll(const mavlink_message_t &msg) {
00292                 bool ret = true;
00293                 for(uint8_t i = 0; i < m_currListSize; ++i) {
00294                     if(NULL != m_moduleList[i] && !deliverMsg(i, msg)) {
00295                         DJI2MAV_ERROR( "Fail to deliver message to module %s!", 
00296                                 m_moduleList[i]->getName().c_str() );
00297                         ret = false;
00298                     }
00299                 }
00300                 if(!ret)
00301                     DJI2MAV_ERROR("Fail to deliver message to some module!");
00302                 return ret;
00303             }
00304 
00305 
00310             static void* thread_call(void* param) {
00311                 ( (MavContainer*)param )->deliverHelper();
00312             }
00313 
00314 
00318             void deliverHelper() {
00319                 mavlink_message_t recvMsgList[DEFAULT_RECV_LIST_SIZE];
00320                 mavlink_status_t recvStatusList[DEFAULT_RECV_LIST_SIZE];
00321                 while(true) {
00322                     for(uint16_t i = 0; i < m_hdlr->getMaxListSize(); ++i) {
00323                         int msgCnt = fetchMsgFromMng(i, recvMsgList, 
00324                                 recvStatusList, DEFAULT_RECV_LIST_SIZE);
00325                         for(uint16_t j = 0; j < msgCnt; ++j) {
00326                             for(uint16_t k = 0; k < m_currListSize; ++k) {
00327                                 deliverMsg(k, recvMsgList[j]);
00328                             }
00329                         }
00330                     }
00331                 }
00332             }
00333 
00334 
00339             bool run() {
00340                 int ret = pthread_create( &m_tid, NULL, thread_call, 
00341                         (void*)this );
00342                 if(0 != ret) {
00343                     DJI2MAV_FATAL("Fail to create thread for the Container!");
00344                     //TODO: should exit and return tid?
00345                     return false;
00346                 }
00347 
00348                 for(uint16_t i = 0; i < m_currListSize; ++i) {
00349                     ret &= m_moduleList[i]->run();
00350                 }
00351                 return ret;
00352             }
00353 
00354 
00355         private:
00356             MavHandler* m_hdlr;
00357 
00358             MavModule** m_moduleList;
00359             uint8_t** m_moduleMOI;
00360             uint16_t m_maxListSize;
00361             uint16_t m_currListSize;
00362 
00363             pthread_t m_tid;
00364 
00365 
00366     };
00367 
00368 } //namespace dji2mav
00369 
00370 
00371 #endif


dji_sdk_dji2mav
Author(s):
autogenerated on Thu Jun 6 2019 17:55:34