帥小伙自制手持建圖儀!基于STM32F103 思嵐A1激光雷達(dá)
前言
一個朋友在做服務(wù)機器人項目,用到思嵐的激光雷達(dá),于是便把淘汰的A1M8雷達(dá)送我一個,本著拿到啥就玩啥的態(tài)度,必須整一波。其實激光雷達(dá)還是搭配ROS才能發(fā)揮最大的作用,奈何資源有限,實力不足,只能依靠STM32開發(fā)板做一個及其簡陋的地圖掃描。
思嵐A1M8激光雷達(dá)
這款激光雷達(dá)屬于低成本的360度激光掃描測距雷達(dá),外置電機,使用皮帶帶動雷達(dá)轉(zhuǎn)臺轉(zhuǎn)動,實現(xiàn)360度的測距掃描,電機的轉(zhuǎn)速由MCU發(fā)送PWM控制。
外部系統(tǒng)通過 TTL 電平的 UART 串口信號與 RPLIDAR 測距核心進(jìn)行通訊。通過本文檔定義的通訊協(xié)議,外部系統(tǒng)可以實時獲取 RPLIDAR 的掃描數(shù)據(jù)、設(shè)備信息、設(shè)備健康狀態(tài)。并且通過相關(guān)命令調(diào)整 RPLIDAR 的工作模式。
按照不同的請求類型, RPLIDAR 具有三種不同的請求/應(yīng)答模式:
標(biāo)準(zhǔn)的單次請求-單次應(yīng)答模式單次請求-多次應(yīng)答模式單次請求/無應(yīng)答模式
對于停止掃描、重啟測距核心這類請求命令, RPLIDAR 采用單次請求,但不做應(yīng)答的通訊模式。此時外部系統(tǒng)需要在發(fā)送請求后等待一定的時間,待RPLIDAR 完成了上一次請求操作后方可繼續(xù)執(zhí)行下一次請求。否則第二次的請求將可能被 RPLIDAR 丟棄。
在此次應(yīng)用中,主要采用后兩種請求/應(yīng)答模式,使用單次請求-多次應(yīng)答模式采集測距數(shù)據(jù),使用單次請求/無應(yīng)答模式停止采樣,進(jìn)行數(shù)據(jù)的處理。
在單次請求-多次應(yīng)答模式采集測距數(shù)據(jù)時,MCU發(fā)送采集指令,雷達(dá)會先回復(fù)一條起使應(yīng)答報文,之后便會循環(huán)回復(fù)數(shù)據(jù)應(yīng)答報文。
請求報文及起始應(yīng)答數(shù)據(jù)格式如下:
在回復(fù)起始應(yīng)答之后,雷達(dá)會循環(huán)回復(fù)測距數(shù)據(jù)。長度為5bytes。
?
例如測距數(shù)據(jù)為 3E D5 16 77 06。
第一個字節(jié):3E,二進(jìn)制為:0011 1110。代表信號質(zhì)量為0x0f。信號質(zhì)量不為零代表數(shù)據(jù)有效,起始標(biāo)志位為0,代表不是新的一圈,該標(biāo)志位只有在新的一圈的第一幀數(shù)據(jù)才會置一,該圈內(nèi)的其余數(shù)據(jù)改為依舊是0。第二個字節(jié):D5,角度數(shù)據(jù)低七位。第三個字節(jié):16,角度數(shù)據(jù)高八位,加上第二個字節(jié)的低七位等于166A,再右移一位得B35。實際角度=835/64=44°,該角度表示與雷達(dá)零度的順時針偏移角度,如下圖。第四個字節(jié):77,距離數(shù)據(jù)低八位。第五個字節(jié):06,距離角度高八位。則此時距離為0x0677/4 = 413mm。
激光雷達(dá)測試:接線:雷達(dá)? ? ? ? ? ? ?MCUGND----------->GNDRX------------->TXTX------------->RXV5.0----------->5VGND----------->GNDMOTOCTL---->PWMVMOTO------->5V
首先測試使用串口助手進(jìn)行數(shù)據(jù)采集,這里將MOTOCTL接到5V電源,直接以最高速度進(jìn)行采樣。串口助手發(fā)送A5 20,可以看到數(shù)據(jù)滾動。
其中開頭的七位數(shù)據(jù)對應(yīng)起始應(yīng)答,后面每5個字節(jié)一組,對應(yīng)測距數(shù)據(jù)。雷達(dá)無損壞,開始連接開發(fā)板調(diào)試。
MCU代碼:
既然是USART通信,我們先初始化USART,使用串口接收中斷接收數(shù)據(jù)。
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 打開串口GPIO的時鐘
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打開串口外設(shè)的時鐘
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 將USART Tx的GPIO配置為推挽復(fù)用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT,