從零搭建麥輪小車

繪製3D模型(Solidworks建模)

全圖

麥克納姆輪小車強化學習訓練_github

部件圖

電機

麥克納姆輪小車強化學習訓練_github_02

共軸器

麥克納姆輪小車強化學習訓練_github_03

麥克納姆輪

麥克納姆輪小車強化學習訓練_上升沿_04

實物圖

麥克納姆輪小車強化學習訓練_github_05

硬件電路搭建

驅動器

選用的是BLDC300W24V直流無刷控制器,有霍爾版本。通過PWM佔空比控制速度

麥克納姆輪小車強化學習訓練_上升沿_06

接線示意圖

驅動器端

麥克納姆輪小車強化學習訓練_github_07


電機端

麥克納姆輪小車強化學習訓練_上升沿_08


實物連接圖

麥克納姆輪小車強化學習訓練_github_09

麥克納姆輪小車強化學習訓練_上升沿_10

脈衝反饋整形電路

由於驅動器的霍爾反饋輸出存在較多毛刺,不利於後面做處理,故使用整形電路。

麥克納姆輪小車強化學習訓練_上升沿_11


實物圖

麥克納姆輪小車強化學習訓練_github_12


波形圖

驅動器PWM輸入

麥克納姆輪小車強化學習訓練_麥克納姆輪小車強化學習訓練_13


霍爾反饋整形後輸出

麥克納姆輪小車強化學習訓練_github_14

PCB電路

由於時間問題,這個板子沒有做出來

原理圖

麥克納姆輪小車強化學習訓練_麥克納姆輪小車強化學習訓練_15


3維圖

麥克納姆輪小車強化學習訓練_麥克納姆輪小車強化學習訓練_16

麥克納姆輪小車強化學習訓練_上升沿_17

FPGA脈衝-轉速轉換

原理

根據測量發現,轉速反饋最高頻率為200hz,故可以採用定時計脈衝的方式得到速度。
FPGA分頻得到基準時鐘,然後記錄中脈衝個數,得到速度。

FPGA框圖

麥克納姆輪小車強化學習訓練_github_18

具體實現

上升沿計數

always @ (posedge clkin or negedge rst_n)
begin
	if(!rst_n)	datatmp = 2'b0;
	else datatmp = {datain,datatmp[1]}; 
end

always @ (posedge clkin or negedge rst_n)
begin
  if(!rst_n)	cnt = 36'b0; 
  else if(datatmp == 2'b10) //上升沿
  begin
    cnt = cnttmp + 1'b1;
    cnttmp = 36'b0;
  end
  else
	 cnttmp = cnttmp + 1'b1;  
end

轉速換算

always @ (posedge clkin or negedge rst_n)
begin
 if(!rst_n)	fx = 15'b0; 
 else if ( 36'd5000 < cnt && cnt < 36'd100000 && cnttmp < 36'd100000)
	   fx <= 36'd1_0000_0000 / cnt;   //100 ~ 2000
 else
		fx <= 0;
end

實物圖

使用正點原子-新起點開發板 做測試,後面採用最簡系統板。

麥克納姆輪小車強化學習訓練_上升沿_19


轉速輸出

麥克納姆輪小車強化學習訓練_github_20

STM32控制程序

主要部分

設置電機轉速
void Set_Wheel_Speed(int16_t target,CAR_WHEEL *wheel,PID_GENERAL *pid,uint8_t Wheel_Num)
{
	Wheel_PID(wheel->speed,target,pid);
	switch(Wheel_Num)
	{
		case W_LF:
			if(pid->output > 0)	
			{
				DIR_CTL_LF(Bit_SET);
				PWM_F_L(fabs(pid->output));
			}
			else {
				DIR_CTL_LF(Bit_RESET);
				PWM_F_L(fabs(pid->output));
			}
			break;
		case W_RF:
			if(pid->output > 0)	
			{
				DIR_CTL_RF(Bit_SET);
				PWM_F_R(fabs(pid->output));
			}
			else {
				DIR_CTL_RF(Bit_RESET);
				PWM_F_R(fabs(pid->output));
			}
			break;
		case W_LB:
			if(pid->output > 0)	
			{
				DIR_CTL_LB(Bit_SET);
				PWM_B_L(fabs(pid->output));
			}
			else {
				DIR_CTL_LB(Bit_RESET);
				PWM_B_L(fabs(pid->output));
			}
			break;
		case W_RB:
			if(pid->output > 0)	
			{
				DIR_CTL_RB(Bit_SET);
				PWM_B_R(fabs(pid->output));
			}
			else {
				DIR_CTL_RB(Bit_RESET);
				PWM_B_R(fabs(pid->output));
			}
			break;
		default: break;
	}
}
遙控器控制
void Motor_Control(void)
{
	static int16_t channel_1 = 0,channel_2 = 0,channel_4 = 0;//channel_3 = 0
	
	channel_1 = -rc_data.Channel_Current[2]/800.0f*10000*0.5f;	//throttle
	channel_2 = rc_data.Channel_Current[0]/800.0f*10000*0.5f;		//rotate
	//channel_3 = rc_data.Channel_Current[1]/800.0f*10000*0.5f;		// no use
	channel_4 = -rc_data.Channel_Current[3]/800.0f*10000*0.5f;	//shift-left/right

	Set_Wheel_Speed(channel_1-channel_4-channel_2,&Car_Wheel_LF,&PID_LF,W_LF);//-
	Set_Wheel_Speed(-channel_1-channel_4-channel_2,&Car_Wheel_RF,&PID_RF,W_RF);
	Set_Wheel_Speed(channel_1+channel_4-channel_2,&Car_Wheel_LB,&PID_LB,W_LB);//-
	Set_Wheel_Speed(-channel_1+channel_4-channel_2,&Car_Wheel_RB,&PID_RB,W_RB);

}

最後

麥克納姆輪小車強化學習訓練_sed_21