首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用MATLAB处理多个Slamtec LIDAR连接问题

用MATLAB处理多个Slamtec LIDAR连接问题
EN

Stack Overflow用户
提问于 2020-05-19 19:20:56
回答 1查看 355关注 0票数 0

我遇到了一些初始的LIDAR连接问题,同时使用MATALB连接4个Slamtec A3和这里提供的接口库:https://github.com/ENSTABretagneRobotics/Hardware-MATLAB

问题是,在连接之前,我必须在至少一个LIDARS上重新尝试连接。它也可以随LIDAR而变化,也就是说。也就是说,除了一个LIDAR,所有的LIDAR都是第一次连接。一次,可能是一个COM端口上的LIDAR,另一次可能是另一个COM端口上的LIDAR。

这就是现在设置的方式。基本上,MATALB加载提供的接口库hardwarex.dll。它公开了一些要由MATLAB使用的库方法。

连接LIDAR的方法如下:

  1. 打开RS232端口
  2. Sets端口选项
  3. 获得一些信息和健康状态来自于激光雷达
  4. 将马达PWM设置为零(停止激光雷达马达)

H 111使用快速扫描模式选项H 212g 213

在这里的某个地方,通讯会出错。使用串行嗅探器,我能够看到LIDAR在向LIDAR发出以下消息之后出现了错误:

代码语言:javascript
复制
a5 f0 02   ff 03 ab   a5 25   a5 82 05 00 00 00 00 00 22

按照这个顺序,我跟踪到以下库方法:

代码语言:javascript
复制
SetMotorPWMRequestRPLIDAR()
CheckMotorControlSupportRequestRPLIDAR()
StopRequestRPLIDAR()
StartExpressScanRequestRPLIDAR()   <-- Error here

激光雷达对此作出的反应是:

代码语言:javascript
复制
a5 5a 54 00 00 40 82 

作为一个成功的连接响应,来自LIDAR的内容要长得多。

Things我试过

lidar.

  • Setting之前和/或之后,
  • 耗尽(强制所有写入数据)具有接口库DrainComputerRS232Port()方法的写入缓冲区,TX/ with FIFO缓冲区到FILE_FLAG_NO_BUFFERING (即。WriteFile()).
  • Changing硬件FIFO缓冲器最大(16)到最小(1)。
  • 使用MATLAB的串行()命令在加载库或尝试connections.

之前刷新任何输入或输出缓冲区。

,这是我使用的系统和设置

Lidar (x4)

  • Slamtec RPLIDAR A3
  • 固件通过USB (不使用USB集线器)
  • 没有连接到

的其他COM端口设备

计算机

  • OS: Windows 10 Pro - Build 1903
  • CPU: Intel Xeon 3.00Ghz
  • RAM: 64 GB
  • HD: SSD -512 64

串口设置

256000

  • Timeout:
  • Boud:

1000

软件

  • MATLAB R2018b (9.5.0)

我一直用这个把头撞在墙上。任何帮助都是非常感谢的!

EN

回答 1

Stack Overflow用户

发布于 2020-05-21 01:59:27

我要自己回答问题。任何人有兴趣进行更详细的讨论,请参阅MATLAB RPLIDAR回购版上的问题:

https://github.com/ENSTABretagneRobotics/Hardware-MATLAB/issues/2

正如我提到的,在调试时,错误似乎发生在ConnectRPLIDAR() --> StartExpressScanRequestRPLIDAR(),然后具体地在这里:

代码语言:javascript
复制
    // Receive the first data response (2 data responses needed for angles computation...).
    memset(pRPLIDAR->esdata_prev, 0, sizeof(pRPLIDAR->esdata_prev));
    if (ReadAllRS232Port(&pRPLIDAR->RS232Port, pRPLIDAR->esdata_prev, sizeof(pRPLIDAR->esdata_prev)) != EXIT_SUCCESS)
    {
        // Failure
        printf("A RPLIDAR is not responding correctly. \n");
        return EXIT_FAILURE;
    }

在此之前发生的事情似乎是在WriteAllRS232Port()中发出命令之后,有时它不会在ReadAllRS232Port()中读取响应,esdata_prev就什么都不是了。

我们尝试在第二个mSleep(500)之前实现一个ReadAllRS232Port()延迟,这似乎很有帮助(我猜激光雷达的响应速度很慢),但是这个问题并没有得到完全解决。

以下是每次使用4个lidars时使其工作的原因:

代码语言:javascript
复制
inline int StartExpressScanRequestRPLIDAR(RPLIDAR* pRPLIDAR)
{
    unsigned char reqbuf[] = { START_FLAG1_RPLIDAR,EXPRESS_SCAN_REQUEST_RPLIDAR,0x05,0,0,0,0,0,0x22 };
    unsigned char descbuf[7];
    unsigned char sync = 0;
    unsigned char ChkSum = 0;

    // Send request to output/tx OS FIFO buffer for port
    if (WriteAllRS232Port(&pRPLIDAR->RS232Port, reqbuf, sizeof(reqbuf)) != EXIT_SUCCESS)
    {
        printf("Error writing data to a RPLIDAR. \n");
        return EXIT_FAILURE;
    }


    // Receive the response descriptor.
    memset(descbuf, 0, sizeof(descbuf));  // Alocate memory
    if (ReadAllRS232Port(&pRPLIDAR->RS232Port, descbuf, sizeof(descbuf)) != EXIT_SUCCESS)
    {
        printf("A RPLIDAR is not responding correctly. \n");
        return EXIT_FAILURE;
    }


    // Quick check of the response descriptor.
    if ((descbuf[2] != 0x54) || (descbuf[5] != 0x40) || (descbuf[6] != MEASUREMENT_CAPSULED_RESPONSE_RPLIDAR))
    {
        printf("A RPLIDAR is not responding correctly. \n");
        return EXIT_FAILURE;
    }


    // Keep anticipating a port read buffer for 1 second
    int timeout = 1500;

    // Check it every 5 ms
    // Note on Checking Period Value:
    //    Waiting on 82 bytes in lidar payload
    //    10 bits per byte for the serial communication
    //    820 bits / 256000 baud = 0.0032s = 3.2ms
    int checkingperiod = 5;

    RS232PORT* pRS232Port = &pRPLIDAR->RS232Port;
    int i;
    int count = 0;

    // Wait for something to show up on the input buffer on port
    if (!WaitForRS232Port(&pRPLIDAR->RS232Port, timeout, checkingperiod))
    {
        //Success - Something is there

        // If anything is on the input buffer, wait until there is enough
        count = 0;
        for (i = 0; i < 50; i++)
        {
            // Check the input FIFO buffer on the port
            GetFIFOComputerRS232Port(pRS232Port->hDev, &count);

            // Check if there is enough to get a full payload read
            if (count >= sizeof(pRPLIDAR->esdata_prev))
            {
                // Thre is enough, stop waiting
                break;
            }
            else
            {
                // Not enough, wait a little
                mSleep(checkingperiod);
            }
        }

    }
    else
    {
        //Failure - After waiting for an input buffer, it wasn't there
        printf("[StartExpressScanRequestRPLIDAR] : Failed to detect response on the input FIFO buffer. \n");
        return EXIT_FAILURE;
    }


    // Receive the first data response (2 data responses needed for angles computation...).
    memset(pRPLIDAR->esdata_prev, 0, sizeof(pRPLIDAR->esdata_prev));
    if (ReadAllRS232Port(&pRPLIDAR->RS232Port, pRPLIDAR->esdata_prev, sizeof(pRPLIDAR->esdata_prev)) != EXIT_SUCCESS)
    {
        // Failure
        printf("A RPLIDAR is not responding correctly. \n");
        return EXIT_FAILURE;
    }


    // Analyze the first data response.
    sync = (pRPLIDAR->esdata_prev[0] & 0xF0)|(pRPLIDAR->esdata_prev[1]>>4);
    if (sync != START_FLAG1_RPLIDAR)
    { 
        printf("A RPLIDAR is not responding correctly : Bad sync1 or sync2. \n");
        return EXIT_FAILURE;    
    }

    ChkSum = (pRPLIDAR->esdata_prev[1]<<4)|(pRPLIDAR->esdata_prev[0] & 0x0F);
    // Force ComputeChecksumRPLIDAR() to compute until the last byte...
    if (ChkSum != ComputeChecksumRPLIDAR(pRPLIDAR->esdata_prev+2, sizeof(pRPLIDAR->esdata_prev)-1))
    { 
        printf("A RPLIDAR is not responding correctly : Bad ChkSum. \n");
        return EXIT_FAILURE;    
    }

    return EXIT_SUCCESS;
}

因此,在上面的代码中,我们等待操作系统读取FIFO缓冲区在1.5s内显示一些内容,每5ms检查一次(WaitForRS232Port())。如果出现任何情况,请确保等待足够的有效负载(GetFIFOComputerRS232Port())大小。

我不确定它是否起了作用,但我们也删除了OS写FIFO缓冲区,将它从0改为FILE_FLAG_NO_BUFFERING

代码语言:javascript
复制
File: OSComputerRS232Port.h
...
    hDev = CreateFile( 
        tstr,
        GENERIC_READ|GENERIC_WRITE,
        0, // Must be opened with exclusive-access.
        NULL, // No security attributes.
        OPEN_EXISTING, // Must use OPEN_EXISTING.
        FILE_FLAG_NO_BUFFERING, // Not overlapped I/O. Should use FILE_FLAG_WRITE_THROUGH and maybe also FILE_FLAG_NO_BUFFERING?
        NULL // hTemplate must be NULL for comm devices.
        );
...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61899056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档