Facebook
From RSLIDAR Systems, 3 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 65
  1. /*
  2. *  RSLIDAR System
  3. *  Driver Interface
  4. *
  5. *  Copyright 2015 RS Team
  6. *  All rights reserved.
  7. *
  8. *       Author: ruishi, Data:2015-12-25
  9. *
  10. */
  11. #include <time.h>
  12. #include "sdkcommon.h"
  13. #include "hal/abs_rxtx.h"
  14. #include "hal/thread.h"
  15. #include "hal/locker.h"
  16. #include "hal/event.h"
  17. #include "rslidar_driver_serial.h"
  18.  
  19.  
  20. //#include <ioctl.h>
  21. using namespace std;
  22. #ifndef min
  23. #define min(a,b)            (((a) < (b)) ? (a) : (b))
  24. #endif
  25.  
  26. namespace rs { namespace standalone{ namespace rslidar {
  27.  
  28.  
  29. // Factory Impl
  30. RSlidarDriver * RSlidarDriver::CreateDriver()
  31. {
  32.     return new RSlidarDriverSerialImpl();
  33. }
  34.  
  35.  
  36. void RSlidarDriver::DisposeDriver(RSlidarDriver * drv)
  37. {
  38.     delete drv;
  39. }
  40.  
  41. // Serial Driver Impl
  42.  
  43. RSlidarDriverSerialImpl::RSlidarDriverSerialImpl(): _isConnected(false), _isScanning(false)
  44. {
  45.     _rxtx = rs::hal::serial_rxtx::CreateRxTx();
  46.         _flag_cached_scan_node_ping_pong = NOTE_BUFFER_PING;
  47.         memset(_cached_scan_note_bufferPing, 0, sizeof(_cached_scan_note_bufferPing));
  48.         memset(_cached_scan_note_bufferPong, 0, sizeof(_cached_scan_note_bufferPong));
  49.     _cached_scan_node_count = 0;
  50.         RunningStates = PORT_RDY;
  51. }
  52.  
  53. RSlidarDriverSerialImpl::~RSlidarDriverSerialImpl()
  54. {
  55.     disconnect();
  56.     rs::hal::serial_rxtx::ReleaseRxTx(_rxtx);
  57. }
  58.  
  59. u_result RSlidarDriverSerialImpl::connect(const char * port_path, _u32 baudrate, _u32 flag)
  60. {
  61.     rs::hal::AutoLocker l(_lock);
  62.     if (isConnected()) return RESULT_ALREADY_DONE;
  63.  
  64.     if (!_rxtx) return RESULT_INSUFFICIENT_MEMORY;
  65.  
  66.     // establish the serial connection...
  67.     if (!_rxtx->bind(port_path, baudrate)  ||  !_rxtx->open()) {
  68.         return RESULT_INVALID_DATA;
  69.     }
  70.  
  71.     _rxtx->flush(0);
  72.     _isConnected = true;
  73.  
  74.         _isGetData = true;
  75.     return RESULT_OK;
  76. }
  77.  
  78. void RSlidarDriverSerialImpl::disconnect()
  79. {
  80.     if (!_isConnected) return ;
  81.                 stopScan();
  82.     _rxtx->close();
  83. }
  84.  
  85. bool RSlidarDriverSerialImpl::isConnected()
  86. {
  87.     return _isConnected;
  88. }
  89.  
  90. u_result RSlidarDriverSerialImpl::_cacheSerialData()
  91. {
  92.         return RESULT_OK;
  93. }
  94.  
  95.  
  96. u_result RSlidarDriverSerialImpl::resetlidar(_u32 timeout)
  97. {
  98.         _u8 param = 0x08;
  99.     u_result ans;
  100.         COMM_FRAME_T *response_header = reinterpret_cast<COMM_FRAME_T *>(_paramReceiveBuf);
  101.  
  102.         if (!isConnected()) return RESULT_OPERATION_FAIL;
  103.  
  104.         _disableDataGrabbing();
  105.  
  106.         {
  107.                 rs::hal::AutoLocker l(_lock);
  108.                 param = RESET_MODE;
  109.                 if (IS_FAIL(ans = _sendCommand(CMD_WORK_MODE, &param, 1))) {
  110.                         return ans;
  111.                 }
  112.  
  113.                 if (IS_FAIL(ans = _waitResponseHeader(response_header, CMD_WORK_MODE, NULL,1, timeout))) {
  114.                         return ans;
  115.                 }
  116.  
  117.                 if ((response_header->command&COMM_FRAME_ERROR) > 0)
  118.                 {
  119.                         return *(response_header->paramBuf);
  120.                 }
  121.         }
  122.  
  123.         return RESULT_OK;
  124. }
  125.  
  126. u_result RSlidarDriverSerialImpl::setMotorRpm(_u16 speed, _u32 timeout)
  127. {
  128.         _u8 Data[] = { 0x23,0x01,0x67,0x45,0xAB,0x89,0xEF,0xCD,0x00,0x00};
  129.         u_result ans;
  130.         COMM_FRAME_T *response_header = reinterpret_cast<COMM_FRAME_T *>(_paramReceiveBuf);
  131.  
  132.         Data[8] = speed;
  133.         Data[9] = speed >> 8;
  134.  
  135.         if (!isConnected()) return RESULT_OPERATION_FAIL;
  136.  
  137.         //_disableDataGrabbing();
  138.  
  139.         {
  140.                 //rs::hal::AutoLocker l(_lock);
  141.  
  142.                 if (IS_FAIL(ans = _sendCommand(CMD_SET_MOTOR_SPEED, &Data, 10))) {
  143.                         return ans;
  144.                 }
  145.  
  146.                 if (IS_FAIL(ans = _waitResponseHeader(response_header, CMD_SET_MOTOR_SPEED, NULL,1, timeout))) {
  147.                         return ans;
  148.                 }
  149.  
  150.                 if ((response_header->command&COMM_FRAME_ERROR) > 0)
  151.                 {
  152.                         return (*(response_header->paramBuf));
  153.                 }
  154.         }
  155.  
  156.         return RESULT_OK;
  157. }
  158.  
  159. u_result RSlidarDriverSerialImpl::getDeviceInfo(LIDAR_RESPONSE_DEV_INFO_T * info, _u32 timeout)
  160. {
  161.         u_result  ans;
  162.         COMM_FRAME_T *response_header = reinterpret_cast<COMM_FRAME_T *>(_paramReceiveBuf);
  163.  
  164.         if (!isConnected()) return RESULT_OPERATION_FAIL;
  165.  
  166.         _disableDataGrabbing();
  167.  
  168.         {
  169.                 rs::hal::AutoLocker l(_lock);
  170.                 if (IS_FAIL(ans = _sendCommand(CMD_READ_DEV_VER, NULL, 0))) {
  171.                         return ans;
  172.                 }
  173.  
  174.                 if (IS_FAIL(ans = _waitResponseHeader(response_header, CMD_READ_DEV_VER, NULL,45, timeout))) {
  175.                         return ans;
  176.                 }
  177.  
  178.                 if ((response_header->command&COMM_FRAME_ERROR) > 0)
  179.                 {
  180.                         return (*(response_header->paramBuf));
  181.                 }
  182.  
  183.                 memcpy(info, response_header->paramBuf, response_header->paramLen);
  184.         }
  185.         return RESULT_OK;
  186. }
  187.  
  188. u_result RSlidarDriverSerialImpl::startScan(_u8 scanmode,_u32 timeout)
  189. {
  190.         _u8 param = scanmode;
  191.         u_result ans;
  192.         COMM_FRAME_T *response_header = reinterpret_cast<COMM_FRAME_T *>(_paramReceiveBuf);
  193.  
  194.         if (!isConnected()) return RESULT_OPERATION_FAIL;
  195.         if (_isScanning) return RESULT_ALREADY_DONE;
  196.  
  197.         {
  198.                 rs::hal::AutoLocker l(_lock);
  199.                 _rxtx->flush(0);
  200.                 if (IS_FAIL(ans = _sendCommand(CMD_WORK_MODE, &param, 1))) {
  201.                         return ans;
  202.                 }
  203.                
  204.                 /*if (IS_FAIL(ans = _waitResponseHeader(response_header, CMD_WORK_MODE, NULL, 1, timeout))) {
  205.                         return ans;
  206.                 }
  207.        
  208.                 if ((response_header->command&COMM_FRAME_ERROR) > 0)
  209.                 {
  210.                         return (*(response_header->paramBuf));
  211.                 }
  212.                 */
  213.                 _isScanning = true;
  214.                 _cachethread = CLASS_THREAD(RSlidarDriverSerialImpl, _cacheScanData);
  215.         }
  216.  
  217.         return RESULT_OK;
  218. }
  219.  
  220.  
  221. u_result RSlidarDriverSerialImpl::stopScan(_u32 timeout)
  222. {
  223.         _u8 param = 0x00;
  224.         u_result ans;
  225.         COMM_FRAME_T *response_header = reinterpret_cast<COMM_FRAME_T *>(_paramReceiveBuf);
  226.  
  227.         if (!isConnected()) return RESULT_OPERATION_FAIL;
  228.  
  229.         _disableDataGrabbing();
  230.  
  231.         {
  232.                 rs::hal::AutoLocker l(_lock);
  233.  
  234.                 if (IS_FAIL(ans = _sendCommand(CMD_WORK_MODE,&param,1))) {
  235.                         return ans;
  236.                 }
  237.  
  238.                 if (IS_FAIL(ans = _waitResponseHeader(response_header, CMD_WORK_MODE, NULL,1, timeout))) {
  239.                         return ans;
  240.                 }
  241.  
  242.                 if ((response_header->command&COMM_FRAME_ERROR) > 0)
  243.                 {
  244.                         return (*(response_header->paramBuf));
  245.                 }
  246.         }
  247.  
  248.         return RESULT_OK;
  249. }
  250.  
  251. u_result RSlidarDriverSerialImpl::_cacheScanData()
  252. {
  253.         LIDAR_MEASURE_INFO_T                            *local_buf = NULL;
  254.         size_t                              count = NUMBER_OF_TEETH;
  255.         size_t                              scan_count = 0;
  256.         u_result                            ans;
  257.  
  258.         _flag_cached_scan_node_ping_pong = NOTE_BUFFER_PING;
  259.         local_buf = _cached_scan_note_bufferPong;
  260.         _waitScanData(local_buf, count); // // always discard the first data since it may be incomplete
  261.         count = NUMBER_OF_TEETH;
  262.  
  263.         while (_isScanning)
  264.         {
  265.                 if (IS_FAIL(ans = _waitScanData(local_buf, count))) {
  266.                         if (!((ans == RESULT_OPERATION_TIMEOUT) || (ans == RESULT_RECEIVE_NODE_ERROR))) {
  267.                                 _isScanning = false;
  268.                                 return RESULT_OPERATION_FAIL;
  269.                         }
  270.                 }
  271.  
  272.                 _lock.lock();
  273.                 _flag_cached_scan_node_ping_pong = _flag_cached_scan_node_ping_pong ^ 0x01;
  274.                 if (NOTE_BUFFER_PING == _flag_cached_scan_node_ping_pong)
  275.                 {
  276.                         local_buf = _cached_scan_note_bufferPong;
  277.                 }
  278.                 else if (NOTE_BUFFER_PONG == _flag_cached_scan_node_ping_pong)
  279.                 {
  280.                         local_buf = _cached_scan_note_bufferPing;
  281.                 }
  282.                 else{}
  283.                 _cached_scan_node_count = count;
  284.                 _dataEvt.set();
  285.                 _lock.unlock();
  286.                 count = NUMBER_OF_TEETH;
  287.         }
  288.         _isScanning = false;
  289.         return RESULT_OK;
  290. }
  291.  
  292. u_result RSlidarDriverSerialImpl::_waitScanData(LIDAR_MEASURE_INFO_T * nodebuffer, size_t & count, _u32 timeout)
  293. {
  294.         _u8             recvBuffer[1024];
  295.         _u16    frameLens = 0;
  296.         _u16    paramLens = 0;
  297.         _u16    angleRange = 0;
  298.         float   angleStep = 0;
  299.         float  speed;
  300.         float  angleoffset;
  301.         bool    flagOfNewNodes = false;
  302.         _u16    crcCheckNum = 0,calcchecksum;
  303.         _u16    sampleNumber = 0;
  304.         _u16    sampleNumberCount = 0;
  305.  
  306.         if (!_isConnected) {
  307.                 count = 0;
  308.                 return RESULT_OPERATION_FAIL;
  309.         }
  310.  
  311.         size_t   recvNodeCount = 0;
  312.         _u32     startTs = getms();
  313.         _u32     waitTime;
  314.         u_result ans;
  315.  
  316.  
  317.         while ((waitTime = getms() - startTs) <= timeout && recvNodeCount < count)
  318.         {
  319.                 if (IS_FAIL(ans = _waitNode(recvBuffer, timeout - waitTime)))
  320.                 {
  321.                         return ans;
  322.                 }
  323.  
  324.                 frameLens = (recvBuffer[2] << 8) | recvBuffer[1];
  325.                 crcCheckNum = *(_u16 *)(recvBuffer + frameLens);
  326.                 calcchecksum = _checksum(recvBuffer, frameLens);
  327.                 angleRange = (recvBuffer[10] << 8) | recvBuffer[9];
  328.  
  329.                 if (crcCheckNum == calcchecksum)
  330.                 {
  331.                         paramLens = (recvBuffer[6] << 8) | recvBuffer[5];
  332.                         sampleNumber = (paramLens - 4) / 2;
  333.                         if ((angleRange >= 35000) || (angleRange <= 100))  //find original point
  334.                         {
  335.                                 flagOfNewNodes = true;
  336.                                 recvNodeCount = 0;
  337.                                 sampleNumberCount = 0;
  338.                                 angleStep = 36000.0 / sampleNumber / NUMBER_OF_TEETH;
  339.                         }
  340.  
  341.                         if (flagOfNewNodes)
  342.                         {
  343.                                 speed = ((recvBuffer[8] << 8) | recvBuffer[7])*0.01;
  344.                                 angleoffset = 0;
  345.  
  346.                                 for (int i = 0; i < sampleNumber; i++)
  347.                                 {
  348.                                         (nodebuffer + sampleNumberCount)->motorspeed = speed;
  349.                                         (nodebuffer + sampleNumberCount)->angle = angleRange + i * angleStep;
  350.                                         (nodebuffer + sampleNumberCount)->angleoffset = angleoffset;
  351.                                         (nodebuffer + sampleNumberCount)->distance = (recvBuffer[12 + i * 2] << 8) | recvBuffer[11 + i * 2];
  352.                                 //      printf("this is my shared data somehow");
  353.                                         printf("test \n");
  354.                                         sampleNumberCount++;
  355.                                 }
  356.                                 recvNodeCount++;
  357.                         }                      
  358.                 }
  359.                 else
  360.                 {
  361.                         RunningStates = CHKSUM_ERROR;
  362.                         continue;
  363.                 }
  364.  
  365.                 if (recvNodeCount == count)
  366.                 {
  367.                         flagOfNewNodes = false;
  368.                         count = sampleNumberCount;
  369.                         return RESULT_OK;
  370.                 }
  371.         }
  372.  
  373.         //CLogout("_waitScanData002:%d \r\n", sampleNumberCount);
  374.         count = sampleNumberCount;
  375.         return RESULT_OPERATION_TIMEOUT;
  376. }
  377.  
  378. u_result RSlidarDriverSerialImpl::_waitNode(_u8 * nodeBuffer, _u32 timeout)
  379. {
  380.         int             recvPos = 0;
  381.         _u32    startTs = getms();
  382.         _u8             recvBuffer[512];
  383.         _u32    waitTime;
  384.         _u16    frameLens = 0;
  385.         size_t  recvSize;
  386.         size_t  remainSize;
  387.         size_t  pos;
  388.         bool    frameDataRcvFlag = false;
  389.        
  390.        
  391.         char tmp_message[100];
  392.         memset(tmp_message, 0, 100);
  393.  
  394.         while ((waitTime = getms() - startTs) <= timeout) {
  395.  
  396.                 if (false == frameDataRcvFlag)
  397.                 {
  398.                         //receive head info
  399.                         remainSize = sizeof(COMM_FRAME_T) - recvPos;
  400.                 }
  401.                 else
  402.                 {
  403.                         //receive data
  404.                         remainSize = frameLens + 2 - recvPos;
  405.                 }
  406.                 recvSize = 0;
  407.                 //printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  408.                 int ans = _rxtx->waitfordata(remainSize, timeout, &recvSize);
  409.  
  410.                 if (ans == rs::hal::serial_rxtx::ANS_DEV_ERR)
  411.                 {
  412.                         return RESULT_OPERATION_FAIL;
  413.                 }
  414.  
  415.                 if ((ans == rs::hal::serial_rxtx::ANS_TIMEOUT) && (0 == recvSize))
  416.                 {
  417.                         GetLocalTime(&tm_time_out);
  418.                         int tm_cha = ((tm_time_out.wMinute - tm_error_frame.wMinute) * 60 + (tm_time_out.wSecond - tm_error_frame.wSecond)) * 1000 + (tm_time_out.wMilliseconds - tm_error_frame.wMilliseconds);
  419.                         if (tm_cha > 500)
  420.                         {
  421.                                 _cprintf("[Eror]: Receive data timeout!\r\n");
  422.                                 RunningStates = RX_DATA_TIMOUT;
  423.                                 continue;
  424.                         }
  425.                 }
  426.                 if (recvSize > remainSize) recvSize = remainSize;
  427.                 _rxtx->recvdata(recvBuffer, recvSize);
  428.                 for (pos = 0; pos < recvSize; ++pos)
  429.                 {
  430.                         _u8 currentByte = recvBuffer[pos];
  431.  
  432.                         if (0 == recvPos)
  433.                         {
  434.                                 if (COMM_HEAD_FLAGE != currentByte)
  435.                                 {
  436.                                         frameDataRcvFlag = false;
  437.                                         continue;
  438.                                 }
  439.                         }
  440.                         else if (4 == recvPos)
  441.                         {
  442.                                 frameLens = (nodeBuffer[2] << 8) | nodeBuffer[1];
  443.                                 //if ((frameLens > 300) || (recvPos < (sizeof(COMM_FRAME_T) - 1)))
  444.                                 if (frameLens > 300)
  445.                                 {
  446.                                         recvPos = 0;
  447.                                         frameLens = 0;
  448.                                         frameDataRcvFlag = false;
  449.                                         continue;
  450.                                 }
  451.                                 else
  452.                                         frameDataRcvFlag = true;
  453.  
  454.                                 if (CMD_REPORT_DEV_ERROR == (currentByte&COMM_MASK))
  455.                                 {
  456.                                         RunningStates = MOTOR_STALL;
  457.                                         continue;                                      
  458.                                 }
  459.  
  460.                                 if (CMD_REPORT_DIST != (currentByte&COMM_MASK))
  461.                                         continue;
  462.                         }
  463.  
  464.                         nodeBuffer[recvPos++] = currentByte;
  465.  
  466.                         if ((recvPos >= (frameLens + 2))&&(recvPos > sizeof(COMM_FRAME_T)))
  467.                         {
  468.                                 RunningStates = WORK_WELL;
  469.                                 return RESULT_OK;
  470.                         }
  471.                 }
  472.         }
  473.         return RESULT_OPERATION_TIMEOUT;
  474. }
  475.  
  476. u_result RSlidarDriverSerialImpl::grabScanData(LIDAR_MEASURE_INFO_T * nodebuffer, size_t & count, _u32 timeout)
  477. {
  478.     switch (_dataEvt.wait(timeout))
  479.     {
  480.                 case rs::hal::Event::EVENT_TIMEOUT:
  481.                         count = 0;
  482.                         return RESULT_OPERATION_TIMEOUT;
  483.                         break;
  484.  
  485.                 case rs::hal::Event::EVENT_OK:
  486.                         {
  487.                                 rs::hal::AutoLocker l(_lock);
  488.  
  489.                                 size_t size_to_copy = min(count, _cached_scan_node_count);
  490.  
  491.                                 if (NOTE_BUFFER_PING == _flag_cached_scan_node_ping_pong)
  492.                                 {
  493.                                         memcpy(nodebuffer, _cached_scan_note_bufferPing, size_to_copy*sizeof(LIDAR_MEASURE_INFO_T));
  494.                                 }
  495.                                 else if (NOTE_BUFFER_PONG == _flag_cached_scan_node_ping_pong)
  496.                                 {
  497.                                         memcpy(nodebuffer, _cached_scan_note_bufferPong, size_to_copy*sizeof(LIDAR_MEASURE_INFO_T));
  498.                                 }
  499.  
  500.                                 count = size_to_copy;
  501.                                 _cached_scan_node_count = 0;
  502.                         }
  503.                         return RESULT_OK;
  504.                         break;
  505.  
  506.                 default:
  507.                         count = 0;
  508.                         return RESULT_OPERATION_FAIL;
  509.                         break;
  510.     }
  511.  
  512. }
  513.  
  514. u_result RSlidarDriverSerialImpl::ascendScanData(LIDAR_MEASURE_INFO_T * nodebuffer, size_t count)
  515. {
  516.     float inc_origin_angle = 360.0/count;
  517.     int i = 0;
  518.  
  519.     //Tune head
  520.     for (i = 0; i < count; i++) {
  521.         if(nodebuffer[i].distance == 0) {
  522.             continue;
  523.         } else {
  524.             while(i != 0) {
  525.                 i--;
  526.                 float expect_angle = (nodebuffer[i+1].angle)/100.0f - inc_origin_angle;
  527.                 if (expect_angle < 0.0f) expect_angle = 0.0f;
  528.                                 nodebuffer[i].angle = (_u16)(expect_angle * 100.0f);
  529.             }
  530.             break;
  531.         }
  532.     }
  533.  
  534.     // all the data is invalid
  535.     if (i == count) return RESULT_OPERATION_FAIL;
  536.  
  537.     //Tune tail
  538.     for (i = count - 1; i >= 0; i--) {
  539.                 if (nodebuffer[i].distance == 0) {
  540.             continue;
  541.         } else {
  542.             while(i != (count - 1)) {
  543.                 i++;
  544.                                 float expect_angle = (nodebuffer[i - 1].angle) / 100.0f + inc_origin_angle;
  545.                 if (expect_angle > 360.0f) expect_angle -= 360.0f;
  546.                                 nodebuffer[i].angle = (_u16)(expect_angle * 100.0f);
  547.             }
  548.             break;
  549.         }
  550.     }
  551.  
  552.     //Fill invalid angle in the scan
  553.         float frontAngle = (nodebuffer[0].angle) / 100.0f;
  554.     for (i = 1; i < count; i++) {
  555.                 if (nodebuffer[i].distance == 0) {
  556.             float expect_angle =  frontAngle + i * inc_origin_angle;
  557.             if (expect_angle > 360.0f) expect_angle -= 360.0f;
  558.                         nodebuffer[i].angle = (_u16)(expect_angle * 100.0f);
  559.         }
  560.     }
  561.  
  562.     // Reorder the scan according to the angle value
  563.     for (i = 0; i < (count-1); i++){
  564.         for (int j = (i+1); j < count; j++){
  565.                         if (nodebuffer[i].angle > nodebuffer[j].angle){
  566.                                 LIDAR_MEASURE_INFO_T temp = nodebuffer[i];
  567.                 nodebuffer[i] = nodebuffer[j];
  568.                 nodebuffer[j] = temp;
  569.             }
  570.         }
  571.     }
  572.  
  573.     return RESULT_OK;
  574. }
  575.  
  576. u_result RSlidarDriverSerialImpl::_sendCommand(_u8 cmd, const void * payload, size_t payloadsize)
  577. {
  578.         _u16 checksum = 0;
  579.         _u8 commBuf[1024] = {0};
  580.         COMM_FRAME_T *commFrameTmp = reinterpret_cast<COMM_FRAME_T *>(commBuf);
  581.         const _u8 *pPayload = reinterpret_cast<const _u8 *>(payload);
  582.  
  583.         if (!_isConnected) return RESULT_OPERATION_FAIL;
  584.  
  585.         commFrameTmp->framehead = COMM_HEAD_FLAGE;
  586.         commFrameTmp->frameLen = sizeof(COMM_FRAME_T)+payloadsize;
  587.         commFrameTmp->protocolver = 4;
  588.         commFrameTmp->command = cmd;
  589.         if (payloadsize && payload) {
  590.                 commFrameTmp->paramLen = payloadsize;
  591.         }
  592.         else
  593.         {
  594.                 commFrameTmp->paramLen = 0;
  595.         }
  596.         if (payloadsize > 0)
  597.         {
  598.                 for (int i = payloadsize-1; i >= 0; i--)
  599.                         *(commFrameTmp->paramBuf+i) = *(pPayload+i);
  600.         }
  601.  
  602.         checksum = _checksum(commBuf, sizeof(COMM_FRAME_T) + payloadsize);
  603.        
  604.         commBuf[sizeof(COMM_FRAME_T)+payloadsize] = checksum;
  605.         commBuf[sizeof(COMM_FRAME_T)+payloadsize + 1] = checksum >> 8;
  606.  
  607.         // send header first
  608.         for (int i = 0; i < (sizeof(COMM_FRAME_T)+payloadsize + sizeof(_u16));i++)
  609.                 printf("%02x ", commBuf[i]);
  610.         printf("\n");
  611.         _rxtx->senddata(commBuf, sizeof(COMM_FRAME_T)+payloadsize + sizeof(_u16));
  612.         return RESULT_OK;
  613. }
  614.  
  615.  
  616. u_result RSlidarDriverSerialImpl::_waitResponseHeader(COMM_FRAME_T * header, _u8 Cmmd,const void * payload, size_t payloadsize, _u32 timeout)
  617. {
  618.         _u8 Data[512];
  619.         int  recvPos = 0,readPos = 0,i;
  620.         _u32 startTs = getms();
  621.         _u8  *headerBuffer = reinterpret_cast<_u8 *>(header);
  622.         _u32 waitTime;
  623.         _u16 framelen,checksumCac, checksumRcv;
  624.         size_t remainSize = sizeof(COMM_FRAME_T) + payloadsize + sizeof(_u16);
  625.         size_t recvSize;
  626.  
  627.         while ((waitTime = getms() - startTs) <= timeout)
  628.         {
  629.                 int ans = _rxtx->waitfordata(remainSize, timeout - waitTime, &recvSize);
  630.                 if (ans == rs::hal::serial_rxtx::ANS_DEV_ERR)
  631.                 {
  632.                         return RESULT_OPERATION_FAIL;
  633.                 }
  634.                 else if (ans == rs::hal::serial_rxtx::ANS_TIMEOUT)
  635.                 {
  636.                         return RESULT_OPERATION_TIMEOUT;
  637.                 }
  638.  
  639.                 if (recvSize > (sizeof(Data) - (recvPos & 0x1FF)))
  640.                 {
  641.                         _rxtx->recvdata(&Data[recvPos & 0x1FF], sizeof(Data) - (recvPos & 0x1FF));
  642.                         _rxtx->recvdata(Data,recvSize - sizeof(Data) + (recvPos & 0x1FF));
  643.                 }
  644.                 else
  645.                         _rxtx->recvdata(&Data[recvPos & 0x1FF], recvSize);
  646.  
  647.                 recvPos += recvSize;
  648.                 if ((readPos + remainSize) > recvPos)
  649.                         continue;
  650.                 else
  651.                 {
  652.                         for (; readPos < recvPos; readPos++)
  653.                         {
  654.                                 if (Data[readPos & 0x1FF] != COMM_HEAD_FLAGE)
  655.                                         continue;
  656.                                 else
  657.                                 {
  658.                                         framelen = (Data[(readPos + 2) & 0x1FF] << 8) | Data[(readPos + 1) & 0x1FF];
  659.                                         if (framelen > 100)
  660.                                                 continue;
  661.  
  662.                                         if ((framelen + 2) > (recvPos - readPos))
  663.                                                 break;
  664.  
  665.                                         if ((Data[(readPos + 4) & 0x1FF]&COMM_MASK) != Cmmd)
  666.                                                 continue;
  667.  
  668.                                         checksumCac = _Cyclechecksum(Data,readPos,framelen,sizeof(Data));
  669.                                         checksumRcv = (Data[(readPos + framelen + 1) & 0x1FF] << 8) | Data[(readPos + framelen) & 0x1FF];
  670.                                         if (checksumCac == checksumRcv)
  671.                                         {
  672.                                                 for (i = 0; i < (payloadsize + sizeof(COMM_FRAME_T)); i++)
  673.                                                 {
  674.                                                         *headerBuffer++ = Data[(readPos + i) & 0x1FF];
  675.                                                 }
  676.                                                 return RESULT_OK;
  677.                                         }
  678.                                         else
  679.                                                 return RESULT_INVALID_DATA;
  680.                                 }
  681.                         }
  682.                 }
  683.         }
  684.         return RESULT_OPERATION_TIMEOUT;
  685. }
  686.  
  687. uint16_t RSlidarDriverSerialImpl::_Cyclechecksum(uint8_t *startByte, _u32 pos,uint16_t numBytes,_u32 buffersize)
  688. {
  689.         uint16_t checksum = 0;                           // CRC���ұ��ָ��
  690.         while (numBytes--)
  691.         {
  692.                 checksum += *(startByte + (pos%buffersize));      // ����CRC
  693.                 pos++;
  694.         }
  695.         return checksum;
  696. }
  697.  
  698. uint16_t RSlidarDriverSerialImpl::_checksum(uint8_t *startByte, uint16_t numBytes)
  699. {
  700.         uint16_t checksum = 0;                           // CRC���ұ��ָ��
  701.         while (numBytes--)
  702.         {
  703.                 checksum += *startByte++;      // ����CRC
  704.         }
  705.         return checksum;
  706. }
  707.  
  708. void RSlidarDriverSerialImpl::_disableDataGrabbing()
  709. {
  710.     _isScanning = false;
  711.     _cachethread.join();
  712.         _rxtx->flush(0);
  713. }
  714.  
  715. }}}
  716.  
  717.