一、項(xiàng)目名稱:
基于樹莓派和stm32f746的智能多功能農(nóng)業(yè)機(jī)器人開發(fā)
二、項(xiàng)目概述:
隨著技術(shù)的不斷進(jìn)步和發(fā)展,農(nóng)業(yè)機(jī)器人逐漸經(jīng)歷了從機(jī)械自動(dòng)化到人工智能、機(jī)器視覺等新技術(shù)加持的轉(zhuǎn)變。人工智能(Artificial Intelligence,AI)作為一種應(yīng)用于農(nóng)業(yè)領(lǐng)域的新興技術(shù),正逐漸改變著傳統(tǒng)農(nóng)業(yè)的面貌。智能農(nóng)機(jī)作為人工智能在農(nóng)業(yè)中的代表之一,在高效種植施肥和精確農(nóng)藥噴灑方面發(fā)揮著重要作用。
基于樹莓派和stm32f746的智能多功能農(nóng)業(yè)機(jī)器人系統(tǒng),可以實(shí)現(xiàn)手動(dòng)遙控和自主導(dǎo)航。完全無人作業(yè)。
本系統(tǒng)主要包括以樹莓派4B為AI中樞,以stm32f746 discovery開發(fā)板為核心、48V轉(zhuǎn)5V 5A電源模塊、4G /WIFI模塊、3D激光雷達(dá)、電機(jī)驅(qū)動(dòng)模塊,RTK高精度查分定位系統(tǒng)單元,2.4G無線遙控器等設(shè)備組成。
遙控器主要由按鍵、指示燈、顯示屏等組成。 按鍵包括前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、啟動(dòng)噴藥、停止噴藥等,通過無線通訊將指令傳輸給智能噴藥車,實(shí)現(xiàn)車輛的主動(dòng)遙控。 指示燈用于顯示遙控器和智能噴藥車的狀態(tài),如電量、工作狀態(tài)、通訊狀態(tài)等。stm32f746 discovery開發(fā)板顯示屏用于顯示智能噴藥車的實(shí)時(shí)位置、運(yùn)動(dòng)狀態(tài)、噴藥狀態(tài)等信息,方便農(nóng)業(yè)管理人員對(duì)機(jī)器人的管理和監(jiān)控。
智能噴藥車通過樹莓派實(shí)現(xiàn)噴藥控制、定位等功能,遙控器通過按鍵、指示燈等方式實(shí)現(xiàn)對(duì)噴藥車的遙控和監(jiān)測(cè)。 智能噴藥車由底盤、行駛控制系統(tǒng)、噴藥控制系統(tǒng)、運(yùn)動(dòng)傳感器、GNSS差分定位等組成。
系統(tǒng)的軟件設(shè)計(jì)主要包括ROS系統(tǒng)Slam算法為核心,以FreeRTOS實(shí)時(shí)操作系統(tǒng)在單片機(jī)為執(zhí)行器。樹莓派與單片機(jī)數(shù)據(jù)傳輸的通訊調(diào)試、千尋阿里云物聯(lián)網(wǎng)實(shí)現(xiàn)高精度差分定位和4G /WIFI模塊在單片機(jī)上的接入以及樹莓派上位機(jī)控制軟件的實(shí)現(xiàn)。
通過利用深度學(xué)習(xí)算法實(shí)現(xiàn)障礙我的識(shí)別與定位,將RTK 信息以及農(nóng)業(yè)機(jī)器人的狀態(tài)使用物聯(lián)網(wǎng)技術(shù)傳輸?shù)皆贫?,?shí)現(xiàn)噴藥車位置點(diǎn)的采集、路徑的編輯/下發(fā)、模式切換、導(dǎo)航控制功能。
三、作品實(shí)物圖
系統(tǒng)架構(gòu)圖:
實(shí)物圖:
部件:
基于樹莓派和stm32f746的智能多功能農(nóng)業(yè)機(jī)器人開發(fā)系統(tǒng)主要由3個(gè)部分組成:
①環(huán)境感知。涉及多種傳感器,包括土壤、煙感器、測(cè)距和溫度檢測(cè)傳感器等,在巡檢過程中實(shí)現(xiàn)對(duì)無人環(huán)境感知實(shí)時(shí)監(jiān)測(cè)。
②執(zhí)行機(jī)構(gòu)。為了方便后期的機(jī)器人維護(hù),上層控制器部分與底層執(zhí)行機(jī)構(gòu)部分采用模塊化設(shè)計(jì),執(zhí)行機(jī)構(gòu)部分采用 STM32F7作為底層處理器,通過4路PWM實(shí)現(xiàn)機(jī)器人底層電機(jī)的驅(qū)動(dòng)。針對(duì)環(huán)境感知系統(tǒng)中存在的導(dǎo)航、傳感器數(shù)據(jù)復(fù)雜和信息量較大等問題,上層控制器的處理器采用樹莓派作為主控。
③控制系統(tǒng):需要給樹莓派的SD卡里燒錄系統(tǒng)鏡像。相關(guān)配置如下:
操作系統(tǒng):Ubuntu18.04系統(tǒng),基于Debian GNU/Linux,支持x86、amd64(即x64)、ARM和ppc架構(gòu)。
仿真系統(tǒng):基于開源機(jī)器人操作系統(tǒng)ROS melodic,上位機(jī)采用ROS melodic,基于Rviz完成全向移動(dòng)底盤小車slam導(dǎo)航運(yùn)動(dòng)規(guī)劃,采用gazebo完成全向移動(dòng)底盤小車物理運(yùn)動(dòng)仿真;下位機(jī)采用基于FreertOS STM32F76實(shí)現(xiàn)對(duì)全向移動(dòng)底盤運(yùn)動(dòng)的控制。
STM32H7采集傳感器將檢測(cè)到的數(shù)據(jù)通過IIC協(xié)議的方式傳遞給樹莓派,執(zhí)行機(jī)構(gòu)部分與樹莓派之間、導(dǎo)航RTK與樹莓派之間采用 USB 通信方式,為了方便管理者在后端管理**查看機(jī)器人的位置和無人化倉庫的情況,機(jī)器人**與終端采用無線的方式實(shí)現(xiàn)通信。
為了能夠讓機(jī)器人按照一定的路徑進(jìn)行農(nóng)業(yè)作業(yè),需規(guī)劃出機(jī)器人從此刻位置到某一位置的移動(dòng)路徑,使得機(jī)器人從當(dāng)前位姿到達(dá)目標(biāo)位姿。移動(dòng)機(jī)器人的速度與位置、位姿存在緊密聯(lián)系,要對(duì)機(jī)器人進(jìn)行控制,需要對(duì)其位姿進(jìn)行準(zhǔn)確表達(dá)。
首先建立搭建ROS開發(fā)環(huán)境,進(jìn)行Slam導(dǎo)航算法,找到合適的坐標(biāo)系,對(duì)主要信息量進(jìn)行表達(dá),然后分析各坐標(biāo)系之間存在的位置關(guān)系,最后確定速度與位姿之間的數(shù)學(xué)關(guān)系表達(dá)式。
VSLAM則主要用攝像頭來實(shí)現(xiàn),主要分為單目、雙目、單目結(jié)構(gòu)光、雙目結(jié)構(gòu)光、ToF幾大類。核心都是獲取RGB和depth map(深度信息)。
STM32與樹莓派交互關(guān)鍵代碼
#include <serial/serial.h>
#include "MbotRosSerial.h"
#include <iostream>
/********************************************************
串口發(fā)送接收相關(guān)常量、變量、共用體對(duì)象
********************************************************/
const unsigned char ender[2] = { 0x0d, 0x0a };
const unsigned char header[2] = { 0x55, 0xaa };
serial::Serial sp;//創(chuàng)建一個(gè)serial對(duì)象
//發(fā)送左右輪速控制速度共用體
union sendData
{
short d;
unsigned char data[2];
}leftVelSet, rightVelSet;
//接收數(shù)據(jù)(左輪速、右輪速、角度)共用體(-32767 - +32768)
union receiveData
{
short d;
unsigned char data[2];
}leftVelNow, rightVelNow, angleNow;
/********************************************************
函數(shù)功能:串口參數(shù)初始化
入口參數(shù):無
出口參數(shù):無
作者:K.Fire
日期:2022.02.10
********************************************************/
void Serial_Init()
{
serial::Timeout to = serial::Timeout::simpleTimeout(100);//創(chuàng)建timeout
serial::parity_t pt = serial::parity_t::parity_none;//創(chuàng)建校驗(yàn)位為0位
serial::bytesize_t bt = serial::bytesize_t::eightbits;//創(chuàng)建發(fā)送字節(jié)數(shù)為8位
serial::flowcontrol_t ft = serial::flowcontrol_t::flowcontrol_none;//創(chuàng)建數(shù)據(jù)流控制,不使用
serial::stopbits_t st = serial::stopbits_t::stopbits_one;//創(chuàng)建終止位為1位
sp.setPort("/dev/ttyUSB0");//設(shè)置要打開的串口名稱
sp.setBaudrate(9600);//設(shè)置串口通信的波特率
sp.setParity(pt);//設(shè)置校驗(yàn)位
sp.setBytesize(bt);//設(shè)置發(fā)送字節(jié)數(shù)
sp.setFlowcontrol(ft);//設(shè)置數(shù)據(jù)流控制
sp.setStopbits(st);//設(shè)置終止位
sp.setTimeout(to);//串口設(shè)置timeout
try
{
//打開串口
sp.open();
}
catch (serial::IOException& e)
{
ROS_ERROR_STREAM("Unable to open port.");
return;
}
}
/********************************************************
函數(shù)功能:將對(duì)機(jī)器人的左右輪子控制速度,打包發(fā)送給下位機(jī)
入口參數(shù):機(jī)器人線速度、角速度
出口參數(shù):無
作者:K.Fire
日期:2022.02.10
********************************************************/
void SendSTM32(double Left_v, double Right_v, unsigned char CtrlCmd)
{
unsigned char buf[11] = { 0 };//發(fā)送數(shù)組
int i, length = 4;
leftVelSet.d = Left_v;//mm/s
rightVelSet.d = Right_v;
// 設(shè)置消息頭
for (i = 0; i < 2; i++)
buf[i] = header[i]; //buf[0] buf[1]
//設(shè)置控制位
buf[2] = CtrlCmd; //buf[2]
//設(shè)置數(shù)據(jù)長度
buf[3] = length; //buf[3]
// 設(shè)置機(jī)器人左右輪速度
for (i = 0; i < 2; i++)
{
buf[i + 4] = leftVelSet.data[i]; //buf[4] buf[5]
buf[i + 6] = rightVelSet.data[i]; //buf[6] buf[7]
}
// 設(shè)置校驗(yàn)值、消息尾
buf[4 + length] = getCrc8(buf, 3 + length);//buf[8]
buf[5 + length] = ender[0]; //buf[9]
buf[6 + length] = ender[1]; //buf[10]
// 通過串口下發(fā)數(shù)據(jù)
sp.write(buf, 11);
}
/********************************************************
函數(shù)功能:讀取下位機(jī)數(shù)據(jù),左右輪速度值、航向角、控制信息
入口參數(shù):左右輪速度值、航向角、控制信息
出口參數(shù):bool
作者:K.Fire
日期:2022.02.10
********************************************************/
bool ReceiveSTM32(double& Left_v, double& Right_v, double& Angle, unsigned char& CtrlCmd)
{
char i, length = 0;
unsigned char checkSum;
unsigned char buf[150] = { 0 };
int n;//信息長度
size_t Receive_N = sp.available();//獲取緩沖區(qū)內(nèi)的字節(jié)數(shù)
if (n != 0)
{
n = sp.read(buf, n);//讀出數(shù)據(jù)
// 檢查信息頭
if (buf[0] != header[0] || buf[1] != header[1]) //buf[0] buf[1]
{
ROS_ERROR("Received message header error!");
return false;
}
//讀取控制位
CtrlCmd = buf[2]; //buf[2]
//讀取數(shù)據(jù)長度
length = buf[3]; //buf[3]
// 檢查信息校驗(yàn)值
checkSum = getCrc8(buf, 4 + length); //buf[10] 計(jì)算得出
if (checkSum != buf[4 + length]) //buf[10] 串口接收
{
ROS_ERROR("Received data check sum error!");
return false;
}
// 讀取速度值和航向角
for (i = 0; i < 2; i++)
{
leftVelNow.data[i] = buf[i + 4]; //buf[4] buf[5]
rightVelNow.data[i] = buf[i + 6]; //buf[6] buf[7]
angleNow.data[i] = buf[i + 8]; //buf[8] buf[9]
}
Left_v = leftVelNow.d;
Right_v = rightVelNow.d;
Angle = angleNow.d;
return true;
}
}
/********************************************************
函數(shù)功能:獲得8位循環(huán)冗余校驗(yàn)值
入口參數(shù):數(shù)組地址、長度
出口參數(shù):校驗(yàn)值
********************************************************/
unsigned char getCrc8(unsigned char* ptr, unsigned short len)
{
unsigned char crc;
unsigned char i;
crc = 0;
while (len--)
{
crc ^= *ptr++;
for (i = 0; i < 8; i++)
{
if (crc & 0x01)
crc = (crc >> 1) ^ 0x8C;
else
crc >>= 1;
}
}
return crc;
}
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "MbotRosSerial.h"
//test send value
double testSend1=5555.0;
double testSend2=2222.0;
unsigned char testSend3=0x07;
//test receive value
double testRece1=0.0;
double testRece2=0.0;
double testRece3=0.0;
unsigned char testRece4=0x00;
int main(int argc,char **argv)
{
ros::init(argc,argv,"serial_test");//節(jié)點(diǎn)初始化
ros::NodeHandle n;//創(chuàng)建節(jié)點(diǎn)句柄
ros::Rate loop_rate(10);
//串口初始化
Serial_Init();
while(ros::ok())
{
//發(fā)送數(shù)據(jù)
SendSTM32(testSend1,testSend2,testSend3);
//接收數(shù)據(jù)
ReceiveSTM32(testRece1,testRece2,testRece3,testRece4);
//打印數(shù)據(jù)
ROS_INFO("Receive Data is: %f,%f,%f,%dn",testRece1,testRece2,testRece3,testRece4);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
RTK 載波相位差分技術(shù),是實(shí)時(shí)處理兩個(gè)測(cè)量站載波相位觀測(cè)量的差分方法,將基準(zhǔn)站采集的載波相位發(fā)給用戶接收機(jī),進(jìn)行求差解算坐標(biāo)。一般包含流動(dòng)站 (移動(dòng)站) 和基準(zhǔn)站 (基站) 。本系統(tǒng)中RTK定位采用千尋定位, 參考的也是千尋CORS基站的坐標(biāo),所以需要先登入千尋cors賬號(hào)。
RTK接入ROS系統(tǒng),nmea_navsat_driver是一套用于獲取并解析GPS數(shù)據(jù)的ROS驅(qū)動(dòng)包,使用Python語言實(shí)現(xiàn)。GPS設(shè)備使用此包的條件是:遵守或者兼容NMEA0183協(xié)議。
本次設(shè)計(jì)結(jié)合攝像頭激光雷達(dá)和RTK實(shí)現(xiàn)融合定位,真正做到厘米級(jí)別,屬于國際領(lǐng)先。
噴嘴可以用來噴灑農(nóng)藥也可以進(jìn)行環(huán)境消毒,也可以進(jìn)行施肥作業(yè),真正做到一機(jī)多用。
四、演示視頻
https://www.bilibili.com/video/BV1uA4m1j7pM/?buvid=XY75B537C416E17A953A00A33EDB883CA28EB&is_story_h5=false&mid=Pw2Hq3t6IhfKj%2FPD%2Bao96g%3D%3D&plat_id=147&share_from=ugc&share_medium=android&share_plat=android&share_session_id=06897bb8-6ae8-4efd-99e7-41f15d1b701d&share_source=WEIXIN&share_tag=s_i×tamp=1706692332&unique_k=Km1lrk3&up_id=526937168
五、項(xiàng)目文檔
ROS串口程序.zip (7.13 KB)
基于樹莓派和stm32f746的智能多功能農(nóng)業(yè)機(jī)器人開發(fā).zip (4.67 MB)