我遇到了一些初始的LIDAR连接问题,同时使用MATALB连接4个Slamtec A3和这里提供的接口库:https://github.com/ENSTABretagneRobotics/Hardware-MATLAB
问题是,在连接之前,我必须在至少一个LIDARS上重新尝试连接。它也可以随LIDAR而变化,也就是说。也就是说,除了一个LIDAR,所有的LIDAR都是第一次连接。一次,可能是一个COM端口上的LIDAR,另一次可能是另一个COM端口上的LIDAR。
这就是现在设置的方式。基本上,MATALB加载提供的接口库hardwarex.dll。它公开了一些要由MATLAB使用的库方法。
连接LIDAR的方法如下:
H 111使用快速扫描模式选项H 212g 213
在这里的某个地方,通讯会出错。使用串行嗅探器,我能够看到LIDAR在向LIDAR发出以下消息之后出现了错误:
a5 f0 02 ff 03 ab a5 25 a5 82 05 00 00 00 00 00 22按照这个顺序,我跟踪到以下库方法:
SetMotorPWMRequestRPLIDAR()
CheckMotorControlSupportRequestRPLIDAR()
StopRequestRPLIDAR()
StartExpressScanRequestRPLIDAR() <-- Error here激光雷达对此作出的反应是:
a5 5a 54 00 00 40 82 作为一个成功的连接响应,来自LIDAR的内容要长得多。
Things我试过
lidar.
DrainComputerRS232Port()方法的写入缓冲区,TX/ with FIFO缓冲区到FILE_FLAG_NO_BUFFERING (即。WriteFile()).之前刷新任何输入或输出缓冲区。
,这是我使用的系统和设置
Lidar (x4)
的其他COM端口设备
计算机
串口设置
256000
1000
软件
我一直用这个把头撞在墙上。任何帮助都是非常感谢的!
发布于 2020-05-21 01:59:27
我要自己回答问题。任何人有兴趣进行更详细的讨论,请参阅MATLAB RPLIDAR回购版上的问题:
https://github.com/ENSTABretagneRobotics/Hardware-MATLAB/issues/2
正如我提到的,在调试时,错误似乎发生在ConnectRPLIDAR() --> StartExpressScanRequestRPLIDAR(),然后具体地在这里:
// 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时使其工作的原因:
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
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.
);
...https://stackoverflow.com/questions/61899056
复制相似问题