RelayBoardV2.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2015, Neobotix GmbH
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Neobotix nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 
00036 #include <stdio.h>
00037 #include <math.h>
00038 #include <ros/ros.h>
00039 #include "../include/RelayBoardV2.h"
00040 
00041 
00042 //-----------------------------------------------
00043 
00044 
00045 
00046 #define RS422_BAUDRATE 420000
00047 
00048 #define RS422_TIMEOUT 0.025
00049 
00050 
00051 RelayBoardV2::RelayBoardV2()
00052 {
00053         m_iNumBytesSend = 0;
00054         m_iNumBytesRec = 0;
00055         m_ihasRelayData = 0;
00056         m_ihas_LCD_DATA = 0;
00057         m_iHasIOBoard = 0;
00058         m_iHasUSBoard = 0;
00059         m_iHasSpeakerData = 0;
00060         m_iChargeState = 0;
00061 
00062         
00063 
00064         m_REC_MSG.iRelayBoard_Status = 0;
00065         m_REC_MSG.iCharging_Current = 0;
00066         m_REC_MSG.iCharging_State = 0;
00067         m_REC_MSG.iBattery_Voltage = 0;
00068         m_REC_MSG.iKey_Pad = 0;
00069         m_REC_MSG.iTemp_Sensor = 0;
00070         m_REC_MSG.iIODig_In = 0;
00071         m_REC_MSG.iIOBoard_State = 0;
00072         m_REC_MSG.iUSBoard_State = 0;
00073 
00074         for(int a = 0; a<8;a++)
00075         {
00076                 m_Motor[a].lEnc = 0;
00077                 m_Motor[a].lEncS = 0;
00078                 m_Motor[a].iStatus = 0;
00079                 m_Motor[a].ldesiredEncS = 0;
00080         }
00081 
00082         m_S_MSG.iSoftEM = 0;
00083         m_S_MSG.iCmdRelayBoard = 0;
00084         m_S_MSG.IOBoard_Cmd = 0;
00085         m_S_MSG.USBoard_Cmd = 0;
00086         m_S_MSG.Speaker = 0;
00087         m_S_MSG.SpeakerLoud = 0;
00088 
00089         m_blogging = false;
00090 
00091         ROS_INFO("Starting RelayBoardV2 Node\n");
00092 
00093 }
00094 //-----------------------------------------------
00095 RelayBoardV2::~RelayBoardV2()
00096 {
00097         m_SerIO.closeIO();
00098 }
00099 //----------------------------------------------
00100 int RelayBoardV2::evalRxBuffer()
00101 {
00102         int errorFlag = NO_ERROR;
00103 
00104         bool found_header = false;
00105         int waiting_cnt = 0;
00106         int waiting_cnt2 = 0;
00107         int msg_type = 100;
00108         int error_cnt = 0;
00109         int no_data_cnt = 0;
00110         int BytesToRead = 0;
00111         int received_checksum = 0;
00112         int my_checksum = 0;
00113         const int c_iSizeBuffer = 130;//4096;
00114         int iNrBytesRead = 0;
00115         unsigned char cDat[c_iSizeBuffer];
00116         unsigned char cHeader[4] = {0x00, 0x00, 0x00, 0x00};
00117         //ROS_INFO("EVAL RX");
00118         while(found_header == false)
00119         {
00120                 if(m_SerIO.getSizeRXQueue() >= 1)
00121                 {
00122                         waiting_cnt = 0;
00123                         //Read Header
00124                         cHeader[3] = cHeader[2];
00125                         cHeader[2] = cHeader[1];
00126                         cHeader[1] = cHeader[0];
00127                         iNrBytesRead = m_SerIO.readBlocking((char*)&cHeader[0], 1);
00128 
00129                         if((cHeader[3] == 0x08) && (cHeader[2] == 0xFE) && (cHeader[1] == 0xEF) && (cHeader[0] == 0x08))
00130                         {
00131                                 //Update Msg
00132                                 msg_type = 1;
00133                                 found_header = true;
00134                         }
00135                         else if((cHeader[3] == 0x02) && (cHeader[2] == 0x80) && (cHeader[1] == 0xD6) && (cHeader[0] == 0x02))
00136                         {
00137                                 //Config Msg
00138                                 msg_type = 2;
00139                                 found_header = true;
00140                         }
00141                         else if((cHeader[3] == 0x02) && (cHeader[2] == 0xFF) && (cHeader[1] == 0xD6) && (cHeader[0] == 0x02))
00142                         {
00143                                 //Error Msg
00144                                 ROS_INFO("Error Msg");
00145                                 msg_type = 3;
00146                                 found_header = true;
00147                         }
00148                         if(++error_cnt > 20)
00149                         {
00150                                 //No Header in first 20 Bytes -> Error
00151                                 //flush input
00152                                 return 99;
00153                         }
00154 
00155                 }
00156                 else
00157                 {
00158                         waiting_cnt++;
00159                         if(waiting_cnt > 60000)
00160                         {
00161                                 waiting_cnt = 0;
00162                                 waiting_cnt2++;
00163                                 if(waiting_cnt2 > 10)
00164                                 {
00165                                         //resend
00166                                         return 101;
00167                                 } 
00168                         }
00169                 }
00170         }
00171         switch(msg_type)
00172         {
00173                 case 1: BytesToRead = m_iNumBytesRec - 4;
00174                                 break;
00175                 case 2: BytesToRead = 6;
00176                                 break;
00177                 case 3: BytesToRead = 3;
00178                                 break;
00179                 default: return 98;
00180         }
00181         error_cnt = 0;
00182         while(m_SerIO.getSizeRXQueue() < BytesToRead)
00183         {
00184                 usleep(2000);
00185         }
00186         iNrBytesRead = m_SerIO.readBlocking((char*)&cDat[0], BytesToRead);
00187 
00188         if(m_blogging == true)
00189         {
00190                 log_to_file(2, cDat); //direction 1 = transmitted; 2 = recived
00191         }
00192         //Calc Checksum
00193         my_checksum += cHeader[3];
00194         my_checksum %= 0xFF00;
00195         my_checksum += cHeader[2];
00196         my_checksum %= 0xFF00;
00197         my_checksum += cHeader[1];
00198         my_checksum %= 0xFF00;
00199         my_checksum += cHeader[0];
00200         for(int e = 0; e < iNrBytesRead - 2; e++)
00201         {
00202                 my_checksum %= 0xFF00;
00203                 my_checksum += cDat[e];
00204         }
00205         //received checksum
00206         received_checksum = (cDat[BytesToRead - 1] << 8);
00207         received_checksum += cDat[BytesToRead - 2];
00208         //ROS_INFO("Fast Fertig Eval RX");
00209         if(received_checksum != my_checksum)
00210         {
00211                 //Wrong Checksum
00212                 return 97;
00213         }
00214         if(msg_type == 1)
00215         {
00216                 convRecMsgToData(&cDat[0]);
00217                 return 0;
00218         }
00219         else if(msg_type == 2)
00220         {
00221                 m_iFoundMotors = cDat[0];
00222                 m_iHomedMotors = cDat[1];
00223                 m_iFoundExtHardware = cDat[2];
00224                 m_iConfigured = cDat[3];
00225                 //ROS_INFO("Found Motors: %d",cDat[0]);
00226                 //ROS_INFO("Homed Motors: %d",cDat[1]);
00227                 //ROS_INFO("Ext Hardware: %d",cDat[2]);
00228                 //ROS_INFO("Configuriert: %d",cDat[3]);
00229                 return 1;
00230         }
00231         else if(msg_type == 3)
00232         {
00233                 
00234                 return 2;
00235         }
00236         else
00237         {
00238                 return 100;
00239         }
00240 
00241         return 0;
00242 }
00243 //----------------------------------Configuration--------------------------------------
00244 int RelayBoardV2::init(const char* cdevice_name, int iactive_motors, int ihoming_motors, int iext_hardware, long lModulo0, long lModulo1, long lModulo2, long lModulo3, long lModulo4, long lModulo5, long lModulo6, long lModulo7)
00245 {
00246         m_SerIO.setDeviceName(cdevice_name);
00247         m_SerIO.setBaudRate(RS422_BAUDRATE);
00248         m_SerIO.openIO();
00249         unsigned char cConfig_Data[33]; //4 Byte Header 3 Config Bytes 24 Byte Modulo 2 Byte Checksum
00250         int iChkSum = 0;
00251         int byteswritten = 0;
00252         int answertype = 0;
00253         int iNumDrives = 0;
00254         //Header
00255         cConfig_Data[0] = 0x02;
00256         cConfig_Data[1] = 0x80;
00257         cConfig_Data[2] = 0xD6;
00258         cConfig_Data[3] = 0x02;
00259         //-------------configuration Bytes-----------------------------------
00260         cConfig_Data[4] = iactive_motors;
00261         cConfig_Data[5] = ihoming_motors;
00262         cConfig_Data[6] = iext_hardware;
00263 
00264         //-------------set motors active-------------------------------------
00265         if((iactive_motors & 0x80) == 0x80) m_Motor[7].iMotorActive = 1;
00266         else m_Motor[7].iMotorActive = 0;
00267         if((iactive_motors & 0x40) == 0x40) m_Motor[6].iMotorActive = 1;
00268         else m_Motor[6].iMotorActive = 0;
00269         if((iactive_motors & 0x20) == 0x20) m_Motor[5].iMotorActive = 1;
00270         else m_Motor[5].iMotorActive = 0;
00271         if((iactive_motors & 0x10) == 0x10) m_Motor[4].iMotorActive = 1;
00272         else m_Motor[4].iMotorActive = 0;
00273         if((iactive_motors & 0x8) == 0x8) m_Motor[3].iMotorActive = 1;
00274         else m_Motor[3].iMotorActive = 0;
00275         if((iactive_motors & 0x4) == 0x4) m_Motor[2].iMotorActive = 1;
00276         else m_Motor[2].iMotorActive = 0;
00277         if((iactive_motors & 0x2) == 0x2) m_Motor[1].iMotorActive = 1;
00278         else m_Motor[1].iMotorActive = 0;
00279         if((iactive_motors & 0x1) == 0x1) m_Motor[0].iMotorActive = 1;
00280         else m_Motor[0].iMotorActive = 0;
00281         //---------------Modulo for all Motors-------------------------------
00282         //Motor1
00283         cConfig_Data[7] = lModulo0 >> 16;
00284         cConfig_Data[8] = lModulo0 >> 8;
00285         cConfig_Data[9] = lModulo0;
00286         //Motor2
00287         cConfig_Data[10] = lModulo1 >> 16;
00288         cConfig_Data[11] = lModulo1 >> 8;
00289         cConfig_Data[12] = lModulo1;
00290         //Motor3
00291         cConfig_Data[13] = lModulo2 >> 16;
00292         cConfig_Data[14] = lModulo2 >> 8;
00293         cConfig_Data[15] = lModulo2;
00294         //Motor4
00295         cConfig_Data[16] = lModulo3 >> 16;
00296         cConfig_Data[17] = lModulo3 >> 8;
00297         cConfig_Data[18] = lModulo3;
00298         //Motor5
00299         cConfig_Data[19] = lModulo4 >> 16;
00300         cConfig_Data[20] = lModulo4 >> 8;
00301         cConfig_Data[21] = lModulo4;
00302         //Motor6
00303         cConfig_Data[22] = lModulo5 >> 16;
00304         cConfig_Data[23] = lModulo5 >> 8;
00305         cConfig_Data[24] = lModulo5;
00306         //Motor7
00307         cConfig_Data[25] = lModulo6 >> 16;
00308         cConfig_Data[26] = lModulo6 >> 8;
00309         cConfig_Data[27] = lModulo6;
00310         //Motor8
00311         cConfig_Data[28] = lModulo7 >> 16;
00312         cConfig_Data[29] = lModulo7 >> 8;
00313         cConfig_Data[30] = lModulo7;
00314 
00315         //-----------------Calc m_iNumBytesRec-----------------------------
00316         m_iNumBytesRec = 4; //4Byte Header
00317         m_iNumBytesRec += 13; //11Byte ActRelayboardConfig, State, Charging Current, Charging State, Batt Voltage, Keypad, Temp
00318         for(int g = 0; g < 8;g++)
00319         {
00320                 if(m_Motor[g].iMotorActive == 1)
00321                 {
00322                         iNumDrives++;
00323                 }
00324         }
00325         //ROS_INFO("Number of Drives %i",iNumDrives);
00326         m_iNumBytesRec += (iNumDrives*10); //10 Byte pro active Motor
00327 
00328         if((iext_hardware & 1) == 1) //IOBoard
00329         {
00330                 m_iNumBytesRec += 20;
00331         }
00332         if((iext_hardware & 2) == 1) //USBoard
00333         {
00334                 m_iNumBytesRec += 26;
00335         }
00336 
00337         m_iNumBytesRec += 2; //2Byte Checksum
00338         //ROS_INFO("iNumBytesRec: %d",m_iNumBytesRec);
00339         //----------------Calc Checksum-------------------------------------
00340         for(int i=4;i<=30;i++)    //i=4 => Header not added to Checksum
00341         {
00342                 iChkSum %= 0xFF00;
00343                 iChkSum += cConfig_Data[i];
00344         }
00345         //----------------END Calc Checksum---------------------------------
00346 
00347         //----------------Add Checksum to Data------------------------------
00348         cConfig_Data[31] = iChkSum >> 8;
00349         cConfig_Data[32] = iChkSum;
00350         //------------END Add Checksum to Data------------------------------
00351         if(m_blogging == true)
00352         {
00353                 log_to_file(3, cConfig_Data); //direction 1 = transmitted; 2 = recived ; 3 = config
00354         }
00355         byteswritten = m_SerIO.writeIO((char*)cConfig_Data,33);
00356         if(byteswritten != 33)
00357         {
00358                 //ROS_ERROR("FAILED: Could not write data to serial port!");
00359                 return 60;
00360         }
00361         else
00362         {
00363                 //ROS_INFO("Waiting for RelayBoard....");
00364         }
00365 
00366         answertype = evalRxBuffer();
00367         if(answertype == 1)
00368         {
00369                 //Check received Data
00370                 if(m_iConfigured == 1)
00371                 {
00372                         ROS_INFO("Configured");
00373                         return 1;
00374                 }
00375                 else
00376                 {
00377                         ROS_ERROR("FAILED: Invalid configuration");
00378                         return 59;
00379                 }
00380 
00381         }
00382         
00383         return 50;
00384         
00385 
00386 }
00387 //-----------------------------------------------
00388 bool RelayBoardV2::shutdownPltf()
00389 {
00390         m_SerIO.closeIO();
00391         return true;
00392 }
00393 //-----------------------------------------------
00394 bool RelayBoardV2::isEMStop()
00395 {
00396         if( (m_REC_MSG.iRelayBoard_Status & 0x0001) != 0)
00397         {
00398                 return true;
00399         }
00400         else
00401         {
00402                 return false;
00403         }
00404 }
00405 //-----------------------------------------------
00406 void RelayBoardV2::setEMStop()
00407 {               
00408         m_S_MSG.iSoftEM |= 0x01;
00409         ROS_ERROR("Software Emergency Stop AKTIVE");
00410 }
00411 
00412 //-----------------------------------------------
00413 void RelayBoardV2::resetEMStop()
00414 {       
00415         m_S_MSG.iSoftEM |= 0x02;
00416         ROS_ERROR("Software Emergency Stop INAKTIVE");
00417 }
00418 //-----------------------------------------------
00419 bool RelayBoardV2::isScannerStop()
00420 {
00421         if( (m_REC_MSG.iRelayBoard_Status & 0x0002) != 0)
00422         {
00423                 return true;
00424         }
00425         else
00426         {
00427                 return false;
00428         }
00429 }
00430 //-------------------------------------------------
00431 int RelayBoardV2::sendDataToRelayBoard()
00432 {
00433 
00434         int errorFlag = NO_ERROR;
00435         int iNrBytesWritten;
00436 
00437         unsigned char cMsg[80];
00438 
00439         m_Mutex.lock();
00440         //ROS_INFO("Converting...");
00441         m_iNumBytesSend = convDataToSendMsg(cMsg);
00442         //ROS_INFO("Fin");      
00443         m_SerIO.purgeTx();
00444         iNrBytesWritten = m_SerIO.writeIO((char*)cMsg,m_iNumBytesSend);
00445 
00446         if(iNrBytesWritten < m_iNumBytesSend) {
00447                 //errorFlag = GENERAL_SENDING_ERROR;
00448                 //ROS_ERROR("ZU wenig gesendet!");
00449         }
00450         //log
00451         if(m_blogging == true)
00452         {
00453                 log_to_file(1, cMsg); //direction 1 = transmitted; 2 = recived
00454         }
00455         //m_LastTime = ros::Time::now();
00456         m_Mutex.unlock();
00457         return errorFlag;
00458 
00459 };
00460 //---------------------------------------------------------------------------------------------------------------------
00461 // MotorCtrl
00462 //---------------------------------------------------------------------------------------------------------------------
00463 void RelayBoardV2::setMotorDesiredEncS(int imotor_nr, long lEncS)
00464 {               
00465         m_Mutex.lock();
00466         
00467         m_Motor[imotor_nr].ldesiredEncS = lEncS;
00468 
00469         m_Mutex.unlock();
00470 }
00471 //-------------------------------------------------------------
00472 void RelayBoardV2::getMotorEnc(int imotor_nr,long* lmotorEnc)
00473 {
00474         m_Mutex.lock();
00475         
00476         *lmotorEnc = m_Motor[imotor_nr].lEnc;
00477         
00478         m_Mutex.unlock();
00479 
00480 }
00481 //-------------------------------------------------------------
00482 void RelayBoardV2::getMotorEncS(int imotor_nr,long* lmotorEncS)
00483 {
00484         m_Mutex.lock();
00485         
00486         *lmotorEncS = m_Motor[imotor_nr].lEncS;
00487 
00488         m_Mutex.unlock();
00489 }
00490 //-------------------------------------------------------------
00491 void RelayBoardV2::getMotorState(int imotor_nr,int* imotorStatus)
00492 {
00493         m_Mutex.lock();
00494         
00495         *imotorStatus = m_Motor[imotor_nr].iStatus;
00496 
00497         m_Mutex.unlock();
00498 }
00499 //---------------------------------------------------------------------------------------------------------------------
00500 // RelayBoard
00501 //---------------------------------------------------------------------------------------------------------------------
00502 void RelayBoardV2::getRelayBoardState(int* State)
00503 {
00504         m_Mutex.lock();
00505         *State = m_REC_MSG.iRelayBoard_Status;
00506         m_Mutex.unlock();
00507 }
00508 //-------------------------------------------------------
00509 void RelayBoardV2::getRelayBoardDigOut(int* DigOut)
00510 {
00511         m_Mutex.lock();
00512         *DigOut = m_S_MSG.iCmdRelayBoard;
00513         m_Mutex.unlock();
00514 }
00515 //-------------------------------------------------------
00516 void RelayBoardV2::setRelayBoardDigOut(int iChannel, bool bOn)
00517 {
00518 
00519       /*Bit 4: Relais 1 schalten
00520         Bit 5: Relais 2 schalten
00521         Bit 6: Relais 3 schalten
00522         Bit 7: Relais 4 schalten*/
00523         m_ihasRelayData = 1;
00524         switch( iChannel)
00525         {
00526         case 1:
00527 
00528                 if(bOn) { m_S_MSG.iCmdRelayBoard |= 8; }
00529                 else { m_S_MSG.iCmdRelayBoard &= ~ 8; }
00530                 
00531                 break;
00532 
00533         case 2:
00534 
00535                 if(bOn) { m_S_MSG.iCmdRelayBoard |= 16; }
00536                 else { m_S_MSG.iCmdRelayBoard &= ~ 16; }
00537 
00538                 break;
00539 
00540         case 3:
00541 
00542                 if(bOn) { m_S_MSG.iCmdRelayBoard |= 32; }
00543                 else { m_S_MSG.iCmdRelayBoard &= ~ 32; }
00544 
00545                 break;
00546 
00547         case 4:
00548 
00549                 if(bOn) { m_S_MSG.iCmdRelayBoard |= 64; }
00550                 else { m_S_MSG.iCmdRelayBoard &= ~ 64; }
00551 
00552                 break;
00553 
00554         default:
00555 
00556                 m_S_MSG.iCmdRelayBoard = 0;
00557         }
00558 }
00559 //-------------------------------------------------------
00560 void RelayBoardV2::getTemperature(int* temp)
00561 {
00562         m_Mutex.lock();
00563 
00564         *temp = m_REC_MSG.iTemp_Sensor;
00565 
00566         m_Mutex.unlock();
00567 }
00568 //-------------------------------------------------------
00569 void RelayBoardV2::getBattVoltage(int* battvolt)
00570 {
00571         m_Mutex.lock();
00572 
00573         *battvolt = m_REC_MSG.iBattery_Voltage;
00574 
00575         m_Mutex.unlock();
00576 }
00577 //-------------------------------------------------------
00578 void RelayBoardV2::getChargingCurrent(int* current)
00579 {
00580         m_Mutex.lock();
00581 
00582         *current = m_REC_MSG.iCharging_Current;
00583 
00584         m_Mutex.unlock();
00585 }
00586 //-------------------------------------------------------
00587 void RelayBoardV2::getChargingState(int* state)
00588 {
00589         m_Mutex.lock();
00590 
00591         *state = m_REC_MSG.iCharging_State;
00592 
00593         m_Mutex.unlock();
00594 }
00595 //-----------------------------------------------
00596 void RelayBoardV2::writeLCD(const std::string& sText)
00597 {
00598         int iSize;
00599         m_ihas_LCD_DATA = 1;
00600         m_Mutex.lock();
00601 
00602         iSize = sText.size();
00603         
00604         for(int i = 0; i < 20; i++)
00605         {
00606                 if(i < iSize)
00607                 {
00608                         m_S_MSG.LCD_Txt[i] = sText[i];
00609                 }
00610                 else
00611                 {
00612                         m_S_MSG.LCD_Txt[i] = ' ';
00613                 }
00614         }
00615         m_Mutex.unlock();
00616 }
00617 //-------------------------------------------------------
00618 void RelayBoardV2::getKeyPad(int* keypad)
00619 {
00620         m_Mutex.lock();
00621         *keypad = m_REC_MSG.iKey_Pad;
00622         m_Mutex.unlock();
00623 }
00624 //-------------------------------------------------------
00625 void RelayBoardV2::startCharging()
00626 {
00627         m_Mutex.lock();
00628         m_ihasRelayData = 1;
00629         m_S_MSG.iCmdRelayBoard |= 1;
00630         m_Mutex.unlock();
00631 }
00632 //-----------------------------------------------
00633 void RelayBoardV2::stopCharging()
00634 {
00635         m_Mutex.lock();
00636         m_ihasRelayData = 1;
00637         m_S_MSG.iCmdRelayBoard &= ~ 1;
00638         m_Mutex.unlock();
00639 }
00640 //-----------------------------------------------
00641 // IOBoard
00642 //-----------------------------------------------
00643 void RelayBoardV2::getIOBoardDigIn(int* DigIn)
00644 {
00645         m_Mutex.lock();
00646         *DigIn = m_REC_MSG.iIODig_In;
00647         m_Mutex.unlock();
00648 }
00649 //-----------------------------------------------
00650 void RelayBoardV2::getIOBoardDigOut(int* DigOut)
00651 {
00652         m_Mutex.lock();
00653         *DigOut = m_S_MSG.IOBoard_Cmd;
00654         m_Mutex.unlock();
00655 }
00656 //-----------------------------------------------
00657 void RelayBoardV2::setIOBoardDigOut(int iChannel, bool bVal)
00658 {
00659         m_iHasIOBoard = 1;
00660         int iMask;
00661 
00662         iMask = (1 << iChannel);
00663         
00664         if(bVal)
00665         {
00666                 m_S_MSG.IOBoard_Cmd |= iMask;
00667         }
00668         else
00669         {
00670                 m_S_MSG.IOBoard_Cmd &= ~iMask;
00671         }       
00672 }
00673 //-----------------------------------------------
00674 void RelayBoardV2::getIOBoardAnalogIn(int* iAnalogIn)
00675 {
00676         int i;
00677 
00678         m_Mutex.lock();
00679 
00680         for(i = 0; i < 8; i++)
00681         {
00682                 iAnalogIn[i] = m_REC_MSG.iIOAnalog_In[i];
00683         }
00684 
00685         m_Mutex.unlock();
00686 }
00687 //---------------------------------------------------------------------------------------------------------------------
00688 // USBoard
00689 //---------------------------------------------------------------------------------------------------------------------
00690 void RelayBoardV2::startUSBoard(int iChannelActive)
00691 {
00692         m_Mutex.lock();
00693         m_iHasUSBoard = 1;
00694         m_S_MSG.USBoard_Cmd = iChannelActive;
00695         m_Mutex.unlock();
00696 }
00697 //-----------------------------------------------
00698 void RelayBoardV2::stopUSBoard()
00699 {
00700         m_Mutex.lock();
00701         m_iHasUSBoard = 1;
00702         m_S_MSG.USBoard_Cmd = 0x00;
00703         m_Mutex.unlock();
00704 }
00705 //-----------------------------------------------
00706 void RelayBoardV2::getUSBoardData1To8(int* piUSDistMM)
00707 {
00708         int i;
00709 
00710         m_Mutex.lock();
00711         
00712         for(i = 0; i < 8; i++)
00713         {
00714                 piUSDistMM[i] = 10 * m_REC_MSG.iUSSensor_Dist[i];
00715         }
00716 
00717         m_Mutex.unlock();
00718 }
00719 //-----------------------------------------------
00720 void RelayBoardV2::getUSBoardData9To16(int* piUSDistMM)
00721 {
00722         int i;
00723 
00724         m_Mutex.lock();
00725 
00726         for(i = 0; i < 8; i++)
00727         {
00728                 piUSDistMM[i] = 10 * m_REC_MSG.iUSSensor_Dist[i + 8];
00729         }
00730 
00731         m_Mutex.unlock();
00732 }
00733 //-----------------------------------------------
00734 void RelayBoardV2::getUSBoardAnalogIn(int* piAnalogIn)
00735 {
00736         int i;
00737 
00738         m_Mutex.lock();
00739 
00740         for(i = 0; i < 4; i++)
00741         {
00742                 piAnalogIn[i] = m_REC_MSG.iUSAnalog_In[i];
00743         }
00744 
00745         m_Mutex.unlock();
00746 }
00747 //---------------------------------------------------------------------------------------------------------------------
00748 //Logging
00749 //---------------------------------------------------------------------------------------------------------------------
00750 void RelayBoardV2::enable_logging()
00751 {
00752         m_blogging = true;
00753 }
00754 //-----------------------------------------------
00755 void RelayBoardV2::disable_logging()
00756 {
00757         m_blogging = false;
00758 }
00759 //-----------------------------------------------
00760 void RelayBoardV2::log_to_file(int direction, unsigned char cMsg[])
00761 {
00762         FILE * pFile;
00763         //Open Logfile
00764         pFile = fopen ("neo_relayboard_RX_TX_log.log","a");
00765         //Write Data to Logfile
00766         if(direction == 1)
00767         {
00768                 fprintf (pFile, "\n\n Direction: %i", direction);
00769                 for(int i=0; i<m_iNumBytesSend; i++)
00770                         fprintf(pFile," %.2x", cMsg[i]);
00771                 fprintf(pFile,"\n");
00772         }
00773         if(direction == 2)
00774         {
00775                 fprintf (pFile, "\n\n Direction: %i", direction);
00776                 for(int i=0; i<(m_iNumBytesRec + 2); i++)
00777                         fprintf(pFile," %.2x", cMsg[i]);
00778                 fprintf(pFile,"\n");
00779         }
00780         if(direction == 3)
00781         {
00782                 fprintf (pFile, "\n\n Direction: %i", direction);
00783                 for(int i=0; i<(33); i++)
00784                         fprintf(pFile," %.2x", cMsg[i]);
00785                 fprintf(pFile,"\n");
00786         }
00787         //Close Logfile
00788         fclose (pFile);
00789 }
00790 //---------------------------------------------------------------------------------------------------------------------
00791 //Data Converter
00792 //---------------------------------------------------------------------------------------------------------------------
00793 void RelayBoardV2::convRecMsgToData(unsigned char cMsg[])
00794 {
00795         //ROS_INFO("Convert Rec to Data");
00796         int data_in_message = 0;
00797 
00798         m_Mutex.lock();
00799 
00800         // convert data
00801         int iCnt = 0;
00802 
00803         //Has Data
00804         data_in_message = cMsg[iCnt];
00805         iCnt++;
00806         //Relayboard Status
00807         m_REC_MSG.iRelayBoard_Status = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00808         iCnt += 2;
00809         //Charging Current
00810         m_REC_MSG.iCharging_Current = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00811         iCnt += 2;
00812         //Charging State
00813         m_REC_MSG.iCharging_State = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00814         iCnt += 2;
00815         //Battery Voltage
00816         m_REC_MSG.iBattery_Voltage = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00817         iCnt += 2;
00818         //Keypad
00819         m_REC_MSG.iKey_Pad = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00820         iCnt += 2;
00821         //Temp Sensor
00822         m_REC_MSG.iTemp_Sensor = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00823         iCnt += 2;
00824 
00825         // IOBoard
00826         if(m_iFoundExtHardware & 1 == 1)
00827         {
00828                 m_REC_MSG.iIODig_In = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00829                 iCnt += 2;
00830                 for(int i = 0; i < 8; i++)
00831                 {
00832                         m_REC_MSG.iIOAnalog_In[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00833                         iCnt += 2;
00834                 }
00835 
00836                 m_REC_MSG.iIOBoard_State =  (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00837                 iCnt += 2;
00838         }
00839         // USBoard
00840         if(m_iFoundExtHardware & 2 == 1)
00841         {
00842                 for(int i = 0; i < 16; i++)
00843                 {
00844                         m_REC_MSG.iUSSensor_Dist[i] = (cMsg[iCnt++]);
00845                 }
00846                 for(int i = 0; i < 4; i++)
00847                 {
00848                         m_REC_MSG.iUSAnalog_In[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00849                         iCnt += 2;
00850                 }
00851 
00852                 m_REC_MSG.iUSBoard_State = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
00853                 iCnt += 2;
00854         }
00855         //Motor Data
00856         if(m_Motor[0].iMotorActive)
00857         {
00858                 //Enc Data
00859                 m_Motor[0].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00860                 iCnt += 4;
00861                 //EncS Data
00862                 m_Motor[0].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00863                 iCnt += 4;
00864                 //Motor Status
00865                 m_Motor[0].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00866                 iCnt += 2;
00867         }
00868         if(m_Motor[1].iMotorActive)
00869         {
00870                 //Enc Data
00871                 m_Motor[1].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00872                 iCnt += 4;
00873                 //EncS Data
00874                 m_Motor[1].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00875                 iCnt += 4;
00876                 //Motor Status
00877                 m_Motor[1].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00878                 iCnt += 2;
00879         }
00880         if(m_Motor[2].iMotorActive)
00881         {
00882                 //Enc Data
00883                 m_Motor[2].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00884                 iCnt += 4;
00885                 //EncS Data
00886                 m_Motor[2].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00887                 iCnt += 4;
00888                 //Motor Status
00889                 m_Motor[2].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00890                 iCnt += 2;
00891         }
00892         if(m_Motor[3].iMotorActive)
00893         {
00894                 //Enc Data
00895                 m_Motor[3].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00896                 iCnt += 4;
00897                 //EncS Data
00898                 m_Motor[3].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00899                 iCnt += 4;
00900                 //Motor Status
00901                 m_Motor[3].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00902                 iCnt += 2;
00903         }
00904         if(m_Motor[4].iMotorActive)
00905         {
00906                 //Enc Data
00907                 m_Motor[4].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00908                 iCnt += 4;
00909                 //EncS Data
00910                 m_Motor[4].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00911                 iCnt += 4;
00912                 //Motor Status
00913                 m_Motor[4].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00914                 iCnt += 2;
00915         }
00916         if(m_Motor[5].iMotorActive)
00917         {
00918                 //Enc Data
00919                 m_Motor[5].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00920                 iCnt += 4;
00921                 //EncS Data
00922                 m_Motor[5].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00923                 iCnt += 4;
00924                 //Motor Status
00925                 m_Motor[5].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00926                 iCnt += 2;
00927         }
00928         if(m_Motor[6].iMotorActive)
00929         {
00930                 //Enc Data
00931                 m_Motor[6].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00932                 iCnt += 4;
00933                 //EncS Data
00934                 m_Motor[6].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00935                 iCnt += 4;
00936                 //Motor Status
00937                 m_Motor[6].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00938                 iCnt += 2;
00939         }
00940         if(m_Motor[7].iMotorActive)
00941         {
00942                 //Enc Data
00943                 m_Motor[7].lEnc = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00944                 iCnt += 4;
00945                 //EncS Data
00946                 m_Motor[7].lEncS = (cMsg[iCnt+3] << 24) + (cMsg[iCnt+2] << 16) + (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00947                 iCnt += 4;
00948                 //Motor Status
00949                 m_Motor[7].iStatus = (cMsg[iCnt+1] << 8) + cMsg[iCnt];
00950                 iCnt += 2;
00951         }
00952 
00953         m_Mutex.unlock();
00954 }
00955 
00956 //------------------------------------------------------------
00957 int RelayBoardV2::convDataToSendMsg(unsigned char cMsg[])
00958 {
00959         //m_Mutex.lock();
00960         int iCnt = 0;
00961         int iChkSum = 0;
00962 
00963         int has_data = 0;
00964         int has_motor_data8 = 0;
00965         int has_motor_data4 = 0;
00966 
00967         if((m_Motor[0].iMotorActive) || (m_Motor[1].iMotorActive) || (m_Motor[2].iMotorActive) || (m_Motor[3].iMotorActive))
00968         {
00969                 has_motor_data4 = 1;
00970                 if((m_Motor[4].iMotorActive) || (m_Motor[5].iMotorActive) || (m_Motor[6].iMotorActive) || (m_Motor[7].iMotorActive))
00971                 {
00972                         has_motor_data8 = 1;
00973                 }
00974         }
00975         //First Bit not in use yet
00976         has_data = (has_motor_data8 << 6) + (has_motor_data4 << 5) + (m_ihasRelayData << 4) + (m_ihas_LCD_DATA << 3) + (m_iHasIOBoard << 2) +(m_iHasUSBoard << 1) + (m_iHasSpeakerData);
00977         //Data in Message:
00978         //Header
00979         cMsg[iCnt++] = 0x02;
00980         cMsg[iCnt++] = 0xD6;
00981         cMsg[iCnt++] = 0x80;
00982         cMsg[iCnt++] = 0x02;
00983         //has_data
00984         //soft_em
00985         //Motor9-6
00986         //Motor5-2
00987         //Relaystates
00988         //LCD Data
00989         //IO Data
00990         //US Data
00991         //Speaker Data
00992         //Checksum
00993         cMsg[iCnt++] = has_data;
00994         cMsg[iCnt++] = m_S_MSG.iSoftEM; //SoftEM
00995 
00996         if(has_motor_data8)
00997         {
00998                 //Motor 9
00999                 cMsg[iCnt++] = ((m_Motor[7].ldesiredEncS & 0xFF000000) >> 24);
01000                 cMsg[iCnt++] = ((m_Motor[7].ldesiredEncS & 0xFF0000) >> 16);
01001                 cMsg[iCnt++] = ((m_Motor[7].ldesiredEncS & 0xFF00) >> 8);
01002                 cMsg[iCnt++] =  (m_Motor[7].ldesiredEncS & 0xFF);
01003                 //Motor 8
01004                 cMsg[iCnt++] = ((m_Motor[6].ldesiredEncS & 0xFF000000) >> 24);
01005                 cMsg[iCnt++] = ((m_Motor[6].ldesiredEncS & 0xFF0000) >> 16);
01006                 cMsg[iCnt++] = ((m_Motor[6].ldesiredEncS & 0xFF00) >> 8);
01007                 cMsg[iCnt++] =  (m_Motor[6].ldesiredEncS & 0xFF);
01008                 //Motor 7
01009                 cMsg[iCnt++] = ((m_Motor[5].ldesiredEncS & 0xFF000000) >> 24);
01010                 cMsg[iCnt++] = ((m_Motor[5].ldesiredEncS & 0xFF0000) >> 16);
01011                 cMsg[iCnt++] = ((m_Motor[5].ldesiredEncS & 0xFF00) >> 8);
01012                 cMsg[iCnt++] =  (m_Motor[5].ldesiredEncS & 0xFF);
01013                 //Motor 6
01014                 cMsg[iCnt++] = ((m_Motor[4].ldesiredEncS & 0xFF000000) >> 24);
01015                 cMsg[iCnt++] = ((m_Motor[4].ldesiredEncS & 0xFF0000) >> 16);
01016                 cMsg[iCnt++] = ((m_Motor[4].ldesiredEncS & 0xFF00) >> 8);
01017                 cMsg[iCnt++] =  (m_Motor[4].ldesiredEncS & 0xFF);
01018         }
01019         if(has_motor_data4)
01020         {
01021                 //Motor 5
01022                 cMsg[iCnt++] = ((m_Motor[3].ldesiredEncS & 0xFF000000) >> 24);
01023                 cMsg[iCnt++] = ((m_Motor[3].ldesiredEncS & 0xFF0000) >> 16);
01024                 cMsg[iCnt++] = ((m_Motor[3].ldesiredEncS & 0xFF00) >> 8);
01025                 cMsg[iCnt++] =  (m_Motor[3].ldesiredEncS & 0xFF);
01026                 //Motor 4
01027                 cMsg[iCnt++] = ((m_Motor[2].ldesiredEncS & 0xFF000000) >> 24);
01028                 cMsg[iCnt++] = ((m_Motor[2].ldesiredEncS & 0xFF0000) >> 16);
01029                 cMsg[iCnt++] = ((m_Motor[2].ldesiredEncS & 0xFF00) >> 8);
01030                 cMsg[iCnt++] =  (m_Motor[2].ldesiredEncS & 0xFF);
01031                 //Motor 3
01032                 cMsg[iCnt++] = ((m_Motor[1].ldesiredEncS & 0xFF000000) >> 24);
01033                 cMsg[iCnt++] = ((m_Motor[1].ldesiredEncS & 0xFF0000) >> 16);
01034                 cMsg[iCnt++] = ((m_Motor[1].ldesiredEncS & 0xFF00) >> 8);
01035                 cMsg[iCnt++] =  (m_Motor[1].ldesiredEncS & 0xFF);
01036                 //Motor 2
01037                 cMsg[iCnt++] = ((m_Motor[0].ldesiredEncS & 0xFF000000) >> 24);
01038                 cMsg[iCnt++] = ((m_Motor[0].ldesiredEncS & 0xFF0000) >> 16);
01039                 cMsg[iCnt++] = ((m_Motor[0].ldesiredEncS & 0xFF00) >> 8);
01040                 cMsg[iCnt++] =  (m_Motor[0].ldesiredEncS & 0xFF);
01041         }
01042         //Relaystates
01043         if(m_ihasRelayData)
01044         {
01045                 cMsg[iCnt++] = m_S_MSG.iCmdRelayBoard >> 8;
01046                 cMsg[iCnt++] = m_S_MSG.iCmdRelayBoard;
01047         }
01048         //LCD Data
01049         if(m_ihas_LCD_DATA)
01050         {
01051                 //ROS_INFO("Display: %s",m_S_MSG.LCD_Txt);
01052                 for(int u = 0; u < 20; u++)
01053                 {
01054                         cMsg[iCnt++] = m_S_MSG.LCD_Txt[u];
01055                 }
01056         }
01057         //IO Data
01058         if(m_iHasIOBoard)
01059         {
01060                 cMsg[iCnt++] = m_S_MSG.IOBoard_Cmd >> 8;
01061                 cMsg[iCnt++] = m_S_MSG.IOBoard_Cmd;
01062         }
01063         //US Data
01064         if(m_iHasUSBoard)
01065         {
01066                 cMsg[iCnt++] = m_S_MSG.USBoard_Cmd >> 8;
01067                 cMsg[iCnt++] = m_S_MSG.USBoard_Cmd;
01068         }
01069         //Speaker Data
01070         if(m_iHasSpeakerData)
01071         {
01072                 cMsg[iCnt++] = m_S_MSG.Speaker >> 8;
01073                 cMsg[iCnt++] = m_S_MSG.SpeakerLoud;
01074         }
01075         m_iNumBytesSend = iCnt;
01076         // calc checksum
01077         for(int i = 4; i < m_iNumBytesSend; i++)
01078         {
01079                 iChkSum %= 0xFF00;
01080                 iChkSum += cMsg[i];
01081         }
01082         cMsg[m_iNumBytesSend] = iChkSum >> 8;
01083         cMsg[m_iNumBytesSend + 1] = iChkSum;
01084         
01085         //resett data indicators
01086         m_iHasIOBoard = 0;
01087         m_ihasRelayData = 0;
01088         m_ihas_LCD_DATA = 0;
01089         m_iHasIOBoard = 0;
01090         m_iHasUSBoard = 0;
01091         m_iHasSpeakerData = 0;
01092 
01093         //m_Mutex.unlock();
01094 
01095         return m_iNumBytesSend + 2;
01096 }


neo_relayboardv2
Author(s): Jan-Niklas Nieland
autogenerated on Fri Sep 9 2016 03:54:28