之前智能車系列已經做了一個比較詳細的解析,但是美中不足是知識點被拆的太零散,可能對于新手來說不太友好,所以借著有空就再寫一點能讓車跑起來的方案。
當然,也就僅僅限于可以跑起來,元素以及高級算法就需要車友們自己去整了,主要還是方便新手上道,當然也歡迎大佬們提出建議。本文以電磁四輪為例進行講解。
材料準備
作為剛接觸電磁車的同學,咱們要想跑起來需要四大件,車模、電磁及運放模塊、主控及母板、電機驅動;
這里筆者打算分成兩種組別來推薦方案,一類是手頭沒有現成車模而且不是今年參賽的練習組,另外一類是今年的參賽組。
備賽組
1.車模
這里以基礎電磁四輪組為例,建議使用C車模,B車的傻蛋5舵機以及機械差速還是有些許的頭禿,當然官方今年好像已經宣布了換掉SD5舵機,由于C車是雙電機可以使用主動差速,所以建議大家上手選擇C車。
車模的機械結構搭建可以去參考往屆優秀隊伍的技術報告,至于怎么找到技術報告,比賽官網有,卓大博客也有—第十六屆全國大學智能車競賽技術報告與總決賽視頻下載。借用逐飛科技的示例車來展示一下:
2.硬件
主控:電磁車今年參賽要求是使用STC的單片機來參賽,所以就可以選購龍邱或者逐飛STC母板來作為主控;
電機驅動:目前比賽常用的有HIP4082、DRV8701、BTN7971或者IR系列加MOS全橋等;
電磁組所需的電感和運放模塊:目前較多的是OP2350、LM358、OPA4377等;
電源模塊:整個小車系統所需的電源種類一般是5V、3.3V、12V,需要有一個系統的電源管理方案,這個需要積累,BUCK、BOOST的電路,網上方案也很多,筆者之前使用的是德州儀器的TPS系列。
硬件設計的注意事項可以參考筆者抗干擾技術的那篇博客。
練習組
1.車模
對于不是急于參賽而是平時訓練的練習組,手頭如果沒有現成的車模和往屆的方案的,建議去淘寶找平價車模代替,因為自己一套買下來得個大幾千塊,都是學生黨,這也不是個小數目。
可以參考下圖這種使用舵機轉向而且后輪電機帶編碼器的車模,加上鋰電池這些一套下來300左右。(圖片來源于某寶,VANBOT教育機器人自營店)
由于原理都差不多一樣的,練習使用這種車模性價比極高,而且還可以留下來參加其他的比賽。
2.硬件方案
電機驅動:購買了這種車模的同學也可以直接用配套的電機驅動,或者使用L298N、TB6612這些電驅都可以。
主控:建議使用帶片內ADC的主控,STM32,STC32、STC16、MSP430都可以反正選一個自己熟悉的就行了。
電磁傳感器:可以購龍邱、或者輪趣科技的。
電源:選用兩節18650加一個LM2596的降壓模塊即可。
如果覺得麻煩,可以直接選購輪趣科技的學習版小車,如下圖:
當然,手頭有往屆的芯片和方案更好,這樣可以無縫銜接到比賽,比如K66、K60這些方案只是現在不用了,但是網上資料多啊,而且這些處理器性能拿來練手綽綽有余。
整車原理
在準備好上面的硬件后,再來捋一下整個小車的運行原理。
小車要正常行駛在賽道上,必定是需要實時根據賽道的狀態來調整車身姿態的,那么,電磁車是怎么樣獲取到賽道信息,又是怎樣實現轉向的呢。
賽道信息獲取及轉向原理
1.工字電感
電磁車是通過獲取賽道信號發生器產生的信號來來獲取賽道信息的,在賽道正中間會有一條磁感線,用來產生交變電磁信號。
小車通過前瞻上的電感即可獲得到賽道信息,為啥可以電感可以獲取賽道信息呢,其實很好理解,電磁感應都映像吧,導體切割磁感線會產生感應電動勢,工字電感內部的導線切割信號線產生的磁場,在電感引腳就會有感應電動勢。
電感距離磁場越近,產生的感應電動勢越大,距離越遠,產生的感應電動勢越小。
(有關電感配頻以及信號在各個節點的狀態可以去筆者的硬件篇查看)。
2.運放模塊
經過工字電感產生的感應電動勢是交流小信號,單片機是無法采集和處理這種小電壓的交變信號
所以需要在后面增加一個峰值檢測以及放大的運放電路,將交變信號進行選頻、檢波然后放到適當倍數,輸出單片機ADC可以采集的直流信號,將感應電動的大小轉換成為單片機ADC采集的數字作為輸入量。
3.轉向原理
了解了單個電感獲取賽道信息的原理后,為了讓小車能夠在賽道上行駛,至少會使用左、右兩個電感,通過ADC采集經過運放處理的感應電動勢值來計算偏差。
方法是直接左右電感采集值之差(或者差比和計算)來判斷賽道信息,將差比和計算出來的偏差以一定的比例關聯到舵機的pwm占空比來控制舵機打角,進而控制小車進行轉向。參考下表
其中系列1是左右電感直接作差的波形,系列2是經過差比和計算出來的波形,可見系列2的波形比系列1更加平滑,這有利于控制系統的跟隨。
具體原理:
如下圖,小車位于2號位置時,左右兩個電感距離信號的距離一樣,周圍磁場強度也基本一致,產生的感應電動勢也是大差不差,左右電感值差比和計算出來的偏差也是0,舵機位于正中間,保持小車直行。
小車位于3號位置時,由于彎道,左邊電感距離信號線近,磁場更強,產生的感應電動勢要大于右電感的感應電動勢,左右電感差比和計算偏差就很大了,將這個偏差輸出到舵機,讓小車左轉來消除這個偏差。
當小車遇見右轉賽道時,兩個電感的狀態剛好相反,此時需要右轉來抵消二者偏差。
詳細描述參考此文:
https://blog.csdn.net/weixin_43788952/article/details/105151921?utm_source=app&app_version=5.2.1&code=app_1562916241&uLinkId=usr1mkqgl919blen
4.元素判斷
從此圖可以看出理論上小車在經過三叉、環島和十字時,左右兩個電感的電感值都會接近磁感線,檢測這個特征就可以識別到了,為了防止誤判還可以增加一個中間電感或者斜放置電感來輔助判斷。
電感只有線圈切割磁場時才能產生感應電動勢,線圈和磁場平行時是沒有感應電動勢的,但是在這些特殊元素是,原本沒有切割磁場的電感可能突然就切割了磁感線,這里留給大家自己去發揮。
此處提供一個思路,直接看圖:
電機及舵機控制原理
舵機和電機都是通過PWM來控制的,只不過舵機控制的PWM的頻率是固定的(50-60HZ),通過改變占空比來實現打角角度。
而電機的頻率沒有指定范圍,但速度也是通過調節占空比來控制的,通過調節電機pwm輸出占空比完成對電機速度的調整,電磁組需注意電機對電磁信號會有干擾。
建議電機控制的pwm頻率設置為13-19khz,以盡可能的消除干擾。
具體的PWM控制原理以及H橋的講解之前已經寫過了,需要的同學去前面方向篇和電機控制篇查看。
代碼實現
在了解了上述原理后,我們就可以開始寫程序控制我們的小車,實現一個可以跑的狀態了。
首先,綜合上面的原理,需要初始化PWM來控制舵機和電機,其中舵機的PWM使用的是50-60hz的pwm進行控制(筆者用的50HZ進行控制),而電機的頻率是13-19Khz。
然后是獲取賽道信息的ADC,需要至少開啟兩路來實現信息采集。
還有為了保證系統的計算和輸出周期固定,需要開啟一個定時器中斷來保證輸出的周期穩定。
其他:根據自己的需求初始化IO控制屏幕,按鍵,蜂鳴器LED燈。
有了這個思路,任何一款處理器都可以實現功能了。筆者這里以STC為例。
框架:
以下代碼僅供參考, 僅僅是代碼框架 不能直接復制編譯!!!
void main()
{
//按照對應芯片進行上述內容的初始
DisableGlobalIRQ(); //關閉總中斷
board_init();
// lcd_init(); //1.8寸TFT初始化
/****電機初始化***/
pwm_init(PWMA_CH1P_P60, 10000, 0); //初始化PWM5 使用引腳P2.5 輸出PWM頻率10000HZ 占空比為百分之 pwm_duty / PWM_DUTY_MAX * 100
pwm_init(PWMA_CH2P_P62, 10000, 0); //初始化PWM5 使用引腳P2.5 輸出PWM頻率10000HZ 占空比為百分之 pwm_duty / PWM_DUTY_MAX * 100
pwm_init(PWMA_CH3P_P64, 10000, 0); //初始化PWM5 使用引腳P2.5 輸出PWM頻率10000HZ 占空比為百分之 pwm_duty / PWM_DUTY_MAX * 100
pwm_init(PWMA_CH4P_P66, 10000, 0); //初始化PWM5 使用引腳P2.5 輸出PWM頻率10000HZ 占空比為百分之 pwm_duty / PWM_DUTY_MAX * 100
/***電磁初始化***/
adc_init(ADC_P00, ADC_SYSclk_DIV_2); //初始化ADC,P1.0通道 ,ADC時鐘頻率:SYSclk/2
adc_init(ADC_P01, ADC_SYSclk_DIV_2); //初始化ADC,P1.1通道 ,ADC時鐘頻率:SYSclk/2
adc_init(ADC_P05, ADC_SYSclk_DIV_2); //初始化ADC,P1.2通道 ,ADC時鐘頻率:SYSclk/2
adc_init(ADC_P06, ADC_SYSclk_DIV_2); //初始化ADC,P1.2通道 ,ADC時鐘頻率:SYSclk/2
//****舵機初始化*****21.12.19/
Steering_Init(50,Steering_Duty); //舵機初始化,PWM頻率為50HZ
/*****編碼器出初始化***/
ctimer_count_init(CTIM0_P34); //初始化2個編碼器
ctimer_count_init(CTIM3_P04); //初始化2個編碼器
gpio_pull_set(P7_7,PULLUP);
BeeOff;
pit_timer_ms(TIM_4, 5); //使用TIMER作為周期中斷,時間5ms一次
EnableGlobalIRQ(); //開啟總中斷
while(1) //電機1
{
//可以放顯示、按鍵操作這一類沒有嚴格時序要求的。
//pwm_init(PWMB_CH1_P74,freq,1350); //PWMA初始化
//屏幕顯示:
// lcd_showstr(0,0,"L:");
// lcd_showuint16(5*8,0,L);
// lcd_showstr(0,1,"M:");
// lcd_showuint16(5*8,1,M);
// lcd_showstr(0,2,"R:");
// lcd_showuint16(5*8,2,R);
// lcd_showstr(0,3,"dutyL:");
// lcd_showuint16(5*8,3,dutyL);
// lcd_showstr(0,4,"dutyR:");
// lcd_showuint16(5*8,4,dutyR);
// lcd_showstr(0,5,"error:");
// lcd_showuint16(5*8,5,error);
//
// delay_ms(10);
}
}
//定時器中斷
void TM4_Isr() interrupt 20
{
TIM4_CLEAR_FLAG; //清除中斷標志
//電感采集獲取賽道信息,三電感 \ 000 000 000 //
L=adc_once(ADC_P00, ADC_10BIT);
M=adc_once(ADC_P01, ADC_10BIT);
R=adc_once(ADC_P05, ADC_10BIT);
My_Direction.NowError=50*(R-L)/(L+M+R);//差比和計算偏差
//方向環
Direction_Out();
//***電機控制***//
if(DIR1 == 1)//讀取編碼器方向
{
speed1 = 2*ctimer_count_read(CTIM0_P34);//
}
else
{
speed1 = 2*ctimer_count_read(CTIM0_P34) * -1;
}
ctimer_count_clean(CTIM0_P34);
if(DIR2 == 1) //輸出高電平,正轉
{
speed2 = 2*ctimer_count_read(CTIM3_P04)* -1;
}
else //輸出低電平,反轉
{
speed2 = 2*ctimer_count_read(CTIM3_P04) ;
}
ctimer_count_clean(CTIM3_P04);//清除積累
Current_speed=(speed1+speed2)/2;
Current_speed=Current_speed*20.4/(2355.2*0.02);//速度=脈沖數*周長/2368*周期;
//電機PI控制
error=(int)(speed-Current_speed);
duty=duty+(error-error_pre)*Motor_P+error*Motor_I;
error_pre=error;
if(duty>=100) duty=100;
else if(duty<=-100) duty=-100;
//電機動作 單極控制
pwm_duty(PWMA_CH2P_P62, 0);
pwm_duty(PWMA_CH1P_P60, dutyL*12);
pwm_duty(PWMA_CH4P_P66, 0);
pwm_duty(PWMA_CH3P_P64, dutyR*12);
}
需要完整代碼的同學去筆者的資源自行下載,也可以去文末鏈接找完賽代碼。
效果欣賞
總結
有關電磁車的介紹就到此為止,這篇主要是串了一下整個車的思路,細節還需要去看筆者之前的介紹。
文章如有不足歡迎指出,祝大家的小車可以拿到滿意的成績,筆者在評論區等待你們賽后的分享。
審核編輯 :李倩
-
智能車
+關注
關注
21文章
403瀏覽量
76952
原文標題:智能車淺談—手把手讓車跑起來(電磁篇)
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論