从零搭建麦轮小车

从零搭建麦轮小车

绘制3D模型(Solidworks建模)

全图

从零搭建麦轮小车_第1张图片

部件图

电机

从零搭建麦轮小车_第2张图片

共轴器

从零搭建麦轮小车_第3张图片

麦克纳姆轮

从零搭建麦轮小车_第4张图片

实物图

从零搭建麦轮小车_第5张图片

硬件电路搭建

驱动器

选用的是BLDC300W24V直流无刷控制器,有霍尔版本。通过PWM占空比控制速度
从零搭建麦轮小车_第6张图片

接线示意图

驱动器端
从零搭建麦轮小车_第7张图片
电机端
从零搭建麦轮小车_第8张图片
实物连接图
从零搭建麦轮小车_第9张图片从零搭建麦轮小车_第10张图片

脉冲反馈整形电路

由于驱动器的霍尔反馈输出存在较多毛刺,不利于后面做处理,故使用整形电路。
从零搭建麦轮小车_第11张图片
实物图
从零搭建麦轮小车_第12张图片
波形图
驱动器PWM输入
从零搭建麦轮小车_第13张图片
霍尔反馈整形后输出
从零搭建麦轮小车_第14张图片

PCB电路

由于时间问题,这个板子没有做出来
原理图
从零搭建麦轮小车_第15张图片
3维图
从零搭建麦轮小车_第16张图片从零搭建麦轮小车_第17张图片

FPGA脉冲-转速转换

原理

根据测量发现,转速反馈最高频率为200hz,故可以采用定时计脉冲的方式得到速度。
FPGA分频得到基准时钟,然后记录中脉冲个数,得到速度。

FPGA框图

从零搭建麦轮小车_第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张图片
转速输出
从零搭建麦轮小车_第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);

}

最后

你可能感兴趣的:(RoboMaster)