一、任務(wù)清單
1. 硬件部分
- 主控板: MSP432P401R
- 數(shù)據(jù)顯示: OLED
- 電機(jī): 霍爾編碼器電機(jī)
- 電池: 7.3V航模電池
- 巡線: OpenMV H7 Plus
- 警報(bào): 蜂鳴器
- 電機(jī)驅(qū)動(dòng): TB6612
- 儀器: 3D打印機(jī)
- 視覺云臺(tái): 3D建模打印
- 轉(zhuǎn)向: 數(shù)字舵機(jī)
-
其他: 銅柱、螺絲螺母、開關(guān)、面包板等。
2. 軟件部分
- 編譯器: Keil、OpenMV IDE
- 建模軟件: SketchUp Pro 2022
- 切片軟件: Cura
- 編程方式: 庫函數(shù)
- 編程語言: C、Python
二、OpenMV巡線
這里巡線不用紅外探頭的原因是考慮到市面上大多紅外對(duì)該虛線采集的信號(hào)并不是很準(zhǔn)確,存在偶然因素,故選擇攝像頭巡線。
這里我通過尋找有效區(qū)域內(nèi)的最大色塊,將其x軸坐標(biāo)返回給單片機(jī),在單片機(jī)端進(jìn)行數(shù)據(jù)處理,例如攝像頭下的分辨率為(w:320,h:240),設(shè)感應(yīng)區(qū)域ROI為(0,90,320,60) ,
采集到的有效色塊X坐標(biāo)為162,下圖可見,被圈出的大白框矩形為感應(yīng)區(qū)域ROI,中間被圈出的為最大有效色塊(圖中色塊閾值選擇為黑色),下方紅色圈出的為該色塊的X軸坐標(biāo)。
獲取目標(biāo)色塊:
img = sensor.snapshot() //截取攝像頭的一個(gè)圖像
blob=img.find_blobs([thresholds[0]], roi=ROI1, x_stride=10, y_stride=5,pixels_threshold=10, area_threshold=10, merge=True)
篩選出最大色塊:
def find_max(blobs):
max_size=0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob=blob
max_size = blob[2]*blob[3]
return max_blob
輸出最大色塊X坐標(biāo):
x=max_ID.cx()
將有效色塊坐標(biāo)發(fā)送至單片機(jī)端后該怎樣對(duì)數(shù)據(jù)進(jìn)行處理呢?
-
方法一:
例如采集到的坐標(biāo)為140,可知中心坐標(biāo)為160,已速度閉環(huán)為例,可先將坐標(biāo)差值Err=140-160=-20,可擬定為負(fù)值為偏左,正值為偏右,假如你的閉環(huán)在每10ms單相雙邊沿產(chǎn)生15個(gè)脈沖信號(hào),可設(shè)定一個(gè)線性系數(shù)k,有Err/k=P,Err2=Err_Last-Err=I,則Target_L=15+PI,Target_R=15-PI,Target_L和Target_R則為計(jì)算后的目標(biāo)脈沖,具體公式推導(dǎo)這里不做介紹,僅供參考! -
方法二:
這種方法也是更為簡單,更為方便的。
對(duì)色塊的X坐標(biāo)進(jìn)行區(qū)域劃分,例如中線為160,則:
①中心區(qū)域可劃分為(150,170)
②偏左區(qū)域可劃分為(120,150)、(90,120)、(60,90)、(30,60)、(0,30)
③偏右區(qū)域可劃分為(170,200)、(200,230)、(230,260)、(260,290)、(290,320)
即可根據(jù)不同位置發(fā)送不同指令。單片機(jī)段根據(jù)不同指令執(zhí)行不同程度的回正操作。
示例如下:
def Send_X(err):
if(err>=150 and err<=170):
uart.write("F")
elif(err>=120 and err<150):
uart.write("0")
elif(err>=90 and err<120):
uart.write("1")
elif(err>=60 and err<90):
uart.write("2")
elif(err>=30 and err<60):
uart.write("3")
elif(err>=0 and err<30):
uart.write("4")
elif(err>170 and err<200):
uart.write("5")
elif(err>=200 and err<230):
uart.write("6")
elif(err>=230 and err<260):
uart.write("7")
elif(err>=260 and err<290):
uart.write("8")
elif(err>=290 and err<320):
uart.write("9")
其中Err表示踩到的X坐標(biāo),根據(jù)不同坐標(biāo)區(qū)域發(fā)送不同指令,在單片機(jī)端接收操作如下:
if( openmv_rx=='F' )
{
}
//偏向左邊
else if( openmv_rx=='0' )
{
}
else if( openmv_rx=='1' )
{
}
else if( openmv_rx=='2' )
{
}
......
//偏向右邊
else if( openmv_rx=='5' )
{
}
else if( openmv_rx=='6' )
{
}
......
三、舵機(jī)轉(zhuǎn)向
舵機(jī)轉(zhuǎn)向問題,在學(xué)習(xí)較為常用的為180°舵機(jī),這里我以180°數(shù)字舵機(jī)進(jìn)行簡單介紹
常用的舵機(jī)大多都分為3根線,其中倆根為VCC和GND,也就是電源線,剩下一根為信號(hào)線,也就是控制舵機(jī)的線
-
舵機(jī)控制
關(guān)于舵機(jī)的控制說的通俗易懂點(diǎn)就是控制信號(hào)線的脈寬,通過控制不同脈沖舵機(jī)轉(zhuǎn)動(dòng)不同角度,如下所示:
20ms為例
0.5ms ------------ 0度;
1.0ms ------------ 45度;
1.5ms ------------ 90度;
2.0ms ------------ 135度;
2.5ms ------------ 180度;
設(shè)一個(gè)PWM周期為20ms,則控制有效電平為0.5ms,也就是一百分之一的時(shí)候,舵機(jī)保持0°,依次類推。
-
實(shí)時(shí)轉(zhuǎn)向
可根據(jù)上面巡線返回的信號(hào)進(jìn)行轉(zhuǎn)向,如當(dāng)接收到信號(hào)F時(shí),表示在中心區(qū)域,則舵機(jī)保持直線行駛狀態(tài),也就是90°,若接收到1-4信號(hào),則舵機(jī)向左偏向,120°、150°、180°等,如接收到5-9信號(hào),則舵機(jī)向右偏向,60°、30°、0°等。 -
舵機(jī)初始化
這里以定時(shí)器A0的通道三為例,如下代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-612541.html
/*初始化引腳*/
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
Timer_A_PWMConfig TimA0_PWMConfig;
/*定時(shí)器PWM初始化*/
TimA0_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //時(shí)鐘源
TimA0_PWMConfig.clockSourceDivider = psc; //時(shí)鐘分頻 范圍1-64
TimA0_PWMConfig.timerPeriod = ccr0; //自動(dòng)重裝載值(ARR)
TimA0_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_3; //通道三
TimA0_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET; //輸出模式
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TimA0_PWMConfig); /* 初始化比較寄存器以產(chǎn)生 PWM1 */
- 角度控制
void SG90_angle(int a)
{
int pwm=500+2000/180*a;
MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_3, pwm);
}
四、停止線識(shí)別
-
方法一
通過判斷有效色塊的面積或者寬度,因?yàn)樵谘簿€中都是1cm1cm的虛線組成,而停止線為5cm1cm,所以可通過色塊的面積或者寬度等其他因素進(jìn)行識(shí)別,返回停止信號(hào)。
w=max_ID.w()
if w>=80:
uart.write("S")
-
方法二
因?yàn)檎麄€(gè)賽圖小車走的路程是固定的,則也可用通過小車走的路程進(jìn)行停止。
if(sum>=1)
{
Stop();
PID_SetPoint(&L_pid,0);
PID_SetPoint(&R_pid,0);
}
五、技術(shù)交流
疑難解答或技術(shù)交流聯(lián)系下方wx即可??????文章來源地址http://www.zghlxwxcb.cn/news/detail-612541.html
到了這里,關(guān)于基于MSP432P401R爬坡小車【2020年電賽C題】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!