SerRelayBoard.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/SerRelayBoard.h"
00040 
00041 
00042 //-----------------------------------------------
00043 
00044 
00045 #define NUM_BYTE_SEND_20CHAR_LCD 50
00046 #define NUM_BYTE_SEND_60CHAR_LCD 79
00047 #define NUM_BYTE_SEND_RELAYBOARD_1_4 88
00048 #define NUM_BYTE_REC_RELAYBOARD_1_4 124
00049 
00050 #define RS422_BAUDRATE 420000
00051 #define RS422_RX_BUFFERSIZE 1024
00052 #define RS422_TX_BUFFERSIZE 1024
00053 
00054 #define RS422_TIMEOUT 0.025
00055 
00056 #define NUM_BYTE_REC_MAX 126
00057 #define NUM_BYTE_REC_HEADER 4
00058 #define NUM_BYTE_REC_CHECKSUM 2
00059 #define NUM_BYTE_REC 104
00060 
00061 #define NEO_PI 3.14159265358979323846
00062 #define DEG2RAD(x) NEO_PI/180 * x
00063 
00064 
00065 //#define OUTPUTERROR(...)
00066 
00067 SerRelayBoard::SerRelayBoard()
00068 {
00069         autoSendRequest = false;        //requests are being send when calling sendRequest();
00070         m_iFoundMotors =  m_iHomedMotors = m_iFoundExtHardware = m_iConfigured = 0;
00071         m_iNumBytesSend = 0;
00072         m_iNumBytesRec = 0;
00073         m_ihasRelayData = 0;
00074         m_ihas_LCD_DATA = 0;
00075         m_iHasIOBoard = 0;
00076         m_iHasUSBoard = 0;
00077         m_iHasSpeakerData = 0;
00078         m_iChargeState = 0;
00079 
00080         std::cerr << "starting serrelayboard node\n";
00081 
00082 }
00083 
00084 /*SerRelayBoard::SerRelayBoard(int iTypeLCD, std::string pathToConf)
00085 {
00086         autoSendRequest = true;         //requests are being send when calling setWheelVel(...);
00087         setStartValues(iTypeLCD); //TODO: backwards compatibility
00088 }
00089 */
00090 
00091 void SerRelayBoard::readConfig( int iTypeLCD,std::string pathToConf, std::string sNumComPort,   int hasMotorRight, 
00092                                 int hasMotorLeft, int hasMotorRearRight, int hasMotorRearLeft, 
00093                                 int hasIOBoard, int hasUSBoard, int hasRadarBoard, int hasGyroBoard, 
00094                                 double quickfix1, double quickfix2, double quickfix3, double quickfix4, 
00095                                 DriveParam driveParamLeft, DriveParam driveParamRight,
00096                                 DriveParam driveParamRearLeft, DriveParam driveParamRearRight
00097                         )
00098 {
00099         int i, iHasBoard, iHasMotorRight, iHasMotorLeft;
00100         m_bComInit = false;
00101 
00102         //RelayBoard
00103         m_cSoftEMStop = 0;
00104         resetEMStop();
00105         iHasBoard = 0;
00106         m_iRelBoardBattVoltage = 0;
00107         m_iConfigRelayBoard = 0;
00108         m_iRelBoardKeyPad = 0xFFFF;
00109 
00110         m_iTypeLCD = iTypeLCD;
00111         if(m_iTypeLCD == LCD_20CHAR_TEXT)
00112         {
00113                 m_iNumBytesSend = NUM_BYTE_SEND_20CHAR_LCD;
00114         }
00115         else if (m_iTypeLCD == LCD_60CHAR_TEXT)
00116         {
00117                 m_iNumBytesSend = NUM_BYTE_SEND_60CHAR_LCD;
00118         }
00119         else if (m_iTypeLCD == RELAY_BOARD_1_4)
00120         {
00121                 m_iNumBytesSend = NUM_BYTE_SEND_RELAYBOARD_1_4;
00122         }
00123         else if (m_iTypeLCD == RELAY_BOARD_2)
00124         {
00125                 //type relayboard 2 only
00126                 m_iNumBytesSend = 4; //4Byte Header
00127                 m_iNumBytesRec = 4; //4Byte Header
00128 
00129                 m_iNumBytesSend += 2; //2Byte Data Mask, Soft EMStop
00130                 m_iNumBytesRec += 13; //11Byte ActRelayboardConfig, State, Charging Current, Charging State, Batt Voltage, Keypad, Temp
00131 
00132                 m_iNumBytesSend += 0; //(4*4); //Send data for 4 Motors (4 Byte pro active Motor)
00133                 m_iNumBytesRec += 0; //10 Byte pro active Motor
00134 
00135                 if(hasIOBoard == 1)
00136                 {
00137                         m_iNumBytesSend += 2;
00138                         m_iNumBytesRec += 20;
00139                 }
00140                 if(hasUSBoard == 1)
00141                 {
00142                         m_iNumBytesSend += 2;
00143                         m_iNumBytesRec += 26;
00144                 }
00145 
00146                 m_iNumBytesSend += 2; //2Byte Checksum
00147                 m_iNumBytesRec += 2; //2Byte Checksum   
00148         }
00149 
00150         m_sNumComPort = sNumComPort;
00151 
00152         iHasMotorRight = hasMotorRight;
00153         iHasMotorLeft = hasMotorLeft;
00154         int iHasMotorRearRight = hasMotorRearRight;
00155         int iHasMotorRearLeft = hasMotorRearLeft;
00156         if(     (iHasMotorRight != 0) || (iHasMotorLeft != 0) && 
00157                 (iHasMotorRearRight == 0) && (iHasMotorRearLeft == 0))
00158         {
00159                 m_iConfigRelayBoard |= CONFIG_HAS_DRIVES;
00160         }
00161 
00162         if( (iHasMotorRight != 0) && (iHasMotorLeft != 0) && 
00163                 (iHasMotorRearRight != 0) && (iHasMotorRearLeft != 0))
00164         {
00165                 m_iConfigRelayBoard |= CONFIG_HAS_4_DRIVES;
00166         }       
00167 
00168         iHasBoard = hasIOBoard;
00169         if(iHasBoard == 1)
00170         {
00171                 m_iConfigRelayBoard |= CONFIG_HAS_IOBOARD;
00172         }
00173 
00174         iHasBoard = hasUSBoard;
00175         if(iHasBoard == 1)
00176         {
00177                 m_iConfigRelayBoard |= CONFIG_HAS_USBOARD;
00178         }
00179         
00180         iHasBoard = hasRadarBoard;
00181         if(iHasBoard == 1)
00182         {
00183                 m_iConfigRelayBoard |= CONFIG_HAS_RADARBOARD1;
00184                 m_iConfigRelayBoard |= CONFIG_HAS_RADARBOARD2;
00185         }
00186 
00187         iHasBoard = hasGyroBoard;
00188         if(iHasBoard == 1)
00189         {
00190                 m_iConfigRelayBoard |= CONFIG_HAS_GYROBOARD;
00191         }
00192 
00193         m_iCmdRelayBoard = 0;
00194         m_iRelBoardStatus = 0;
00195 
00196         // IOBoard
00197         m_iIOBoardBattVoltage = 0;
00198         m_iIOBoardDigIn = 0;
00199         m_iIOBoardDigOut = 0;
00200         for(i = 0; i < 8; i++) { m_iIOBoardAnalogIn[i] = 0; }
00201 
00202 
00203 
00204         // drive parameters
00205         
00206         m_DriveParamLeft = driveParamLeft;
00207         m_DriveParamRight = driveParamRight;
00208         m_DriveParamRearLeft = driveParamRearLeft;
00209         m_DriveParamRearRight = driveParamRearRight;
00210 
00211         //
00212         m_iVelCmdMotRightEncS = 0;
00213         m_iVelCmdMotLeftEncS = 0;
00214         m_iPosMeasMotRightEnc = 0;
00215         m_iVelMeasMotRightEncS = 0;
00216         m_iPosMeasMotLeftEnc = 0;
00217         m_iVelMeasMotLeftEncS = 0;
00218 
00219 
00220         m_iVelCmdMotRearRightEncS = 0;
00221         m_iVelCmdMotRearLeftEncS = 0;
00222         m_iPosMeasMotRearRightEnc = 0;
00223         m_iVelMeasMotRearRightEncS = 0;
00224         m_iPosMeasMotRearLeftEnc = 0;
00225         m_iVelMeasMotRearLeftEncS = 0;
00226 
00227         quickFix[0] = quickfix1;
00228         quickFix[1] = quickfix2;
00229         quickFix[2] = quickfix3;
00230         quickFix[3] = quickfix4;
00231 
00232         // GyroBoard
00233         m_bGyroBoardZeroGyro = false;
00234         m_iGyroBoardAng = 0;
00235         for(i = 0; i < 3; i++) { m_iGyroBoardAcc[i]; }
00236         
00237         // RadarBoard
00238         for(i = 0; i < 4; i++) { m_iRadarBoardVel[i] = 0; }
00239         
00240         // USBoard
00241         m_iUSBoardSensorActive = 0xFFFF;
00242 
00243         for(i = 0; i < 16; i++) { m_iUSBoardSensorData[i] = 0; }
00244         for(i = 0; i < 4; i++) { m_iUSBoardAnalogData[i] = 0; }
00245 
00246         m_dLastPosRight = 0;
00247         m_dLastPosLeft = 0;
00248 
00249         for(i = 0; i < 60; i++) { m_cTextDisplay[i] = 0; }
00250 }
00251 
00252 
00253 
00254 
00255 
00256 //-----------------------------------------------
00257 SerRelayBoard::~SerRelayBoard()
00258 {
00259         m_SerIO.closeIO();
00260 }
00261 
00262 //-----------------------------------------------
00263 void SerRelayBoard::readConfiguration()
00264 {
00265 
00266 }
00267 
00268 //-----------------------------------------------
00269 int SerRelayBoard::evalRxBuffer()
00270 {
00271         if(m_iTypeLCD == RELAY_BOARD_2)
00272         {
00273                 evalRxBufferRelayBoard2();      
00274                 return 0;
00275         }
00276         else
00277         {
00278 
00279                 int errorFlag = NO_ERROR;
00280                 static int siNoMsgCnt = 0;
00281 
00282                 double dDltT;
00283         
00284                 int iNumByteRec = NUM_BYTE_REC;
00285                 if(m_iTypeLCD == RELAY_BOARD_1_4)
00286                 {
00287                         iNumByteRec = NUM_BYTE_REC_RELAYBOARD_1_4;
00288                 }
00289 
00290                 const int c_iNrBytesMin = NUM_BYTE_REC_HEADER + iNumByteRec + NUM_BYTE_REC_CHECKSUM;
00291                 const int c_iSizeBuffer = 4096;
00292 
00293                 int i;
00294                 int iNrBytesInQueue, iNrBytesRead, iDataStart;
00295                 unsigned char cDat[c_iSizeBuffer];
00296                 unsigned char cTest[4] = {0x02, 0x80, 0xD6, 0x02};
00297 
00298                 //m_CurrTime = ros::Time::now();
00299                 //dDltT = m_CurrTime.toSec()- m_LastTime.toSec();
00300 
00301                 if( !m_bComInit ) return 0;
00302 
00303                 //enough data in queue?
00304                 iNrBytesInQueue = m_SerIO.getSizeRXQueue();
00305 
00306                 if(iNrBytesInQueue < c_iNrBytesMin)
00307                 {
00308                         siNoMsgCnt++;
00309                         if(siNoMsgCnt > 29)
00310                         {
00311                                 siNoMsgCnt = 0;
00312                                 errorFlag = NO_MESSAGES;
00313                         }  else errorFlag = TOO_LESS_BYTES_IN_QUEUE;
00314 
00315 
00316                         return errorFlag;
00317                 }
00318                 else
00319                 {
00320                         siNoMsgCnt = 0;
00321                 }
00322 
00323                 // search most recent data from back of queue
00324                 iNrBytesRead = m_SerIO.readBlocking((char*)&cDat[0], iNrBytesInQueue);
00325 
00326                 //log
00327                 if(logging == true)
00328                 {
00329                         log_to_file(2, cDat); //direction 1 = transmitted; 2 = recived
00330                 }       
00331 
00332                 for(i = (iNrBytesRead - c_iNrBytesMin); i >= 0 ; i--)
00333                 {
00334                         //try to find start bytes
00335                         if((cDat[i] == cTest[0]) && (cDat[i+1] == cTest[1]) && (cDat[i+2] == cTest[2]) && (cDat[i+3] == cTest[3]))
00336                         {
00337                                 iDataStart = i + 4;
00338 
00339                                 // checksum ok?
00340                                 if( convRecMsgToData(&cDat[iDataStart]) )
00341                                 {
00342                                         return errorFlag;
00343                                 }
00344                                 else
00345                                 {
00346                                         errorFlag = CHECKSUM_ERROR;
00347                                         return errorFlag;
00348                                 }
00349                         }
00350                 }
00351 
00352                 return errorFlag;
00353         }
00354 }
00355 
00356 //----------------------------------------------
00357 int SerRelayBoard::evalRxBufferRelayBoard2()
00358 {
00359         int errorFlag = NO_ERROR;
00360 
00361         if( !m_bComInit ) return 0;
00362 
00363         bool found_header = false;
00364         int msg_type = 100;
00365         int error_cnt = 0;
00366         int no_data_cnt = 0;
00367         int BytesToRead = 0;
00368         int received_checksum = 0;
00369         int my_checksum = 0;
00370         const int c_iSizeBuffer = 130;//4096;
00371         int iNrBytesRead = 0;
00372         unsigned char cDat[c_iSizeBuffer];
00373         unsigned char cHeader[4] = {0x00, 0x00, 0x00, 0x00};
00374 
00375         while(found_header == false)
00376         {
00377                 //std::cout << "warte auf daten " << std::endl; //JNN
00378                 if(m_SerIO.getSizeRXQueue() >= 1)
00379                 {
00380                         //std::cout << "In der schleife: " << std::endl; //JNN
00381                         //Read Header
00382                         cHeader[3] = cHeader[2];
00383                         cHeader[2] = cHeader[1];
00384                         cHeader[1] = cHeader[0];
00385                         iNrBytesRead = m_SerIO.readBlocking((char*)&cHeader[0], 1);
00386                         //std::cout << "Header: " << (int)cHeader[0] << "----" << (int)cHeader[1] << "----" << (int)cHeader[2] << "----" << (int)cHeader[3] << "----" << std::endl; //JNN
00387                         if((cHeader[3] == 0x08) && (cHeader[2] == 0xFE) && (cHeader[1] == 0xEF) && (cHeader[0] == 0x08))
00388                         {
00389                                 //Update Msg
00390                                 msg_type = 1;
00391                                 found_header = true;
00392                         }
00393                         else if((cHeader[3] == 0x02) && (cHeader[2] == 0x80) && (cHeader[1] == 0xD6) && (cHeader[0] == 0x02))
00394                         {
00395                                 //Config Msg
00396                                 msg_type = 2;
00397                                 found_header = true;
00398                         }
00399                         else if((cHeader[3] == 0x02) && (cHeader[2] == 0xFF) && (cHeader[1] == 0xD6) && (cHeader[0] == 0x02))
00400                         {
00401                                 //Error Msg
00402                                 msg_type = 3;
00403                                 found_header = true;
00404                         }
00405                         if(++error_cnt > 20)
00406                         {
00407                                 //No Header in first 20 Bytes -> Error
00408                                 //flush input
00409                                 return 99;
00410                         }
00411 
00412                 }
00413         }
00414         switch(msg_type)
00415         {
00416                 case 1: BytesToRead = m_iNumBytesRec - 4;
00417                                 break;
00418                 case 2: BytesToRead = 6;
00419                                 break;
00420                 case 3: BytesToRead = 3;
00421                                 break;
00422                 default: return 98;
00423         }
00424         error_cnt = 0;
00425 
00426         //std::cout << " daten erwartet: " << BytesToRead << std::endl; //JNN
00427         while(m_SerIO.getSizeRXQueue() < BytesToRead)
00428         {
00429                 usleep(2000);
00430                 //std::cout << " Queue Size: " << m_SerIO.getSizeRXQueue() << std::endl; //JNN
00431         }
00432         iNrBytesRead = m_SerIO.readBlocking((char*)&cDat[0], BytesToRead);
00433         //std::cout << " anz. empf. daten: " << iNrBytesRead << std::endl; //JNN
00434 
00435         //Calc Checksum
00436         //my_checksum %= 0xFF00;
00437         my_checksum += cHeader[3];
00438         my_checksum %= 0xFF00;
00439         my_checksum += cHeader[2];
00440         my_checksum %= 0xFF00;
00441         my_checksum += cHeader[1];
00442         my_checksum %= 0xFF00;
00443         my_checksum += cHeader[0];
00444         for(int e = 0; e < iNrBytesRead - 2; e++)
00445         {
00446                 my_checksum %= 0xFF00;
00447                 my_checksum += cDat[e];
00448         }
00449         //received checksum
00450         received_checksum = (cDat[BytesToRead - 1] << 8);
00451         received_checksum += cDat[BytesToRead - 2];
00452         //std::cout << "empfangene Checksumme: " << received_checksum << std::endl; //JNN
00453         if(received_checksum != my_checksum)
00454         {
00455                 //Wrong Checksum
00456                 return CHECKSUM_ERROR;
00457         }
00458         if(msg_type == 1)
00459         {
00460                 convRecMsgToDataRelayBoard2(&cDat[0]);
00461                 return NO_ERROR;
00462         }
00463         else if(msg_type == 2)
00464         {
00465                 m_iFoundMotors = cDat[0];
00466                 m_iHomedMotors = cDat[1];
00467                 m_iFoundExtHardware = cDat[2];
00468                 m_iConfigured = cDat[3];
00469                 return MSG_CONFIG;
00470         }
00471         else if(msg_type == 3)
00472         {
00473                 ROS_INFO("ERROR evalrxBuffer: ");
00474                 int iLastError = cDat[0];
00475                 
00476                 return GENERAL_SENDING_ERROR;
00477         }
00478         else
00479         {
00480                 return GENERAL_SENDING_ERROR;
00481         }
00482 
00483         return 0;
00484 
00485 }
00486 
00487 //-----------------------------------------------
00488 bool SerRelayBoard::init() 
00489 { 
00490         return initPltf();
00491 };
00492 
00493 //------------------------------------------------
00494 bool SerRelayBoard::initPltf()
00495 {
00496         int iRet;
00497         m_SerIO.setBaudRate(RS422_BAUDRATE);
00498         m_SerIO.setDeviceName( m_sNumComPort.c_str() );
00499         m_SerIO.setBufferSize(RS422_RX_BUFFERSIZE, RS422_TX_BUFFERSIZE);
00500         m_SerIO.setTimeout(RS422_TIMEOUT);
00501         iRet = m_SerIO.openIO();
00502         if (iRet != 0)
00503         {
00504                 m_bComInit = false;
00505                 return false;   
00506         }
00507 
00508         m_bComInit = true;
00509 
00510         if(m_iTypeLCD == RELAY_BOARD_2)
00511         {
00512                 initRelayBoard2();
00513         }
00514         else
00515         {
00516                 m_iCmdRelayBoard |= CMD_RESET_POS_CNT;
00517         }
00518 
00519         return true;
00520 }
00521 
00522 //-----------------------------------------------
00523 bool SerRelayBoard::initRelayBoard2()
00524 {
00525         unsigned char cConfig_Data[33]; //4 Byte Header 3 Config Bytes 24 Byte Modulo 2 Byte Checksum JNN
00526         unsigned char cExtHardware = 0;
00527         int iChkSum = 0;
00528         int byteswritten = 0;
00529         int answertype = 0;
00530         //Header
00531         cConfig_Data[0] = 0x02;
00532         cConfig_Data[1] = 0x80;
00533         cConfig_Data[2] = 0xD6;
00534         cConfig_Data[3] = 0x02;
00535         //configuration Bytes
00536         cConfig_Data[4] = 0;    // 2 fake - motors
00537         cConfig_Data[5] = 0;    // do not home motors
00538         cConfig_Data[6] = cExtHardware; //no ext hardware
00539 
00540         //---------------Modulo for all Motors - char 7 - 30--------------------------->
00541         for (int i = 7; i < 31; i++)
00542         {
00543                 cConfig_Data[i] = 0;
00544         }
00545         
00546         //----------------Calc Checksum------------------------------------->
00547         for(int i=4;i<=30;i++)    //r=4 => Header not added to Checksum
00548         {
00549                 iChkSum %= 0xFF00;
00550                 iChkSum += cConfig_Data[i];
00551         }
00552         //----------------END Calc Checksum--------------------------------->
00553 
00554         //----------------Add Checksum to Data------------------------------>
00555         cConfig_Data[31] = iChkSum >> 8;
00556         cConfig_Data[32] = iChkSum;
00557         //------------END Add Checksum to Data------------------------------>
00558 
00559         byteswritten = m_SerIO.writeIO((char*)cConfig_Data,33);
00560         if(byteswritten != 33)
00561         {
00562                 //------Log Error here -------------------
00563                 std::cerr << "Config not sent. \n";
00564                 return false;
00565         }
00566         else
00567         {
00568                 std::cerr << "Relayboard config sent. \n";
00569         }
00570 
00571         answertype = evalRxBufferRelayBoard2();
00572 
00573         if(answertype == 2)
00574         {
00575                 //Check received Data
00576                 if(m_iConfigured == 1)
00577                 {
00578                         //Configuration Failed
00579                         std::cerr << "RelayBoard Configuration ok. ";
00580                         return true;
00581                         //------Log Error here -------------------
00582                 }
00583                 else
00584                 {
00585                         std::cerr << "RelayBoard Configuration FAILED. ";
00586                         return -1;
00587                         //------Log Error here -------------------
00588                 }
00589 
00590         }
00591         
00592 
00593 }
00594 
00595 //-----------------------------------------------
00596 bool SerRelayBoard::reset(){
00597         return resetPltf();
00598 }
00599 
00600 //-----------------------------------------
00601 bool SerRelayBoard::resetPltf()
00602 {
00603         m_SerIO.closeIO();
00604         m_bComInit = false;
00605 
00606         init();
00607         return true;
00608 }
00609 
00610 //-----------------------------------------------
00611 bool SerRelayBoard::shutdown()
00612 {
00613         return shutdownPltf();
00614 }
00615 
00616 
00617 bool SerRelayBoard::shutdownPltf()
00618 {
00619         m_SerIO.closeIO();
00620         m_bComInit = false;
00621         return true;
00622 }
00623 
00624 //-----------------------------------------------
00625 bool SerRelayBoard::isComError()
00626 {
00627         return false;   
00628 }
00629 
00630 //-----------------------------------------------
00631 bool SerRelayBoard::isDriveError()
00632 {
00633         return false;   
00634 }
00635 
00636 //-----------------------------------------------
00637 bool SerRelayBoard::isEMStop()
00638 {
00639         if( (m_iRelBoardStatus & 0x0001) != 0)
00640         {
00641                 return true;
00642         }
00643         else
00644         {
00645                 return false;
00646         }
00647 }
00648 
00649 //-----------------------------------------------
00650 bool SerRelayBoard::isScannerStop()
00651 {
00652         if( (m_iRelBoardStatus & 0x0002) != 0)
00653         {
00654                 return true;
00655         }
00656         else
00657         {
00658                 return false;
00659         }
00660 }
00661 
00662 //-----------------------------------------------
00663 void SerRelayBoard::sendNetStartCanOpen()
00664 {
00665 
00666 }
00667 
00668 //-------------------------------------------------
00669 int SerRelayBoard::sendRequest()
00670 {
00671         if(!autoSendRequest){
00672                 int errorFlag = NO_ERROR;
00673                 int iNrBytesWritten;
00674 
00675                 unsigned char cMsg[m_iNumBytesSend+50];
00676         
00677                 m_Mutex.lock();
00678         
00679                         if(m_iTypeLCD == RELAY_BOARD_2)
00680                         {
00681                                 convDataToSendMsgRelayBoard2(cMsg);                     
00682                         }
00683                         else
00684                         {
00685                                 convDataToSendMsg(cMsg);
00686                         }
00687 
00688                         m_SerIO.purgeTx();
00689                         iNrBytesWritten = m_SerIO.writeIO((char*)cMsg,m_iNumBytesSend);
00690         
00691                         if(iNrBytesWritten < m_iNumBytesSend) {
00692                                 errorFlag = GENERAL_SENDING_ERROR;
00693                         }
00694                         //log
00695                         if(logging == true)
00696                         {
00697                                 log_to_file(1, cMsg); //direction 1 = transmitted; 2 = recived
00698                         }
00699                         //m_LastTime = ros::Time::now();
00700                 m_Mutex.unlock();
00701                 return errorFlag;
00702         }
00703         else {
00704                 std::cerr << "You are running the depreced mode for backward compability, that's why sendRequest is being handled by setWheelVel()\n";
00705                 return 0;
00706         }
00707 };
00708 
00709 
00710 //-----------------------------------------------
00711 // MotCtrlBoard
00712 //-----------------------------------------------
00713 
00714 //-----------------------------------------------
00715 int SerRelayBoard::disableBrake(int iCanIdent, bool bDisabled)
00716 {
00717         return 0;
00718 }
00719 
00720 //-----------------------------------------------
00721 int SerRelayBoard::setWheelVel(int iCanIdent, double dVelWheel, bool bQuickStop)
00722 {               
00723         //ROS_INFO("set wheel called %d ", iCanIdent);
00724 
00725         static bool bDataMotRight = false;
00726         static bool bDataMotLeft = false;
00727         static bool bDataMotRearRight = false;
00728         static bool bDataMotRearLeft = false;
00729 
00730         bool bVelLimited = false;
00731         int iNrBytesWritten;
00732 
00733         unsigned char cMsg[NUM_BYTE_SEND_RELAYBOARD_1_4];
00734 
00735         /*if(m_iTypeLCD != RELAY_BOARD_1_4)
00736         {
00737                 //set rear data available for 2-drive-robot
00738                 bDataMotRearRight = true;
00739                 bDataMotRearLeft = true;
00740 
00741         }*/
00742         
00743         m_Mutex.lock();
00744         
00745         if(iCanIdent == CANNODE_MOTORRIGHT)
00746         {
00747                 m_iVelCmdMotRightEncS = m_DriveParamRight.getSign()     *
00748                         m_DriveParamRight.convRadSToIncrPerPeriod(dVelWheel);
00749 
00750 /* TODO:
00751                 if(MathSup::limit(&m_iVelCmdMotRightEncS, (int)m_DriveParamRight.getVelMax()) != 0)
00752                 {
00753                         LOGALERT("vel right limited");
00754                 }
00755 */
00756                 bDataMotRight = true;
00757         }
00758 
00759         if(iCanIdent == CANNODE_MOTORLEFT)
00760         {
00761                 m_iVelCmdMotLeftEncS = m_DriveParamLeft.getSign()       *
00762                         m_DriveParamLeft.convRadSToIncrPerPeriod(dVelWheel);
00763 
00764 
00765 /* TODO:
00766                 if(MathSup::limit(&m_iVelCmdMotLeftEncS, (int)m_DriveParamLeft.getVelMax()) != 0)
00767                 {
00768                         LOGALERT("vel left limited");
00769                 }
00770 */
00771         
00772                 bDataMotLeft = true;
00773         }
00774 
00775         if(iCanIdent == CANNODE_MOTORREARRIGHT)
00776         {
00777                 m_iVelCmdMotRearRightEncS = (int)(m_DriveParamRearRight.getSign()       *
00778                         m_DriveParamRearRight.convRadSToIncrPerPeriod(dVelWheel));
00779 
00780 /*              if(MathSup::limit(&m_iVelCmdMotRearRightEncS, (int)m_DriveParamRearRight.getVelMax()) != 0)
00781                 {
00782                         LOGALERT("vel rearright limited");
00783                 }
00784 */
00785                 bDataMotRearRight = true;
00786         }
00787 
00788         if(iCanIdent == CANNODE_MOTORREARLEFT)
00789         {
00790                 m_iVelCmdMotRearLeftEncS = (int)(m_DriveParamRearLeft.getSign() *
00791                         m_DriveParamRearLeft.convRadSToIncrPerPeriod(dVelWheel));
00792 
00793 /*              if(MathSup::limit(&m_iVelCmdMotRearLeftEncS, (int)m_DriveParamRearLeft.getVelMax()) != 0)
00794                 {
00795                         LOGALERT("vel rearleft limited");
00796                 }
00797 */      
00798                 bDataMotRearLeft = true;
00799         }
00800 
00801         /*if(bDataMotRight && bDataMotLeft && bDataMotRearLeft && bDataMotRearRight)
00802         {
00803 
00804                 //ROS_INFO("sending data to relayboard ");
00805                 bDataMotRight = bDataMotLeft = bDataMotRearRight = bDataMotRearLeft = false; 
00806 
00807                 if(bQuickStop)
00808                 {
00809                         m_iCmdRelayBoard |= CMD_QUICK_STOP;
00810                 }
00811                 else
00812                 {
00813                         m_iCmdRelayBoard &= ~CMD_QUICK_STOP;
00814                 }
00815         
00816                 //data will be sent with autoupdate after calling setWheel with every drive
00817                 /*
00818                 convDataToSendMsg(cMsg);
00819 
00820                 m_SerIO.purgeTx();
00821 
00822                 // send data
00823                 iNrBytesWritten = m_SerIO.write((char*)cMsg, m_iNumBytesSend);
00824                 if(iNrBytesWritten < m_iNumBytesSend)
00825                 {
00826                         //LOGALERT("only " << iNrBytesWritten << " bytes written to socket");
00827                 }
00828         
00829 
00830         }*/
00831 
00832 
00833         m_Mutex.unlock();
00834 
00835         return iNrBytesWritten;
00836 }
00837 //-----------------------------------------------
00838 int SerRelayBoard::setWheelPosVel(int iCanIdent, double dPos, double dVel, bool bQuickStop)
00839 {
00840         return 0;
00841 }
00842 
00843 //-----------------------------------------------
00844 int SerRelayBoard::requestMotPosVel(int iCanIdent)
00845 {
00846         return 0;
00847 }
00848 
00849 //-----------------------------------------------
00850 void SerRelayBoard::requestDriveStatus()
00851 {
00852 
00853 }
00854 
00855 //-----------------------------------------------
00856 int SerRelayBoard::getWheelPosVel(      int iCanIdent, double* pdAngWheel, double* pdVelWheel)
00857 {
00858         m_Mutex.lock();
00859         
00860         if(iCanIdent == CANNODE_MOTORRIGHT)
00861         {
00862                 *pdAngWheel = m_DriveParamRight.getSign() * m_DriveParamRight.convIncrToRad(m_iPosMeasMotRightEnc) * quickFix[0];       
00863                 *pdVelWheel = m_DriveParamRight.getSign() * m_DriveParamRight.convIncrPerPeriodToRadS(m_iVelMeasMotRightEncS) * quickFix[0];
00864         }
00865 
00866         if(iCanIdent == CANNODE_MOTORLEFT)
00867         {
00868                 *pdAngWheel = m_DriveParamLeft.getSign() * m_DriveParamLeft.convIncrToRad(m_iPosMeasMotLeftEnc) * quickFix[1];  
00869                 *pdVelWheel = m_DriveParamLeft.getSign() * m_DriveParamLeft.convIncrPerPeriodToRadS(m_iVelMeasMotLeftEncS) * quickFix[1];
00870         }
00871         if(iCanIdent == CANNODE_MOTORREARRIGHT)
00872         {
00873                 *pdAngWheel = m_DriveParamRearRight.getSign() * m_DriveParamRearRight.convIncrToRad(m_iPosMeasMotRearRightEnc) * quickFix[2];   
00874                 *pdVelWheel = m_DriveParamRearRight.getSign() * m_DriveParamRearRight.convIncrPerPeriodToRadS(m_iVelMeasMotRearRightEncS) * quickFix[2];
00875         }
00876 
00877         if(iCanIdent == CANNODE_MOTORREARLEFT)
00878         {
00879                 *pdAngWheel = m_DriveParamRearLeft.getSign() * m_DriveParamRearLeft.convIncrToRad(m_iPosMeasMotRearLeftEnc) * quickFix[3];      
00880                 *pdVelWheel = m_DriveParamRearLeft.getSign() * m_DriveParamRearLeft.convIncrPerPeriodToRadS(m_iVelMeasMotRearLeftEncS) * quickFix[3];
00881         }
00882 
00883         m_Mutex.unlock();
00884 
00885         return 0;
00886 }
00887 
00888 //-----------------------------------------------
00889 int SerRelayBoard::getWheelDltPosVel(   int iCanIdent, double* pdDltAng, double* pdVelWheel)
00890 {
00891         double dCurrPos;
00892 
00893         m_Mutex.lock();
00894         
00895         if(iCanIdent == CANNODE_MOTORRIGHT)
00896         {
00897                 dCurrPos = m_DriveParamRight.getSign() * m_DriveParamRight.convIncrToRad(m_iPosMeasMotRightEnc) * quickFix[0];
00898                 
00899                 *pdDltAng = dCurrPos - m_dLastPosRight;
00900                 m_dLastPosRight = dCurrPos;
00901 
00902                 *pdVelWheel = m_DriveParamRight.getSign() * m_DriveParamRight.convIncrPerPeriodToRadS(m_iVelMeasMotRightEncS) * quickFix[0];
00903         }
00904 
00905         if(iCanIdent == CANNODE_MOTORLEFT)
00906         {
00907                 dCurrPos = m_DriveParamLeft.getSign() * m_DriveParamLeft.convIncrToRad(m_iPosMeasMotLeftEnc) * quickFix[1];
00908 
00909                 *pdDltAng = dCurrPos - m_dLastPosLeft;
00910                 m_dLastPosLeft = dCurrPos;
00911 
00912                 *pdVelWheel = m_DriveParamLeft.getSign() * m_DriveParamLeft.convIncrPerPeriodToRadS(m_iVelMeasMotLeftEncS) * quickFix[1];
00913         }
00914 
00915         if(iCanIdent == CANNODE_MOTORREARRIGHT)
00916         {
00917                 dCurrPos = m_DriveParamRearRight.getSign() * m_DriveParamRearRight.convIncrToRad(m_iPosMeasMotRearRightEnc) * quickFix[2];
00918                 
00919                 *pdDltAng = dCurrPos - m_dLastPosRearRight;
00920                 m_dLastPosRearRight = dCurrPos; 
00921 
00922                 *pdVelWheel = m_DriveParamRearRight.getSign() * m_DriveParamRearRight.convIncrPerPeriodToRadS(m_iVelMeasMotRearRightEncS) * quickFix[2];
00923         }
00924 
00925         if(iCanIdent == CANNODE_MOTORREARLEFT)
00926         {
00927                 dCurrPos = m_DriveParamRearLeft.getSign() * m_DriveParamRearLeft.convIncrToRad(m_iPosMeasMotRearLeftEnc) * quickFix[3]; 
00928 
00929                 *pdDltAng = dCurrPos - m_dLastPosRearLeft;
00930                 m_dLastPosRearLeft = dCurrPos;
00931 
00932                 *pdVelWheel = m_DriveParamRearLeft.getSign() * m_DriveParamRearLeft.convIncrPerPeriodToRadS(m_iVelMeasMotRearLeftEncS) *  quickFix[3];
00933         }
00934 
00935         m_Mutex.unlock();
00936 
00937         return 0;
00938 }
00939 
00940 //-----------------------------------------------
00941 void SerRelayBoard::getStatus(int iCanIdent, int* piStatus, int* piTempCel)
00942 {
00943         switch(iCanIdent)
00944         {
00945         case CANNODE_MOTORLEFT:
00946                 *piStatus = m_iMotLeftStatus;
00947                 break;
00948         case CANNODE_MOTORRIGHT:
00949                 *piStatus = m_iMotRightStatus;
00950                 break;
00951         case CANNODE_MOTORREARLEFT:
00952                 *piStatus = m_iMotRearLeftStatus;
00953                 break;
00954         case CANNODE_MOTORREARRIGHT:
00955                 *piStatus = m_iMotRearRightStatus;
00956                 break;
00957         default:
00958                 std::cout<<"Canident of drive unknown: " << iCanIdent<<std::endl;
00959 
00960         }
00961 
00962         *piTempCel = 0;
00963 }
00964 
00965 //-----------------------------------------------
00966 int SerRelayBoard::execHoming(int CanIdent)
00967 {
00968         // NOT IMPLEMENTED !!!!
00969         return 0;
00970 }
00971 
00972 //-----------------------------------------------
00973 // RelayBoard
00974 //-----------------------------------------------
00975 
00976 int SerRelayBoard::getRelayBoardDigOut()
00977 {
00978         return m_iCmdRelayBoard;
00979 }
00980 int SerRelayBoard::setRelayBoardDigOut(int iChannel, bool bOn)
00981 {
00982         switch( iChannel)
00983         {
00984         case 0:
00985 
00986                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_CHARGE_RELAY; }
00987                 else { m_iCmdRelayBoard &= ~CMD_SET_CHARGE_RELAY; }
00988                 
00989                 break;
00990 
00991         case 1:
00992 
00993                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY1; }
00994                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY1; }
00995 
00996                 break;
00997 
00998         case 2:
00999 
01000                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY2; }
01001                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY2; }
01002 
01003                 break;
01004 
01005         case 3:
01006 
01007                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY3; }
01008                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY3; }
01009 
01010                 break;
01011 
01012         case 4:
01013 
01014                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY4; }
01015                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY4; }
01016 
01017                 break;
01018 
01019         case 5:
01020 
01021                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY5; }
01022                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY5; }
01023 
01024                 break;
01025 
01026         case 6:
01027 
01028                 if(bOn) { m_iCmdRelayBoard |= CMD_SET_RELAY6; }
01029                 else { m_iCmdRelayBoard &= ~CMD_SET_RELAY6; }
01030 
01031                 break;
01032 
01033         default:
01034 
01035                 return -1;
01036         }
01037         
01038         return 0;
01039 }
01040 //-----------------------------------------------
01041 int SerRelayBoard::getRelayBoardAnalogIn(int* piAnalogIn)
01042 {
01043         piAnalogIn[0] = m_iChargeCurrent;
01044         piAnalogIn[1] = m_iRelBoardBattVoltage;
01045         piAnalogIn[2] = m_iRelBoardTempSensor;
01046         piAnalogIn[3] = m_iRelBoardKeyPad;
01047         piAnalogIn[4] = m_iRelBoardIRSensor[0];
01048         piAnalogIn[5] = m_iRelBoardIRSensor[1];
01049         piAnalogIn[6] = m_iRelBoardIRSensor[2];
01050         piAnalogIn[7] = m_iRelBoardIRSensor[3];
01051 
01052         return 0;
01053 }
01054 
01055 //-----------------------------------------------
01056 int SerRelayBoard::getRelayBoardDigIn()
01057 {
01058         //is transmitted in keypaddata
01059         //m_iRelBoardKeyPad & 
01060         if((~m_iRelBoardKeyPad) & 0x20)
01061                 //first digin 31
01062                 return 1;
01063         if((~m_iRelBoardKeyPad) & 0x10)
01064                 //second digin 47
01065                 return 2;
01066         else
01067                 return 0;
01068 
01069 }
01070 
01071 //-----------------------------------------------
01072 // IOBoard
01073 //-----------------------------------------------
01074 
01075 //-----------------------------------------------
01076 void SerRelayBoard::requestIOBoardData()
01077 {
01078 }
01079 
01080 //-----------------------------------------------
01081 void SerRelayBoard::requestIOBoardAnalogIn()
01082 {
01083 }
01084 
01085 //-----------------------------------------------
01086 void SerRelayBoard::getIOBoardJoyValWheelMean(double* pdVelWheelLeftMean, double* pdVelWheelRightMean)
01087 {
01088         *pdVelWheelLeftMean = 0;
01089         *pdVelWheelRightMean = 0;
01090 }
01091 
01092 //-----------------------------------------------
01093 void SerRelayBoard::getIOBoardJoyValNorm(double* pdJoyXNorm, double* pdJoyYNorm)
01094 {
01095         *pdJoyXNorm = 0;
01096         *pdJoyYNorm = 0;
01097 }
01098 
01099 //-----------------------------------------------
01100 int SerRelayBoard::getIOBoardBattVoltage()
01101 {
01102         return m_iIOBoardBattVoltage;
01103 }
01104 
01105 //-----------------------------------------------
01106 int SerRelayBoard::getIOBoardDigIn()
01107 {
01108         return m_iIOBoardDigIn;
01109 }
01110 
01111 //-----------------------------------------------
01112 int SerRelayBoard::getIOBoardDigOut()
01113 {
01114         return m_iIOBoardDigOut;
01115 }
01116 
01117 //-----------------------------------------------
01118 int SerRelayBoard::setIOBoardDigOut(int iChannel, bool bVal)
01119 {
01120         int iMask;
01121 
01122         iMask = (1 << iChannel);
01123         
01124         if(bVal)
01125         {
01126                 m_iIOBoardDigOut |= iMask;
01127         }
01128         else
01129         {
01130                 m_iIOBoardDigOut &= ~iMask;
01131         }
01132         
01133         return 0;       
01134 }
01135 
01136 //-----------------------------------------------
01137 int SerRelayBoard::getIOBoardAnalogIn(int* piAnalogIn)
01138 {
01139         int i;
01140 
01141         m_Mutex.lock();
01142         
01143         for(i = 0; i < 8; i++)
01144         {
01145                 piAnalogIn[i] = m_iIOBoardAnalogIn[i];
01146         }
01147 
01148         m_Mutex.unlock();
01149 
01150         return 0;
01151 }
01152 
01153 //-----------------------------------------------
01154 void SerRelayBoard::writeIOBoardLCD(int iLine, int iColumn, const std::string& sText)
01155 {
01156         int i, iSize;
01157 
01158         iSize = sText.size();
01159 
01160         protocol_version = m_iTypeLCD;
01161         if(m_iTypeLCD == LCD_20CHAR_TEXT)
01162         {
01163                 for(i = 0; i < 20; i++)
01164                 {
01165                         if(i < iSize)
01166                         {
01167                                 m_cTextDisplay[i] = sText[i];
01168                         }
01169                         else
01170                         {
01171                                 m_cTextDisplay[i] = 0;
01172                         }
01173                 }
01174         }
01175         else
01176         {
01177                 for(i = 0; i < 60; i++)
01178                 {
01179                         if(i < iSize)
01180                         {
01181                                 m_cTextDisplay[i] = sText[i];
01182                         }
01183                         else
01184                         {
01185                                 m_cTextDisplay[i] = ' ';
01186                         }
01187                 }
01188         }
01189 }
01190 
01191 //-----------------------------------------------
01192 //USBoard
01193 //-----------------------------------------------
01194 
01195 //-----------------------------------------------
01196 int SerRelayBoard::startUS(int iChannelActive)
01197 {
01198         m_iUSBoardSensorActive = iChannelActive;
01199         
01200         return 0;
01201 }
01202 //-----------------------------------------------
01203 int SerRelayBoard::stopUS()
01204 {
01205         m_iUSBoardSensorActive = 0x00;
01206 
01207         return 0;
01208 }
01209 //-----------------------------------------------
01210 void SerRelayBoard::requestUSBoardData1To8()
01211 {
01212 }
01213 
01214 //-----------------------------------------------
01215 int SerRelayBoard::getUSBoardData1To8(int* piUSDistMM)
01216 {
01217         int i;
01218 
01219         m_Mutex.lock();
01220         
01221         for(i = 0; i < 8; i++)
01222         {
01223                 piUSDistMM[i] = 10 * m_iUSBoardSensorData[i];
01224         }
01225 
01226         m_Mutex.unlock();
01227 
01228         return 0;
01229 }
01230 
01231 //-----------------------------------------------
01232 void SerRelayBoard::requestUSBoardData9To16()
01233 {
01234 }
01235 
01236 //-----------------------------------------------
01237 int SerRelayBoard::getUSBoardData9To16(int* piUSDistMM)
01238 {
01239         int i;
01240 
01241         m_Mutex.lock();
01242 
01243         for(i = 0; i < 8; i++)
01244         {
01245                 piUSDistMM[i] = 10 * m_iUSBoardSensorData[i + 8];
01246         }
01247 
01248         m_Mutex.unlock();
01249         
01250         return 0;
01251 }
01252 
01253 //-----------------------------------------------
01254 void SerRelayBoard::requestUSBoardAnalogIn()
01255 {
01256 }
01257 
01258 //-----------------------------------------------
01259 void SerRelayBoard::getUSBoardAnalogIn(int* piAnalogIn)
01260 {
01261         int i;
01262 
01263         m_Mutex.lock();
01264 
01265         for(i = 0; i < 4; i++)
01266         {
01267                 piAnalogIn[i] = m_iUSBoardAnalogData[i];
01268         }
01269 
01270         m_Mutex.unlock();
01271 }
01272 
01273 
01274 
01275 
01276 //-----------------------------------------------
01277 // GyroBoard
01278 //-----------------------------------------------
01279 
01280 //-----------------------------------------------
01281 void SerRelayBoard::zeroGyro(bool bZeroActive)
01282 {
01283         if(bZeroActive)
01284         {
01285                 m_iCmdRelayBoard |= CMD_ZERO_GYRO;
01286         }
01287         else
01288         {
01289                 m_iCmdRelayBoard &= ~CMD_ZERO_GYRO;
01290         }
01291 }
01292 
01293 //-----------------------------------------------
01294 int SerRelayBoard::getGyroBoardAng(double* pdAngRad, double dAcc[])
01295 {
01296         const double cdGyroScale = 1 / 520.5;
01297 
01298         int i;
01299         double dAng;
01300         
01301         m_Mutex.lock();
01302         
01303         dAng = m_iGyroBoardAng * cdGyroScale; // gyroboard transmits gyro value in degrees
01304         *pdAngRad = DEG2RAD(dAng);
01305 
01306         for(i = 0; i < 3; i++)
01307         {
01308                 dAcc[i] = m_iGyroBoardAcc[i];
01309         }
01310 
01311         m_Mutex.unlock();
01312         
01313         return 0;
01314 }
01315 int SerRelayBoard::getGyroBoardAngBoost(double* pdAngRad, boost::array<double, 3u>& dAcc)
01316 {
01317         const double cdGyroScale = 1 / 520.5;
01318 
01319         int i;
01320         double dAng;
01321         
01322         m_Mutex.lock();
01323         
01324         dAng = m_iGyroBoardAng * cdGyroScale; // gyroboard transmits gyro value in degrees
01325         *pdAngRad = DEG2RAD(dAng);
01326 
01327         for(i = 0; i < 3; i++)
01328         {
01329                 dAcc[i] = m_iGyroBoardAcc[i];
01330         }
01331 
01332         m_Mutex.unlock();
01333         
01334         return 0;
01335 }
01336 
01337 
01338 //-----------------------------------------------
01339 int SerRelayBoard::getGyroBoardDltAng(double* pdAng, double dAcc[])
01340 {
01341         return 0;
01342 }
01343 
01344 //-----------------------------------------------
01345 // RadarBoard
01346 //-----------------------------------------------
01347 void SerRelayBoard::requestRadarBoardData()
01348 {
01349 }
01350 
01351 //-----------------------------------------------
01352 int SerRelayBoard::getRadarBoardData(double* pdVelMMS)
01353 {
01354         int i;
01355 
01356         m_Mutex.lock();
01357         
01358         for(i = 0; i < 4; i++)
01359         {
01360                 pdVelMMS[i] = m_iRadarBoardVel[i];
01361 
01362         }
01363 
01364         m_Mutex.unlock();
01365         
01366         return 0;
01367 }
01368 
01369 //-----------------------------------------------
01370 // CanClientGeneric
01371 //-----------------------------------------------
01372 void SerRelayBoard::addGenericCANListeningId(int id)
01373 {
01374 }
01375 
01376 //-----------------------------------------------
01377 void SerRelayBoard::removeGenericCANListeningId(int id)
01378 {
01379 }
01380 
01381 //-----------------------------------------------
01382 void SerRelayBoard::getGenericCANMessages(std::vector<CANTimedMessage>& pMessages)
01383 {
01384 }
01385 
01386 //-----------------------------------------------
01387 void SerRelayBoard::sendGenericCANMessage(CanMsg& message)
01388 {
01389 }
01390 
01391 //-----------------------------------------------
01392 void SerRelayBoard::setEMStop()
01393 {               
01394         if (m_cSoftEMStop & 0x01)
01395         {
01396                 m_cSoftEMStop &= 0xFE;
01397                 //LOGINFO ("Emergency Stop INAKTIVE");
01398         }
01399         else if ((m_cSoftEMStop == 0) || (m_cSoftEMStop & 0x02))
01400         {
01401                 m_cSoftEMStop |= 0x01;
01402                 //LOGINFO("Emergency Stop AKTIVE");
01403         }
01404 }
01405 
01406 //-----------------------------------------------
01407 void SerRelayBoard::resetEMStop()
01408 {       
01409         m_cSoftEMStop |= 0x02;
01410 }
01411 
01412 //-----------------------------------------------
01413 void SerRelayBoard::enable_logging()
01414 {
01415         logging = true;
01416 }
01417 //-----------------------------------------------
01418 void SerRelayBoard::disable_logging()
01419 {
01420         logging = false;
01421 }
01422 
01423 void SerRelayBoard::log_to_file(int direction, unsigned char cMsg[])
01424 {
01425         FILE * pFile;
01426         //Open Logfile
01427         pFile = fopen ("neo_relayboard_RX_TX_log.log","a");
01428         //Write Data to Logfile
01429         if(direction == 1)
01430         {
01431                 fprintf (pFile, "\n\n Direction: %i", direction);
01432                 for(int i=0; i<NUM_BYTE_SEND_RELAYBOARD_1_4; i++)
01433                         fprintf(pFile," %.2x", cMsg[i]);
01434                 fprintf(pFile,"\n");
01435         }
01436         if(direction == 2)
01437         {
01438                 fprintf (pFile, "\n\n Direction: %i", direction);
01439                 for(int i=0; i<NUM_BYTE_REC_RELAYBOARD_1_4; i++)
01440                         fprintf(pFile," %.2x", cMsg[i]);
01441                 fprintf(pFile,"\n");
01442         }
01443         //Close Logfile
01444         fclose (pFile);
01445 }
01446 
01447 //-----------------------------------------------
01448 void SerRelayBoard::convDataToSendMsg(unsigned char cMsg[])
01449 {
01450         int i;
01451         static int j = 0;
01452         int iCnt = 0;
01453         int iChkSum = 0;
01454 
01455         if (m_cSoftEMStop & 0x02)
01456         {
01457                 if (j == 1)
01458                 {
01459                         m_cSoftEMStop &= 0xFD;
01460                         j = 0;
01461                 }
01462                 else if (j == 0)
01463                 {
01464                         j = 1;
01465                 }
01466         }
01467 
01468         cMsg[iCnt++] = CMD_RELAISBOARD_GET_DATA;
01469 
01470         cMsg[iCnt++] = m_iConfigRelayBoard >> 8;
01471         cMsg[iCnt++] = m_iConfigRelayBoard;
01472 
01473         cMsg[iCnt++] = m_iCmdRelayBoard >> 8;
01474         cMsg[iCnt++] = m_iCmdRelayBoard;
01475 
01476         cMsg[iCnt++] = m_iIOBoardDigOut >> 8;
01477         cMsg[iCnt++] = m_iIOBoardDigOut;
01478 
01479         cMsg[iCnt++] = m_iVelCmdMotRightEncS >> 24;
01480         cMsg[iCnt++] = m_iVelCmdMotRightEncS >> 16;
01481         cMsg[iCnt++] = m_iVelCmdMotRightEncS >> 8;
01482         cMsg[iCnt++] = m_iVelCmdMotRightEncS;
01483 
01484         cMsg[iCnt++] = m_iVelCmdMotLeftEncS >> 24;
01485         cMsg[iCnt++] = m_iVelCmdMotLeftEncS >> 16;
01486         cMsg[iCnt++] = m_iVelCmdMotLeftEncS >> 8;
01487         cMsg[iCnt++] = m_iVelCmdMotLeftEncS;
01488 
01489         if(m_iTypeLCD == RELAY_BOARD_1_4)
01490         {
01491                 cMsg[iCnt++] = m_iVelCmdMotRearRightEncS >> 24;
01492                 cMsg[iCnt++] = m_iVelCmdMotRearRightEncS >> 16;
01493                 cMsg[iCnt++] = m_iVelCmdMotRearRightEncS >> 8;
01494                 cMsg[iCnt++] = m_iVelCmdMotRearRightEncS;
01495 
01496                 cMsg[iCnt++] = m_iVelCmdMotRearLeftEncS >> 24;
01497                 cMsg[iCnt++] = m_iVelCmdMotRearLeftEncS >> 16;
01498                 cMsg[iCnt++] = m_iVelCmdMotRearLeftEncS >> 8;
01499                 cMsg[iCnt++] = m_iVelCmdMotRearLeftEncS;
01500         }
01501 
01502 
01503         cMsg[iCnt++] = m_iUSBoardSensorActive >> 8;
01504         cMsg[iCnt++] = m_iUSBoardSensorActive;
01505 
01506         if(m_iTypeLCD == LCD_20CHAR_TEXT)
01507         {
01508                 for(i = 0; i < 20; i++)
01509                 {
01510                         cMsg[iCnt++] = m_cTextDisplay[i];
01511                 }
01512 
01513                 // fill remaining msg with 0's
01514                 do
01515                 {
01516                         cMsg[iCnt++] = 0;
01517                 }
01518                 while(iCnt < (m_iNumBytesSend - 2));
01519         }
01520         else
01521         {
01522                 for(i = 0; i < 60; i++)
01523                 {
01524                         cMsg[iCnt++] = m_cTextDisplay[i];
01525                 }
01526         }
01527 
01528         if(m_iTypeLCD == RELAY_BOARD_1_4)
01529         {
01530 
01531                 cMsg[iCnt++] = m_cSoftEMStop;
01532         }
01533 
01534         // calc checksum
01535         for(i = 0; i < (m_iNumBytesSend - 2); i++)
01536         {
01537                 iChkSum %= 0xFF00;
01538                 iChkSum += cMsg[i];
01539         }
01540 
01541         cMsg[m_iNumBytesSend - 2] = iChkSum >> 8;
01542         cMsg[m_iNumBytesSend - 1] = iChkSum;
01543 
01544         // reset flags
01545         m_iCmdRelayBoard &= ~CMD_RESET_POS_CNT;
01546 }
01547 
01548 //-----------------------------------------------
01549 bool SerRelayBoard::convRecMsgToData(unsigned char cMsg[])
01550 {
01551 
01552         int iNumByteRec = NUM_BYTE_REC;
01553 
01554         if(m_iTypeLCD == RELAY_BOARD_1_4)
01555         {
01556                 iNumByteRec = NUM_BYTE_REC_RELAYBOARD_1_4;
01557         }
01558 
01559         const int c_iStartCheckSum = iNumByteRec;
01560 
01561         int i;
01562         unsigned int iTxCheckSum;
01563         unsigned int iCheckSum;
01564 
01565         m_Mutex.lock();
01566 
01567         // test checksum
01568         iTxCheckSum = (cMsg[c_iStartCheckSum + 1] << 8) | cMsg[c_iStartCheckSum];
01569 
01570         iCheckSum = 0;
01571         for(i = 0; i < c_iStartCheckSum; i++)
01572         {
01573                 iCheckSum %= 0xFF00;
01574                 iCheckSum += cMsg[i];
01575         }
01576 
01577         if(iCheckSum != iTxCheckSum)
01578         {
01579                 return false;
01580         }
01581 
01582         // convert data
01583         int iCnt = 0;
01584 
01585         // RelayBoard
01586 
01587         m_iRelBoardStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01588         iCnt += 2;
01589 
01590         m_iChargeCurrent = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01591 
01592         iCnt += 2;
01593 
01594         m_iRelBoardBattVoltage = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01595         iCnt += 2;
01596 
01597         m_iRelBoardKeyPad = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01598         iCnt += 2;
01599 
01600         for(i = 0; i < 4; i++)
01601         {
01602                 m_iRelBoardIRSensor[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01603                 iCnt += 2;
01604         }
01605 
01606         m_iRelBoardTempSensor = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01607         iCnt += 2;
01608 
01609         // IOBoard
01610 
01611         m_iIOBoardDigIn = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01612         iCnt += 2;
01613 
01614         for(i = 0; i < 8; i++)
01615         {
01616                 m_iIOBoardAnalogIn[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01617                 iCnt += 2;
01618         }
01619 
01620         m_iIOBoardStatus =  (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01621         iCnt += 2;
01622 
01623         // Motion control boards
01624 
01625         m_iPosMeasMotRightEnc = cMsg[iCnt] |
01626                                                         (cMsg[iCnt + 1] << 8) |
01627                                                         (cMsg[iCnt + 2] << 16) |
01628                                                         (cMsg[iCnt + 3] << 24);
01629 
01630         m_cDebugRight[0] = cMsg[iCnt];
01631         m_cDebugRight[1] = cMsg[iCnt + 1];
01632         m_cDebugRight[2] = cMsg[iCnt + 2];
01633         m_cDebugRight[3] = cMsg[iCnt + 3];
01634 
01635         iCnt += 4;
01636 
01637         m_iVelMeasMotRightEncS =cMsg[iCnt] |
01638                                                         (cMsg[iCnt + 1] << 8) |
01639                                                         (cMsg[iCnt + 2] << 16) |
01640                                                         (cMsg[iCnt + 3] << 24);
01641         iCnt += 4;
01642 
01643         m_iPosMeasMotLeftEnc =  cMsg[iCnt] |
01644                                                         (cMsg[iCnt + 1] << 8) |
01645                                                         (cMsg[iCnt + 2] << 16) |
01646                                                         (cMsg[iCnt + 3] << 24);
01647 
01648         m_cDebugLeft[0] = cMsg[iCnt];
01649         m_cDebugLeft[1] = cMsg[iCnt + 1];
01650         m_cDebugLeft[2] = cMsg[iCnt + 2];
01651         m_cDebugLeft[3] = cMsg[iCnt + 3];
01652 
01653         iCnt += 4;
01654 
01655         m_iVelMeasMotLeftEncS = cMsg[iCnt] |
01656                                                         (cMsg[iCnt + 1] << 8) |
01657                                                         (cMsg[iCnt + 2] << 16) |
01658                                                         (cMsg[iCnt + 3] << 24);
01659         iCnt += 4;
01660 
01661         m_iMotRightStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01662         iCnt += 2;
01663 
01664         m_iMotLeftStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01665         iCnt += 2;
01666 
01667 
01668         if(m_iTypeLCD == RELAY_BOARD_1_4)
01669         {
01670                 m_iPosMeasMotRearRightEnc =     cMsg[iCnt] |
01671                                                                         (cMsg[iCnt + 1] << 8) |
01672                                                                         (cMsg[iCnt + 2] << 16) |
01673                                                                         (cMsg[iCnt + 3] << 24);
01674                 
01675                 m_cDebugRearRight[0] = cMsg[iCnt];
01676                 m_cDebugRearRight[1] = cMsg[iCnt + 1];
01677                 m_cDebugRearRight[2] = cMsg[iCnt + 2];
01678                 m_cDebugRearRight[3] = cMsg[iCnt + 3];
01679 
01680                 iCnt += 4;
01681 
01682                 m_iVelMeasMotRearRightEncS =cMsg[iCnt] |
01683                                                                         (cMsg[iCnt + 1] << 8) |
01684                                                                         (cMsg[iCnt + 2] << 16) |
01685                                                                         (cMsg[iCnt + 3] << 24);
01686         
01687                 iCnt += 4;
01688 
01689                 m_iPosMeasMotRearLeftEnc =      cMsg[iCnt] |
01690                                                                         (cMsg[iCnt + 1] << 8) |
01691                                                                         (cMsg[iCnt + 2] << 16) |
01692                                                                         (cMsg[iCnt + 3] << 24);
01693                 
01694                 m_cDebugRearLeft[0] = cMsg[iCnt];
01695                 m_cDebugRearLeft[1] = cMsg[iCnt + 1];
01696                 m_cDebugRearLeft[2] = cMsg[iCnt + 2];
01697                 m_cDebugRearLeft[3] = cMsg[iCnt + 3];
01698 
01699                 iCnt += 4;
01700 
01701                 m_iVelMeasMotRearLeftEncS = cMsg[iCnt] |
01702                                                                         (cMsg[iCnt + 1] << 8) |
01703                                                                         (cMsg[iCnt + 2] << 16) |
01704                                                                         (cMsg[iCnt + 3] << 24);         
01705                 iCnt += 4;
01706 
01707                 m_iMotRearRightStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01708                 iCnt += 2;      
01709 
01710                 m_iMotRearLeftStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01711                 iCnt += 2;
01712         }
01713 
01714         // GyroBoard
01715 
01716         m_iGyroBoardAng =       (cMsg[iCnt] << 24) |
01717                                                 (cMsg[iCnt + 1] << 16) |
01718                                                 (cMsg[iCnt + 2] << 8) |
01719                                                 cMsg[iCnt + 3];
01720         iCnt += 4;
01721 
01722         for(i = 0; i < 3; i++)
01723         {
01724                 m_iGyroBoardAcc[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01725                 iCnt += 2;
01726         }
01727 
01728         m_iGyroBoardStatus =  (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01729         iCnt += 2;
01730 
01731         // RadarBoard
01732 
01733         for(i = 0; i < 3; i++)
01734         {
01735                 m_iRadarBoardVel[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01736                 iCnt += 2;
01737         }
01738 
01739         m_iRadarBoardStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01740         iCnt += 2;
01741 
01742         // USBoard
01743 
01744         for(i = 0; i < 16; i++)
01745         {
01746                 m_iUSBoardSensorData[i] = (cMsg[iCnt++]);
01747         }
01748 
01749         for(i = 0; i < 4; i++)
01750         {
01751                 m_iUSBoardAnalogData[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01752                 iCnt += 2;
01753         }
01754 
01755         m_iUSBoardStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01756         iCnt += 2;
01757 
01758         m_Mutex.unlock();
01759 
01760         if( iCnt >= NUM_BYTE_REC_MAX )
01761         {
01762                 ROS_INFO("msg size too small");
01763         }
01764 
01765         return true;
01766 }
01767 
01768 //---------------------------------------------------------
01769 bool SerRelayBoard::convRecMsgToDataRelayBoard2(unsigned char cMsg[])
01770 {
01771         int data_in_message = 0;
01772 
01773         m_Mutex.lock();
01774 
01775         // convert data
01776         int iCnt = 0;
01777 
01778         //Has Data
01779         data_in_message = cMsg[iCnt];
01780         iCnt++;
01781         //Relayboard Status
01782         m_iRelBoardStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01783         iCnt += 2;
01784         //Charging Current
01785         m_iChargeCurrent = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01786         //std::cout << "Charging Current: " << m_iChargeCurrent << std::endl; //JNN
01787         iCnt += 2;
01788         //Charging State
01789         m_iChargeState = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01790         //std::cout << "Charging State: " << m_iChargeState << std::endl; //JNN
01791         iCnt += 2;
01792         //Battery Voltage
01793         m_iRelBoardBattVoltage = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01794         //std::cout << "Battery Voltage: " << m_iRelBoardBattVoltage << std::endl; //JNN
01795         iCnt += 2;
01796         //Keypad
01797         m_iRelBoardKeyPad = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01798         iCnt += 2;
01799         //Temp Sensor
01800         m_iRelBoardTempSensor = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01801         //std::cout << "Relayboard Temp: " << m_iRelBoardTempSensor << std::endl; //JNN
01802         iCnt += 2;
01803 
01804         // IOBoard
01805         if(m_iHasIOBoard)
01806         {
01807                 m_iIOBoardDigIn = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01808                 iCnt += 2;
01809 
01810                 for(int i = 0; i < 8; i++)
01811                 {
01812                         m_iIOBoardAnalogIn[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01813                         iCnt += 2;
01814                 }
01815 
01816                 m_iIOBoardStatus =  (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01817                 iCnt += 2;
01818         }
01819         // USBoard
01820         if(m_iHasUSBoard)
01821         {
01822                 for(int i = 0; i < 16; i++)
01823                 {
01824                         m_iUSBoardSensorData[i] = (cMsg[iCnt++]);
01825                         //std::cout << "USBoard Sensor Data " << i << ": " << m_iUSBoardSensorData[i] << std::endl; //JNN
01826                 }
01827                 for(int i = 0; i < 4; i++)
01828                 {
01829                         m_iUSBoardAnalogData[i] = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01830                         iCnt += 2;
01831                         //std::cout << "USBoard Analog Data " << i << ": " << m_iUSBoardAnalogData[i] << std::endl; //JNN
01832                 }
01833 
01834                 m_iUSBoardStatus = (cMsg[iCnt + 1] << 8) | cMsg[iCnt];
01835                 iCnt += 2;
01836                 //std::cout << "USBoard Status: " << m_iUSBoardStatus << std::endl; //JNN
01837         }
01838 
01839         m_Mutex.unlock();
01840 
01841 
01842         return true;
01843 }
01844 
01845 //------------------------------------------------------------
01846 void SerRelayBoard::convDataToSendMsgRelayBoard2(unsigned char cMsg[])
01847 {
01848         int iCnt = 0;
01849         int iChkSum = 0;
01850 
01851         int has_data = 0;
01852         int has_motor_data8 = 0;
01853         int has_motor_data4 = 0;
01854 
01855         //First Bit not in use yet
01856         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);
01857 
01858         //Data in Message:
01859         //Header
01860         cMsg[iCnt++] = 0x02;
01861         cMsg[iCnt++] = 0xD6;
01862         cMsg[iCnt++] = 0x80;
01863         cMsg[iCnt++] = 0x02;
01864         //has_data
01865         //soft_em
01866         //Motor9-6
01867         //Motor5-2
01868         //Relaystates
01869         //LCD Data
01870         //IO Data
01871         //US Data
01872         //Speaker Data
01873         //Checksum
01874         cMsg[iCnt++] = has_data;
01875         cMsg[iCnt++] = m_cSoftEMStop; //SoftEM
01876 
01877         //Relaystates
01878         if(m_ihasRelayData)
01879         {
01880                 cMsg[iCnt++] = m_iCmdRelayBoard >> 8;
01881                 cMsg[iCnt++] = m_iCmdRelayBoard;
01882         }
01883         //LCD Data
01884         if(m_ihas_LCD_DATA)
01885         {
01886                 for(int u = 0; u < 20; u++)
01887                 {
01888                         cMsg[iCnt++] = m_cTextDisplay[u];
01889                 }
01890         }
01891         //IO Data
01892         if(m_iHasIOBoard)
01893         {
01894                 cMsg[iCnt++] = m_iIOBoardDigOut >> 8;
01895                 cMsg[iCnt++] = m_iIOBoardDigOut;
01896         }
01897         //US Data
01898         if(m_iHasUSBoard)
01899         {
01900                 cMsg[iCnt++] = m_iUSBoardSensorActive >> 8;
01901                 cMsg[iCnt++] = m_iUSBoardSensorActive;
01902         }
01903         //Speaker Data
01904         if(m_iHasSpeakerData)
01905         {
01906                 cMsg[iCnt++] = 0 >> 8;
01907                 cMsg[iCnt++] = 0;
01908         }
01909         // calc checksum
01910         for(int i = 4; i < (m_iNumBytesSend - 2); i++)
01911         {
01912                 iChkSum %= 0xFF00;
01913                 iChkSum += cMsg[i];
01914         }
01915 
01916         cMsg[iCnt++] = iChkSum >> 8;
01917         cMsg[iCnt++] = iChkSum;
01918         m_iNumBytesSend = iCnt;
01919 }
01920 


neo_relayboard
Author(s): Jan-Niklas Nieland
autogenerated on Thu Jun 6 2019 21:37:07