懒得自己研究的推荐去Git上找
先简单说下A2和A3的区别, 具体参数参照官网配置,解析都一样,主要说下波特率
A2: 115200
A3: 256000
串口板是可以调节的,代码层面也是要对应
串口一般都是COM3,具体看设备管理器
先看下官方提供的工具frame_grabber
扫描模式分为5种:
Standard 4k 普通模式
Express 8k 高速模式
Boost 16k 增强模式(高速模式的变种1)
Sensitivity 16k 敏感模式(高速模式的变种2)
Stability 16k 稳定模式(高速模式的变种3)
通过观摩C++SDK只写出了 普通和高速模式, 剩下的3种模式(同一种解析)如果有人研究出来请私信我,十分感谢
下图是各个模式指令/起使应答报文头/ 数据报文
红线标出的是于高速扫描指令不同之处,蓝线标出的是数据起使报文头
启动电机指令 "A5F002C40291"
关闭电机指令 "A5F002000057"
Unity的SerialPort和Winform的SerialPort是有出入的,unity种无法使用DataReceived事件,只能自己建立线程去搞,如下:
public void Connect(int baudrate, string portName)
{
m_SerialPort = new SerialPort(portName, baudrate, Parity.None, 8, StopBits.One);
m_SerialPort.Open();
m_SerialPort.DiscardInBuffer();
m_SerialPort.DiscardOutBuffer();
m_SerialPort.DtrEnable = false;
m_SerialPort.ReadTimeout = -1;
m_ThreadReceive = new Thread(ListenSerialPort_RPLidarAX)
{
IsBackground = true
};
//m_ThreadReceive.SetApartmentState(ApartmentState.STA);
m_ThreadReceive.Start();
}
m_SerialPort.DiscardInBuffer();//清除接收缓冲区的数据
m_SerialPort.DiscardOutBuffer();//清除发送缓冲区的数据
m_SerialPort.DtrEnable = false;// 默认就是false
m_SerialPort.ReadTimeout = -1;//调成>=0,接受不到数据,写了-1就有了,别问为什么
public void Disconnect()
{
if (m_ThreadReceive != null)
{
//关闭线程
m_ThreadReceive.Abort();
m_ThreadReceive = null;
Debug.Log("Close thread");
}
//关闭串口
m_SerialPort.Close();
//将串口从内存中释放掉,注意如果这里不释放则在同一次运行状态下打不开此关闭的串口
m_SerialPort.Dispose();
Debug.Log("Serial Disconnected");
}
发送串口消息
/// <summary>
/// 给串口发消息
/// </summary>
/// <param name="byteArray"></param>
/// <returns></returns>
public void SendMessage(byte[] byteArray)
{
if (m_SerialPort != null && m_SerialPort.IsOpen == true)
{
m_SerialPort.Write(byteArray, 0, (int)byteArray.LongLength);
SerialCom_SerialPortSendMessageReportEvent(byteArray);
}
else
{
Debug.Log("Message Send Failed!");
}
}
最关键的接受数据来了:
/// <summary>
/// 监听串口,读取串口消息
/// </summary>
private void ListenSerialPort_RPLidarAX()
{
lock (RevBuffer)
{
while (m_SerialPort != null && m_SerialPort.IsOpen)
{
Thread.Sleep(10);
byte[] buffer = new byte[length];
//Debug.Log(RevBuffer.Count);
while (NormalScanCommand()) ;
if ((checklen = m_SerialPort.Read(buffer, 0, buffer.Length)) <= length)
RevBuffer.AddRange(buffer.Take(checklen));
}
}
//lock (RevBuffer)
//{
// while (m_SerialPort != null && m_SerialPort.IsOpen)
// {
// Thread.Sleep(10);
// buffer = new byte[length];
// while (ExpressScanCommand()) ;
// if ((checklen = m_SerialPort.Read(buffer, 0, buffer.Length)) <= length)
// RevBuffer.AddRange(buffer.Take(checklen));
// }
//}
}
}
NormalScanCommand方法是 接受数据,判断头,解析报文
先比对报文头是否是"A55A0500004081",是的话开始写数据进入缓冲区,检查是否写入了1000个字节,都满足,开始解析数据
参考官方手册 : 通讯接口协议与应用手册
private bool NormalScanCommand()
{
lock (RevBuffer)
{
checklen = 0;
var len = RevBuffer.Count;
if (len < length)
return false;
var command = new byte[length + errornumber - 1];
Array.Copy(RevBuffer.ToArray(), command, length + errornumber - 1);
if (checkalready || length == 7)
RevBuffer.RemoveRange(0, length + errornumber - 1);
if (length == 1000 && checkalready == false)
{
if (startscan)
{
if (RevBuffer.Count >= 1 + errornumber)
{
checkalready = true;
}
}
errornumber++;
}
//Debug.Log(MyMath.ByteToHexString(command));
if (checkalready)
{
RPLidarA3_DataResponseContentProcess_SCAN(command);
errornumber = 1;
}
if (MyMath.ByteToHexString(command) == "A55A0500004081" && startscan != true)
{
startscan = true;
length = 1000;
}
return true; //通知调用程序,收到了一个任务
}
}
private void RPLidarA3_DataResponseContentProcess_SCAN(byte[] responseData)
{
for (int i = 0; i < responseData.Length; i += 5)
{
bool isNewScan = (responseData[i] & 1) != 0;
bool isNewScan2 = (responseData[i] & 2) != 0;
// 起始字节的判断和数据校验
if (isNewScan == isNewScan2)
{
return;
}
// 校验位,永远为1
if ((responseData[i + 1] & 1) != 1)
{
return;
}
// 获取角度/距离/云点质量
float angle = ((responseData[i + 2] << 7) | (responseData[i + 1] >> 1)) / 64.0f;
float distance = ((responseData[i + 4] << 8) | responseData[i + 3]) / 4.0f;
int quality = responseData[i] >> 2;
// 添加一个点
...
}
// 此处通知绘制层绘制点
....
}
高速扫描也是同样的,检查报文头是不是"A55A5400004082", 长度为84,并重新解析就行了, 点比较散就不放出来了
增强模式也是同样的,检查报文头是不是"A55A8400004084", 长度为132,并重新解析,没搞出来,希望有大佬指点x1
敏感模式也是同样的,检查报文头是不是"A55A8400004084", 长度为132,并重新解析,没搞出来,希望有大佬指点x2
稳定模式也是同样的,检查报文头是不是"A55A8400004084", 长度为132,并重新解析,没搞出来,希望有大佬指点x3
最后放上一张运行效果图,用GL方式画的: