Ros

rplider(思岚雷达)

硬件:思岚RPLIDAR A1M8

一、接收雷达数据

接收数据用的是一个新线程。根据不同扫描模式会用不同线程函数,针对RPLIDAR A1M8是RPlidarDriverImplCommon::_cacheUltraCapsuledScanData。启动时机是在向rplidar发送开始扫描命令时。

1.1 _waitUltraCapsuledNode

u_result RPlidarDriverImplCommon::_waitUltraCapsuledNode(rplidar_response_ultra_capsule_measurement_nodes_t & node, _u32 timeout)

从串口接收一个胶囊字节数(132字节),数据存放在node。

  • @node。收到的数据放到这个node。sizeof(rplidar_response_ultra_capsule_measurement_nodes_t)=132。
  • @timeout。接收此个node数据的溢出时间。默认2秒。2秒内没收完这个node,返回RESULT_OPERATION_TIMEOUT。
  • 返回值。1)RESULT_OK:成功。2)RESULT_OPERATION_TIMEOUT:接收时间超过了timeout。3)RESULT_INVALID_DATA:132字节是收全了,但较验失败。

1.2 _ultraCapsuleToNormal

typedef struct rplidar_response_measurement_node_hq_t {
    _u16   angle_z_q14; 
    _u32   dist_mm_q2; 
    _u8    quality;  
    _u8    flag;
} __attribute__((packed)) rplidar_response_measurement_node_hq_t;

void RPlidarDriverImplCommon::_ultraCapsuleToNormal(const rplidar_response_ultra_capsule_measurement_nodes_t & capsule, rplidar_response_measurement_node_hq_t *nodebuffer, size_t &nodeCount)

直接从串口收到的数据用了思岚自个的压缩算法,_ultraCapsuleToNormal负责进行解压缩,解压缩后的数据放在nodebuffer。nodebuffer是个数组,一个nodebuffer单元字节数sizeof(rplidar_response_measurement_node_hq_t),所以解压缩一个132字节胶囊后会得到多个nodebuffer,参数nodeCount记录了这个数目。

[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[生成一帧]commit one, scan_count(1083) * sizeof(rplidar_response_measurement_node_hq_t)(8) = 8664

[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[_ultraCapsuleToNormal]sizeof(ultra_capsule_node): 132, sizeof(rplidar_response_measurement_node_hq_t): 8, count: 96
[生成一帧]commit one, scan_count(1082) * sizeof(rplidar_response_measurement_node_hq_t)(8) = 8656

上面是数次解压缩,并形成帧。它显示了两帧,第一帧1083圈,一帧8664字节。第二帧1882圈,一帧8656字节。从上面可看出,一个132字节胶囊解压缩后可得到8圈768字节(8*96)。

综上所述,数据线程把数据以着一圈圈放在了(_cached_scan_node_hq_buf, _cached_scan_node_hq_count)。_cached_scan_node_hq_buf是个数组,元素类型是rplidar_response_measurement_node_hq_t。cached_scan_node_hq_count就圈数,值可能像1083、1082等。知道这个结果后,就能很快理解main线程调用的grabScanDataHq。

1.3 grabScanDataHq

u_result RPlidarDriverImplCommon::grabScanDataHq(rplidar_response_measurement_node_hq_t * nodebuffer, size_t & count, _u32 timeout)
{
    if (!_dataEvt.Wait(timeout)) {
        // rp::hal::Event::EVENT_TIMEOUT
        count = 0;
        return RESULT_OPERATION_TIMEOUT;
    } else {
        // rp::hal::Event::EVENT_OK:
        if (_cached_scan_node_hq_count == 0) return RESULT_OPERATION_TIMEOUT; //consider as timeout

        threading::lock l(_lock);

        size_t size_to_copy = min(count, _cached_scan_node_hq_count);
        memcpy(nodebuffer, _cached_scan_node_hq_buf, size_to_copy * sizeof(rplidar_response_measurement_node_hq_t));

        count = size_to_copy;
        _cached_scan_node_hq_count = 0;
    }
    return RESULT_OK;
}

_cached_scan_node_hq_count不等0,意味着数据线程收到新数据,grabScanDataHq反这些数据复制到nodebuffer,count存储着圈数。复制完后,_cached_scan_node_hq_count置0,保证下次grabScanDataHq得到的会是新数据。

 

全部评论: 0

    写评论: