国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同

這篇具有很好參考價值的文章主要介紹了空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1 題目

1.1 任務(wù)

設(shè)計一個由四旋翼無人機(jī)及消防車構(gòu)成的空地協(xié)同智能消防系統(tǒng)。無人機(jī)上安裝垂直向下的激光筆,用于指示巡邏航跡。巡防區(qū)域為40dm×48dm。無人機(jī)巡邏時可覆蓋地面8dm寬度區(qū)域。以縮短完成全覆蓋巡邏時間為原則,無人機(jī)按照規(guī)劃航線巡邏。發(fā)現(xiàn)火情后立即采取初步消防措施,并將火源地點位置信息發(fā)給消防車,使其前往熄滅火源??盏貐f(xié)同巡邏及消防工作完成時間越短越好。

空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

1.2 任務(wù)點

1、基本要求(50分)

  • (1)參賽隊需自制模擬火源。模擬火源是用電池供電的紅色光源,如LED等,用激光筆持續(xù)照射可控制開啟或關(guān)閉:持續(xù)照射2秒左右開啟,再持續(xù)照射2秒左右關(guān)閉。(5分)
  • (2)展示規(guī)劃的巡邏航線圖,在消防車上按鍵啟動無人機(jī)垂直起飛后,無
    人機(jī)以18dm左右高度,在巡防區(qū)域按規(guī)劃的航線完成全覆蓋巡邏。(22分)
  • (3)無人機(jī)與消防車之間采用無線通信;巡邏期間無人機(jī)每秒向消防車發(fā)
    送1次位置坐標(biāo)信息,消防車上顯示器實時更新顯示無人機(jī)位置坐標(biāo)信息。(8分)
  • (4)巡邏中,消防車顯示器顯示巡邏航跡曲線,計算并顯示累計巡邏航程。(8分)
  • (5)完成巡邏后,無人機(jī)返回,準(zhǔn)確降落在起飛區(qū)域內(nèi)。(7分)

2、發(fā)揮部分(50分)

  • (1)手動操作激光筆點亮-一個火源。在消防車上啟動無人機(jī)巡邏。無人機(jī)
    按規(guī)劃航線巡邏,發(fā)現(xiàn)火情后,前往接近火源(水平距離≤5dm)識別確認(rèn),再在無人機(jī)上用LED指示燈示警。(8分)
  • (2)無人機(jī)飛至火源地點上方,降低至10dm左右高度,懸停3s后拋灑滅
    火包,滅火包落在以火源點為中心、半徑3dm圓形區(qū)域內(nèi);再將火源地點位置坐標(biāo)發(fā)送給消防車,然后繼續(xù)巡邏,完成后返航回到起飛點。(12分)
  • (3)消防車接收到火情信息,顯示火源地點位置坐標(biāo)后,從消防站出發(fā)前
    往火源地點,途中不得碾壓街區(qū)及其邊界線,在5dm距離內(nèi)以激光筆光束照射模擬火源將其熄滅。(15分)
  • (4)熄滅模擬火源后消防車返回到出發(fā)區(qū)域內(nèi)。發(fā)揮部分限時360s內(nèi)完成。(10分)
  • (5)其他。(5分)

1.3 設(shè)計部分

1.3.1 模擬火源

該部分的要求如下:
模擬火源可用電池供電的紅色LED等,需帶向上的喇叭形遮光罩,遮光罩角度約60°左右,高度不超過10cm??捎眉す夤P控制其開啟或關(guān)閉。
示意圖如下:
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)
外部遮光罩可仿照寵物防咬罩進(jìn)行修改:
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)
內(nèi)部LED燈罩是為了擴(kuò)大燈光面積,以便系統(tǒng)內(nèi)圖像識別系統(tǒng)的工作。同時為了提高小車激光跟隨算法的工作效率,需要擴(kuò)大光敏傳感器檢測區(qū)域,建議使用人體微波檢測模塊上的塑料透鏡,以達(dá)到聚光的效果。
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)
電路設(shè)計圖:STC8最小系統(tǒng)板加兩節(jié)1.5V干電池,一個紅色LED,300Ω左右的電阻,一個光敏傳感器就差不多了。
程序設(shè)計:程序中用到一個GPIO輸出、ADC、定時器。

1.3.2 小車部分

該部分要求如下:
消防車要求使用 4 輪電動小車,長寬投影尺寸不大于 20cm×35cm,高度不大于 40cm;不得使用麥克納姆輪。

1、底盤與電機(jī):
(1)底盤:自選。
(2)電機(jī):最好使用帶編碼器的金屬齒輪減速點擊,能夠得到轉(zhuǎn)速和角度,以便估測小車位置,更好地控制小車。
(3)電機(jī)驅(qū)動:H橋電機(jī)驅(qū)動模塊。
(4)電池:12V高倍率鋰電池組。
最好找要帶有電機(jī)驅(qū)動的、編碼器接口、能夠降壓給主控供電的小車底板,比如開山斧電機(jī)驅(qū)動模塊。
四輪小車的前兩個輪子無動力,采用舵機(jī)控制方向,后兩個輪子分別采用直流電機(jī)控制。
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

2、主控芯片
(1)盤古:
如果選擇TI的,盤古這塊系統(tǒng)板開發(fā)起來還是比較順手的,用起來Bug少。板子上有OLED驅(qū)動芯片和加速度傳感器、蜂鳴器、多個按鍵、串口接口多。
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

(2)TM4C123GXL:
這塊板子十分不推薦,調(diào)試接口有問題,驅(qū)動也不好打(ICDI,要安裝CCS),性能也比較差,供電端口也少,寫代碼的時候Keil閃退無數(shù)次,硬件跑程序也容易進(jìn)中斷卡死。
要是有別人改過的、開發(fā)好的成品,用用還是可以的。
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

3、電機(jī)驅(qū)動芯片:
使用的是無名創(chuàng)新的開山斧驅(qū)動板,以下是模塊接口圖:
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

  • 電機(jī)控制信號接口:為四路PWM輸入,兩路PWM控制一個電機(jī)的轉(zhuǎn)速和旋轉(zhuǎn)方向。
  • … …

3、顯示屏
建議使用陶晶馳的串口屏,配置方便,代碼簡單,能夠回傳字符串。
引腳:5V、GND、TXD、RXD
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

4、無線模塊
可以使用藍(lán)牙、WIFI、Lora等等。
無線模塊建議采用有廣播功能的模塊,這樣多機(jī)調(diào)試更加方便。
引腳:VCC(5~3.3V)、GND、TXD、RXD
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)
今年還允許使用UWB,能夠?qū)崿F(xiàn)無人機(jī)和小車的精確定位,還能夠傳輸數(shù)據(jù),只要來得及開發(fā)代碼,可以說是降維打擊,不過價格還是比較昂貴的。

5、機(jī)器視覺和舵機(jī)
對于模擬火源的檢測,有OpenMV方案和K210方案。
OpenMV模塊有控制舵機(jī)的例程,可以控制激光筆關(guān)閉模擬火源,但溢價過多,可以自己DIY。

6、IMU
這個主控板上有就最好,沒有就用模塊化的MPU6050,不過要安裝在小車中心處。

7、其他模塊:
(1)灰度傳感器:白光照射不同顏色的地面,反射回的光強(qiáng)不同,可以進(jìn)行巡線等任務(wù)。
(2)激光頭。
(3)…

1.3.3 無人機(jī)部分

直接購買成品化的TI無人機(jī),主控板可以使用前面提到的主控。

2 程序設(shè)計

我主要是做小車的,因此講一下我小車的設(shè)計方案。
小車上主控板選用TI 盤古的開發(fā)板,板載芯片為TM4C123GH6PZT7,MCU內(nèi)核為ARM Cortex-M4F,MCU最大主頻為80 MHz,工作電壓范圍1.08 V-3.63 V,RAM為32 KB,F(xiàn)lash大小為256 KB,EEPROM為2 KB,核心位寬為32-Bit,ADC為12 bit。
外設(shè)和內(nèi)部資源需要使用串口屏、藍(lán)牙模塊/UWB模塊、定時器、PWM、LED輸出、按鍵輸入(這個可以使用串口屏的按鍵串口信息回傳事件替代)、蜂鳴器驅(qū)動。

2.1 藍(lán)牙模塊配置

本人使用的是大熊智能的雙模藍(lán)牙模塊,兩個藍(lán)牙模塊配對的話需要設(shè)置一主機(jī)一從機(jī),以下藍(lán)牙模塊連接CH340模塊,在電腦上使用AT命令配置兩個模塊。默認(rèn)使用115200波特率連接。

藍(lán)牙從機(jī),連接無人機(jī):

AT+NAME=DX2003-S		# 設(shè)置從機(jī)名稱
AT+MASTER=01			# 設(shè)置從機(jī)工作模式
AT+BAUD=115200			# 設(shè)置波特率為115200
AT+LADDR				# 讀取從機(jī)藍(lán)牙地址,以便主機(jī)連接

+LADDR=22345000891f

藍(lán)牙主機(jī),連接小車:

AT+NAME=DX2003-M		# 設(shè)置主機(jī)名稱
AT+MASTER=04			# 設(shè)置主機(jī)工作模式
AT+BAUD=115200			# 設(shè)置波特率為115200
AT+CONN=22345000891f	# 主機(jī)連接從機(jī)地址

連接上之后:
(1)主機(jī)顯示:

IM_CONN:0		# 0代表是BLE連接上,1代表是SPP連接上

(2)從機(jī)顯示:

IM_CONN:8

藍(lán)牙斷開連接命令:

AT+DSCET=1	

2.2 小車串口屏界面設(shè)計

串口屏使用USART HMI軟件繪制界面,需要進(jìn)行界面排版,字庫添加,程序編譯。
軟件下載及學(xué)習(xí)鏈接:

http://mall.micromove.cn/start/download_ide.html

空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

2.2.1 串口通信協(xié)議

1、串口屏接收:
協(xié)議為:字符串+HEX標(biāo)識符
HEX標(biāo)識符為:\xff\xff\xff
USART HMI軟件上仿真不需要添加HEX標(biāo)識符(\xff\xff\xff)。
例子:
如果是串口屏使用CH340連接電腦,則電腦上的串口工具輸入(不要加空格):

t0.txt="陶晶馳電子"\xff\xff\xff
b0.txt="Hello World"\xff\xff\xff
j0.val=100\xff\xff\xff
page0.bco=WHITE\xff\xff\xff

如果是MCU串口發(fā)送數(shù)據(jù):在2.4.2中詳述。

2、串口屏發(fā)送:
(1)prints:從串口打印一個變量/常量。
(2)printh:從串口打印16進(jìn)制。

2.2.2 繪圖函數(shù)

主要使用的有:
(1)cirs:繪制實心圓

cirs x,y,radius,color\xff\xff\xff
cirs 160,266,6,RED\xff\xff\xff

(2)line:繪制直線

line x_start,y_start,x_end,y_end,color\xff\xff\xff
line 185,246,185,26,BLUE\xff\xff\xff

(3)插入圖片

pic x,y,picid\xff\xff\xff					# picid為軟件插入的ID號為x的圖片
pic,123,150,0\xff\xff\xff

2.2.3 串口屏界面設(shè)計

小車能夠通過藍(lán)牙串口接收無人機(jī)傳回的航點數(shù)據(jù)(協(xié)議A)和火災(zāi)位置數(shù)據(jù)(協(xié)議B),并在串口屏上顯示出藍(lán)色原點和紅色六角形。

空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

2.3 無人機(jī)與小車之間的通信協(xié)議設(shè)計

1、無人機(jī)通過串口發(fā)送給小車的字符串:

A,160,150,F			// 無人機(jī)航點坐標(biāo)(160,150)
B,250,100,F			// 模擬火源坐標(biāo)(250,100)
C,1,F				// 模擬火源ID: 1

A類表示無人機(jī)航點,F(xiàn)為結(jié)束標(biāo)志位
B類表示無人機(jī)檢測到的火源坐標(biāo),F(xiàn)為結(jié)束標(biāo)志位。
C類表示無人機(jī)檢測到的模擬火源所在的區(qū)域ID,F(xiàn)為結(jié)束標(biāo)志位。這個協(xié)議可以不發(fā)送,直接小車通過B類協(xié)議計算模擬火源位置。

2、小車通過串口發(fā)給無人機(jī)的字符串只需要一個按鍵使能,使用按鍵輸入或者串口屏的點擊,通過藍(lán)牙串口發(fā)送“TakeOff”字符串,無人機(jī)檢測到就能起飛了。

2.4 小車程序設(shè)計

首先進(jìn)行各個部分的初始化,然后進(jìn)入while(1)循環(huán),循環(huán)內(nèi)寫入大部分處理函數(shù)。中斷處理函數(shù)中存放處理函數(shù)的使能位,當(dāng)某些函數(shù)工作時間較長,需要在中斷中使能標(biāo)志位,然后在主函數(shù)main中進(jìn)行處理,以免造成中斷阻塞。
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

主函數(shù):

#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
// ......

// 全局變量
char uart4_rec_temp[50];		// 接收到暫存的字符數(shù)組
bool uart4_rec_check_flag = 0;		// 接收數(shù)據(jù)解包的標(biāo)志位

// ......

int main(void)
{
	ROM_FPUEnable();//使能浮點單元
	ROM_FPULazyStackingEnable();//浮點延遲堆棧,減少中斷響應(yīng)延遲  
	ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);//配置系統(tǒng)時鐘
	initTime();					// 初始化滴答定時器
	GPIO_Init();				// LED燈初始化
	// ......
	ConfigureUART4();			// 初始化藍(lán)牙BLE-串口4
	ConfigureUART5();			// 初始化串口屏驅(qū)動-串口5
	UART4_BLE_CONNECT();		// 串口4連接藍(lán)牙
	HMI_Init();					// 串口屏初始化
	
	// ......
	
	while(1)
	{
		// ......
		uart4_data_check();		//串口4數(shù)據(jù)包解包
		uart5_uav_point_write();	// 向串口屏寫入無人機(jī)航點
		Control_UAV_flight_status();	// 小車控制無人機(jī)起飛
		// ......
	}
}

2.4.1 藍(lán)牙串口程序

藍(lán)牙串口程序包括串口初始化、串口發(fā)送、串口中斷服務(wù)函數(shù)(串口接收)、串口數(shù)據(jù)解析等部分。

1、串口初始化:

// 藍(lán)牙-串口4驅(qū)動 PC4/PC5
void ConfigureUART4(void)
{ 
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);// Enable the GPIO Peripheral used by the UART.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);// Enable UART0
    ROM_GPIOPinConfigure(GPIO_PC4_U4RX);// Configure GPIO Pins for UART mode.
    ROM_GPIOPinConfigure(GPIO_PC5_U4TX);
    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
	UARTConfigSetExpClk(UART4_BASE,SysCtlClockGet(),115200,
												(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
	UARTFIFODisable(UART4_BASE);			// 使能UART4中斷
	UARTIntEnable(UART4_BASE,UART_INT_RX);	// 使能UART4接收中斷
	UARTIntRegister(UART4_BASE,UART4_IRQHandler);	//UART4中斷地址注冊
	IntPrioritySet(INT_UART4,USER_INT3);			//中斷優(yōu)先級設(shè)置USER_INT3(0最高)
}

2、串口中斷服務(wù)函數(shù):

void UART4_IRQHandler(void)		//UART4中斷函數(shù)-藍(lán)牙BLE接收中斷(無人機(jī)信息發(fā)送給小車)
{
	uint32_t flag = UARTIntStatus(UART4_BASE,1);//獲取中斷標(biāo)志 原始中斷狀態(tài) 屏蔽中斷標(biāo)志		
	UARTIntClear(UART4_BASE,flag);//清除中斷標(biāo)志	
	char ch;
	while(UARTCharsAvail(UART4_BASE))//判斷FIFO是否還有數(shù)據(jù)		
	{
		ch = UARTCharGet(UART4_BASE);	
		uart4_rec_temp[temp_cnt] = ch;
		temp_cnt ++;
 	}
	if(ch == 'F')
		uart4_rec_check_flag = 1;			// 接收數(shù)據(jù)解包的標(biāo)志位置1
	if(temp_cnt >= 50)						//數(shù)組存滿后清空
	{
		memset(uart4_rec_temp, 0, sizeof(uart4_rec_temp));		// 清空字符數(shù)組
		temp_cnt = 0;
	}
	bit_data = !bit_data;
	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_5, bit_data);		//置低位點亮,保持閃爍,如果LED不閃爍了,表示程序卡死了
}

3、串口發(fā)送函數(shù):

void UART4_SendString(const char *string)
{
	int len = strlen(string);
	while(len--)
	{
		// 等待UART發(fā)送緩沖區(qū)為空
		while(UARTSpaceAvail(UART4_BASE) == 0);
		
		// 發(fā)送字符到UART
		UARTCharPut(UART4_BASE, *string++);
	}
}

4、解析串口接收到的數(shù)據(jù):
首先檢測第一個數(shù)是否是“A”或“B”,然后檢測字符串最后一個字符是否是“F”。接著索引字符串中的“,”,將中間的兩個數(shù)字字符串拆分出來,使用atof()函數(shù)將字符串轉(zhuǎn)換為浮點數(shù)。最后將獲得的浮點數(shù)存入對應(yīng)的變量中,或者使用調(diào)試接口輸出,或使用OLED屏輸出。

// 串口4數(shù)據(jù)包解包
void uart4_data_check(void)
{
	if(uart4_rec_check_flag == 1)		// 分析uart4_rec_temp中的數(shù)據(jù)
	{
		uart4_rec_check_flag = 0;
		if(uart4_rec_temp[0] == 'A')		// 是無人機(jī)XY坐標(biāo)數(shù)據(jù)包
		{
			int len = strlen(uart4_rec_temp);
			if(uart4_rec_temp[len-1] == 'F')
			{
				char* token;
				token = strtok(uart4_rec_temp,",");
				token = strtok(NULL,",");
				uart4_rec_x[uav_cnt] = atof(token);
				token = strtok(NULL,",");
				uart4_rec_y[uav_cnt] = atof(token);
				uart4_flight_dist = uart4_flight_dist + sqrt(pow(uart4_rec_x[uav_cnt]-uart4_rec_x[uav_cnt-1],2) + pow(uart4_rec_y[uav_cnt]-uart4_rec_y[uav_cnt-1],2));
				printf("A-X: uart4_rec_x[%d]:%f\r\n",uav_cnt,uart4_rec_x[uav_cnt]);		// 測試
				printf("A-Y: uart4_rec_y[%d]:%f\r\n",uav_cnt,uart4_rec_y[uav_cnt]);		// 測試
				printf("A-D: uart4_flight_dist[%d]:%fm\r\n",uav_cnt,uart4_flight_dist/100);		// 測試
				// ......
			}
			// 處理完成后,清空uart4_rec_temp
			memset(uart4_rec_temp, 0, sizeof(uart4_rec_temp));
			temp_cnt = 0;
		}
		else if(uart4_rec_temp[0] == 'B')		// 是火源XY坐標(biāo)數(shù)據(jù)包
		{
			int len = strlen(uart4_rec_temp);
			if(uart4_rec_temp[len-1] == 'F')
			{
				char* token;
				token = strtok(uart4_rec_temp,",");
				token = strtok(NULL,",");
				uart4_fire[0] = atof(token);
				token = strtok(NULL,",");
				uart4_fire[1] = atof(token);
				printf("B-X: uart4_fire[0]:%f\r\n",uart4_fire[0]);		// 測試
				printf("B-Y: uart4_fire[1]:%f\r\n",uart4_fire[1]);		// 測試
				// ......
			}
			// 處理完成后,清空uart4_rec_temp
			memset(uart4_rec_temp, 0, sizeof(uart4_rec_temp));
			temp_cnt = 0;
		}
		else
		{	// 沒找到A/B數(shù)據(jù)包,清空uart4_rec_temp
			memset(uart4_rec_temp, 0, sizeof(uart4_rec_temp));
			temp_cnt = 0;
		}
	}
}

2.4.2 串口屏控制程序

串口屏界面:
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

1、串口驅(qū)動:

// 串口屏-串口5 PE4/PE5
void ConfigureUART5(void)
{ 
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);// Enable the GPIO Peripheral used by the UART.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);// Enable UART6
    ROM_GPIOPinConfigure(GPIO_PE4_U5RX);// Configure GPIO Pins for UART mode.
    ROM_GPIOPinConfigure(GPIO_PE5_U5TX);
    ROM_GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
	UARTConfigSetExpClk(UART5_BASE,SysCtlClockGet(),115200,
		(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
	UARTFIFODisable(UART5_BASE);			// 使能UART6中斷
	UARTIntEnable(UART5_BASE,UART_INT_RX);	// 使能UART6接收中斷
	UARTIntRegister(UART5_BASE,UART5_IRQHandler);	//UART6中斷地址注冊
	IntPrioritySet(INT_UART5,USER_INT5);			// 中斷優(yōu)先級設(shè)置USER_INT6
}

2、串口中斷服務(wù)函數(shù):
函數(shù)內(nèi)包含串口接收,由于接收數(shù)據(jù)分析較為簡單,解析就在函數(shù)內(nèi)解決了,如果數(shù)據(jù)解析較為復(fù)雜,建議在中斷服務(wù)中給個flag,在主函數(shù)內(nèi)處理。

void UART5_IRQHandler(void)
{
	uint32_t flag = UARTIntStatus(UART5_BASE,1);//獲取中斷標(biāo)志 原始中斷狀態(tài) 屏蔽中斷標(biāo)志		
  UARTIntClear(UART5_BASE,flag);//清除中斷標(biāo)志	
	char ch;
  while(UARTCharsAvail(UART5_BASE))//判斷FIFO是否還有數(shù)據(jù)		
  {
		ch = UARTCharGet(UART5_BASE);
		uart5_hmi_rec[uart5_cnt] = ch;	//串口屏發(fā)送回的數(shù)據(jù)存儲到buffer中
  }
	uart5_cnt ++;
	if(strstr(uart5_hmi_rec,"TO"))		// 數(shù)據(jù)解析,如果uart5_hmi_rec中有"TO",則設(shè)置flag
	{
		key_flag = 1;		// 藍(lán)牙串口發(fā)送數(shù)據(jù)的flag
	}
	if(uart5_cnt >= 5)
	{
		uart5_cnt = 0;
		memset(uart5_hmi_rec,0,sizeof(uart5_hmi_rec));		// 清空buffer
	}
}

3、串口發(fā)動函數(shù):

// UART5 主控串口5發(fā)送給串口屏HMI-----字符串
void UART5_SendString(const char *string)
{
	int len = strlen(string);
	while(len--)
	{
		// 等待UART發(fā)送緩沖區(qū)為空
		while(UARTSpaceAvail(UART5_BASE) == 0);
		
		// 發(fā)送字符到UART
		UARTCharPut(UART5_BASE, *string++);
	}
}

// UART5 主控串口5發(fā)送給串口屏HMI------二進(jìn)制
void UART5_SendBinary(void)
{
	u8 i;
	for(i=0;i<3;i++)
	{
		// 等待UART發(fā)送緩沖區(qū)為空
		while(UARTSpaceAvail(UART5_BASE) == 0);
		// 發(fā)送二進(jìn)制0xff到UART
		UARTCharPut(UART5_BASE, 0xff);
	}
}

4、串口屏啟動程序:
函數(shù)UART5_SendString(cmd)的后面必須跟著函數(shù)UART5_SendBinary(),為的是給串口屏發(fā)送三個0xff結(jié)束標(biāo)志符。

// 串口屏初始化
void HMI_Init(void)
{
	char cmd[50];
	const int point_num = 5;
	int UAVwaypoint[point_num][2] = {{185, 246},
									{185, 70},
									{400, 70},
									{400, 246},
									{185, 246}};
	UART5_SendString("rest");	// 重啟屏幕
	UART5_SendBinary();
	Delay_Ms(1000);
	UART5_SendString("line 100,20,150,20,BLUE");	// 繪制巡邏軌跡樣例
	UART5_SendBinary();
	
	for(int i=0;i<point_num-1;i++)					// 	繪制規(guī)劃航點
	{
		sprintf(cmd,"line %d,%d,%d,%d,BLUE",UAVwaypoint[i][0],UAVwaypoint[i][1],UAVwaypoint[i+1][0],UAVwaypoint[i+1][1]);
		UART5_SendString(cmd);
		UART5_SendBinary();
		Delay_Ms(250);
	}
	sprintf(cmd,"line %d,%d,%d,%d,BLUE",UAVwaypoint[point_num-1][0],UAVwaypoint[point_num-1][1],UAVwaypoint[0][0],UAVwaypoint[0][1]);
	UART5_SendString(cmd);
	UART5_SendBinary();
}

5、向串口屏寫入無人機(jī)航點位置和火源位置:

void uart5_uav_point_write(void)
{
	if(uav_flag == 1)  //無人機(jī)航點位置
	{
		uav_flag = 0;
		char cmd[30];
		memset(cmd,0,sizeof(cmd));
		// X、Y數(shù)據(jù)處理
		float x_fixed,y_fixed;
		if(uart4_rec_x[uav_cnt-1] > 480)
			x_fixed = 480;
		else if(uart4_rec_x[uav_cnt-1] < 0)
			x_fixed = 0;
		else
			x_fixed = uart4_rec_x[uav_cnt-1];
		uint16_t x_pixel = (uint16_t)(x_fixed/480*312);
		
		if(uart4_rec_y[uav_cnt-1] > 400)
			y_fixed = 400;
		else if(uart4_rec_y[uav_cnt-1] < 0)
			y_fixed = 0;
		else
			y_fixed = uart4_rec_y[uav_cnt-1];
		uint16_t y_pixel = (uint16_t)(y_fixed/256*400);
		
		sprintf(cmd,"cirs %d,%d,6,BLUE",160+x_pixel,262-y_pixel);
		//printf("uav_cmd:    %s\r\n\r\n",cmd);
		UART5_SendString(cmd);	// 繪制藍(lán)色圓形 x,y,radius,color
		UART5_SendBinary();
		
		sprintf(cmd,"t16.txt=\"(%d,%d)\"",(int)(x_fixed/10),(int)(y_fixed/10));
		//printf("uav_position:    %s\r\n\r\n",cmd);
		UART5_SendString(cmd);	// 寫入無人機(jī)位置坐標(biāo)(x,y)
		UART5_SendBinary();
		
		sprintf(cmd,"t10.txt=\"%.3f\"",uart4_flight_dist/100);
		//printf("uav_flight_dist:    %s\r\n\r\n",cmd);
		UART5_SendString(cmd);	// 寫入無人機(jī)航程
		UART5_SendBinary();
	}
	if(fire_flag == 1)	// 火源位置
	{
		fire_flag = 0;
		char cmd[30];
		memset(cmd,0,sizeof(cmd));
		
		float x_fixed,y_fixed;
		if(uart4_fire[0] > 480)
			x_fixed = 480;
		else if(uart4_fire[0] < 0)
			x_fixed = 0;
		else
			x_fixed = uart4_fire[0];
		uint16_t x_pixel = (uint16_t)(x_fixed*312/480);
		
		if(uart4_fire[1] > 400)
			y_fixed = 400;
		else if(uart4_fire[1] < 0)
			y_fixed = 0;
		else
			y_fixed = uart4_fire[1];
		uint16_t y_pixel = (uint16_t)(y_fixed*256/400);
		
		sprintf(cmd,"pic %d,%d,1",160+x_pixel,262-y_pixel);
		//printf("fire_cmd:   %s\r\n\r\n",cmd);
		UART5_SendString(cmd);	// 繪制紅色火災(zāi)圖像
		UART5_SendBinary();
		
		sprintf(cmd,"t8.txt=\"(%d,%d)\"",(int)(x_fixed/10),(int)(y_fixed/10));
		//printf("fire_position:    %s\r\n\r\n",cmd);
		UART5_SendString(cmd);	// 寫入火源位置坐標(biāo)
		UART5_SendBinary();
	}
}

2.4.3 小車控制無人機(jī)

依舊是藍(lán)牙串口的部分,藍(lán)牙串口發(fā)送“TakeOff\r\n”字符串,無人機(jī)串口檢測到后能夠解鎖。

// key_flag = 1時,小車控制無人機(jī)起飛
void Control_UAV_flight_status(void)
{
	if(key_flag == 1)
	{
		key_flag = 0;
		UART4_SendString("TakeOff\r\n");
	}
}

2.4.4 小車電機(jī)控制

小車控制電機(jī)最好需要檢測編碼器信號、讀取IMU的姿態(tài)和加速度信號,但由于時間限制,這一些部分并沒有編寫,完全處于開環(huán)控制。

開山斧模塊能夠直接獲取電機(jī)的轉(zhuǎn)速和方向:
空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同,無人機(jī)

此處對小車直流電機(jī)進(jìn)行控制,采用定時器控制PWM波占空比,以調(diào)整直流電機(jī)轉(zhuǎn)速。

1、PWM初始化:

void PWM0_Init(void)
{
	SysCtlPWMClockSet(MOTOR_PWM_SYSCTL_PWMDIV); // Set divider to 80M/8=10M=0.1us
	SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); // Enable PWM peripheral
	SysCtlDelay(2); // Insert a few cycles after enabling the peripheral to allow the clock to be fully activated
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Enable GPIOB peripheral
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // Enable GPIOB peripheral
	SysCtlDelay(2); // Insert a few cycles after enabling the peripheral to allow the clock to be fully activated
	// Use alternate function
	GPIOPinConfigure(GPIO_PB4_M0PWM2);
	GPIOPinConfigure(GPIO_PB5_M0PWM3);
	GPIOPinConfigure(GPIO_PD0_M0PWM6);
	GPIOPinConfigure(GPIO_PD1_M0PWM7);
	
	// Use pin with PWM peripheral
	GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4);//M0PWM2
	GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_5);//M0PWM3
	GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);//M0PWM6
	GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_1);//M0PWM7
	// Configure the PWM generator for count down mode with immediate updates to the parameters
	PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE 
										| PWM_GEN_SYNC_MODE);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE 
										| PWM_GEN_SYNC_MODE);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE 
										| PWM_GEN_SYNC_MODE);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE 
										| PWM_GEN_SYNC_MODE);
	
	// The period is set to 100us (10 KHz)
	period = MOTOR_PERIOD_MAX_800US; 
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period); // Set the period
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, period);
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, period);
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, period);
	// Start the timers in generator 0 and 1
	PWMGenEnable(PWM0_BASE, PWM_GEN_0);
	PWMGenEnable(PWM0_BASE, PWM_GEN_1);
	PWMGenEnable(PWM0_BASE, PWM_GEN_2);
	PWMGenEnable(PWM0_BASE, PWM_GEN_3);
	// Enable the outputs
	PWMOutputState(PWM0_BASE, 
					  PWM_OUT_0_BIT | PWM_OUT_1_BIT 
					| PWM_OUT_2_BIT | PWM_OUT_3_BIT
					| PWM_OUT_4_BIT | PWM_OUT_5_BIT
					| PWM_OUT_6_BIT | PWM_OUT_7_BIT
					,  true);									
}

2、PWM輸出:

// width1/2/3/4 為四個PWM通道設(shè)置的脈沖寬度(0-1000)
void PWM_Output(uint16_t width1, uint16_t width2, uint16_t width3, uint16_t width4)
{
	uint16_t pwm[4]={0};
	pwm[0]  = width1;
	pwm[1] = width2;
	pwm[2] = width3;
	pwm[3] = width4;

	//EPWM1端口M0PWM0、M0PWM1、M0PWM2、M0PWM3
	PWMPulseWidthSet(PWM0_BASE,PWM_OUT_2, pwm[0]);//PH0——M0PWM0 
	PWMPulseWidthSet(PWM0_BASE,PWM_OUT_3, pwm[1]);//PH1——M0PWM1 
	PWMPulseWidthSet(PWM0_BASE,PWM_OUT_6, pwm[2]);//PH2——M0PWM2 
	PWMPulseWidthSet(PWM0_BASE,PWM_OUT_7, pwm[3]);//PH3——M0PWM3
}      

3、小車運動:
簡單編寫了小車向前/后/左/右運動的函數(shù)。

// 向前,value為脈寬,換算一下相當(dāng)于速度;delay_ms為持續(xù)時間
void Car_Forward(int value,int delay_ms)
{
	PWM_Output(0,0,0,0);
	PWM_Output(0,value,value,0);
	Delay_Ms(delay_ms);
	PWM_Output(0,0,0,0);
}
// 向后,value為脈寬,換算一下相當(dāng)于速度;delay_ms為持續(xù)時間
void Car_Backward(int value,int delay_ms)
{
	PWM_Output(0,0,0,0);
	PWM_Output(value,0,0,value);
	Delay_Ms(delay_ms);
	PWM_Output(0,0,0,0);
}
// 左轉(zhuǎn),value為脈寬,換算一下相當(dāng)于轉(zhuǎn)速;delay_ms為持續(xù)時間
void Car_TurnLeft(int value,int delay_ms)
{
	PWM_Output(0,0,0,0);
	PWM_Output(0,value,0,value);
	Delay_Ms(delay_ms);
	PWM_Output(0,0,0,0);
}
//右轉(zhuǎn),value為脈寬,換算一下相當(dāng)于轉(zhuǎn)速;delay_ms為持續(xù)時間
void Car_TurnRight(int value,int delay_ms)
{
	PWM_Output(0,0,0,0);
	PWM_Output(value,0,value,0);
	Delay_Ms(delay_ms);
	PWM_Output(0,0,0,0);
}

4、小車移動到指定街區(qū)的函數(shù):
這一部分就是整活了,近處的街區(qū)還能將就一下,遠(yuǎn)的街區(qū)很容易跑偏。

int WaitTime = 10000;		// 小車靜止等待的時間為10s
// 在小車等待的時候,視覺模塊控制舵機(jī)上的激光筆照射模擬火源
void Car_Move(int position)	// position為火源id
{
	if(car_move_flag == 1)
	{
		car_move_flag = 0;
		switch(position){
			case 0:			//無火災(zāi),不用動
			break;
			case 1:			// 1號街區(qū)
				Car_Forward(500,1000);
				Delay_Ms(1000);
				Car_TurnLeft(500,1000);
				Delay_Ms(WaitTime);
				Car_TurnRight(500,1000);
				Delay_Ms(1000);
				Car_Backward(500,1000);
				Delay_Ms(1000);
			break;
			case 2:			// 2號街區(qū)
				Car_TurnRight(500,1000);
				Delay_Ms(500);
				Car_Forward(500,500);
				Delay_Ms(500);
				Car_TurnLeft(500,500);
				Delay_Ms(500);
				Car_Forward(500,3000);
				Car_TurnLeft(500,1000);
				Delay_Ms(500);
				Delay_Ms(WaitTime);
				Car_TurnRight(500,1000);
				Delay_Ms(500);
				Car_Backward(500,3000);
				Delay_Ms(1000);
			break;
			case 3:			// 3號街區(qū)
				Car_TurnRight(500,1000);
				Delay_Ms(500);
				Car_Forward(500,1000);
				Delay_Ms(500);
				Car_TurnLeft(500,1000);
				Delay_Ms(500);
				Car_Forward(500,3000);
				Car_TurnRight(500,1000);
				Delay_Ms(500);
				Delay_Ms(WaitTime);
				Car_TurnLeft(500,1000);
				Delay_Ms(500);
				Car_Backward(500,3000);
				Delay_Ms(1000);
			break;
			case 4:		// 最遠(yuǎn)的4號街區(qū),瞎跑
				Car_TurnRight(500,2000);
				Delay_Ms(500);
				Car_Forward(500,3000);
				Delay_Ms(500);
				Delay_Ms(WaitTime);
				Car_Backward(500,3000);
				Delay_Ms(1000);
			break;
			case 5:			// 5號街區(qū)
				Car_TurnRight(500,2000);
				Delay_Ms(500);
				Car_Forward(500,3000);
				Delay_Ms(500);
				Delay_Ms(WaitTime);
				Car_Backward(500,3000);
				Delay_Ms(1000);
			break;
			case 6:			// 6號街區(qū)
				Car_TurnRight(500,1000);
				Delay_Ms(500);
				Car_Forward(500,1500);
				Delay_Ms(500);
				Delay_Ms(WaitTime);
				Car_Backward(500,1000);
				Delay_Ms(1000);
			break;
			case 7:					// 旋轉(zhuǎn)測試
				Car_TurnRight(500,6000);
				Delay_Ms(1000);
				Car_TurnRight(500,5000);
				Delay_Ms(1000);
			break;
			default:
			break;
		}
	}
}

2.5 無人機(jī)程序設(shè)計

由于無人機(jī)程序大部分已經(jīng)編寫的差不多了,直接使用購買無人機(jī)的代碼修改。
無人機(jī)上需要安裝藍(lán)牙、光流、OpenMV或K210、激光筆、LED燈等外設(shè)。

2.5.1 藍(lán)牙串口程序

用來發(fā)送無人機(jī)位置信息和無人機(jī)監(jiān)測到的火源信息,接收小車發(fā)來的起飛解鎖信息。文章來源地址http://www.zghlxwxcb.cn/news/detail-629901.html

到了這里,關(guān)于空地協(xié)同智能消防系統(tǒng)——無人機(jī)、小車協(xié)同的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包