关注分享主机优惠活动
国内外VPS云服务器

电机控制和参数调整(伺服电机参数调整)

无刷电机结构简单,开发时间长,技术成熟,响应速度快,启动转矩大,运行稳定,制动效果好,控制精度高,使用成本低,维护方便。无刷电机具有干扰噪音低、运行寿命长、维护成本低等优点。电机控制模式扭矩控制指定电机提供设定扭矩。

电机参数调整1、电机相关0、废话1、电机类型2、电机控制方式2、电机控制器1、PID控制器2、PID各环节功能3、PID类型3、电机参数调整1、T电机参数调整1.1控制框图1.2 PID程序1.3电机控制完整程序1.4 PID调试技巧2、M2006(M3508)整定2.1 M2006(M3508)控制框图2.2 M2006和M3508完整控制程序2.3调试技巧存在的问题

一、电机相关电机作为一种能将电能转化为机械能的装置,在制造、医疗、运动控制等很多地方都有着重要的作用。想了解机器人的朋友学习电机也是一条不错(坎坷)的路。

0.废话。其实我和电机接触很多。记得小时候把“电机”拆开看,了解原理。我还把电机拿出来贴了更多的胶带,做了一些小的diy。后来高中学了电磁学,基本原理我也有所了解(不断刷题之后)。然后到了大学才真正用上。第一次用是大一买的单片机,配了电机,有程序调节速度。但是,因为某些原因,我没有再用。大三的时候学习了电机驱动,对电机有了更深入的了解,做了一些关于电机的实验。但是,我忘不了的是,研究生开始调试电机的时候,真的是……一言难尽。之前也咨询过很多大博客,所以想总结一下难忘的经历,给有需要的朋友一个参考。

1.根据电源类型,电机类型分为DC电机和交流电机。我们最常见的汽车是DC汽车。与前者相比,交流电机不需要换向器和电刷来改变电流的方向。与DC电机相比,它们具有更简单的结构和更高的功率,并广泛应用于工业领域。

根据有无刷分有刷电机和无刷电机。有刷电机结构简单,发展时间长,技术成熟,响应速度快,启动转矩大,运行稳定,制动效果好,控制精度高,使用成本低,维护方便。无刷电机具有低干扰、低噪音、运行平稳、使用寿命长、维护成本低等优点。所以我接触的主要是无刷电机。

根据有无反馈可分为步进电机和伺服电机。前者没有反馈信号,位置精度不够高,转速远低于后者。当需要精确控制时,伺服电机更常用。

2.电机控制模式扭矩控制:指定电机以提供设定扭矩。(不过因为扭矩传感器太贵了,这里的扭矩一般都是用电流换算的。在电流恒定的情况下,转矩=转矩恒定*电流)速度控制:指定电机以设定速度旋转。位置控制:指定电机旋转到设定位置。由于位置是速度的积分,因此需要三种控制模式的控制框图。下面是一个常见的控制结构图。当然,如果只用一种或两种控制方式,控制方案会比这个简单。

二、电机控制器为了方便用户使用,市面上很多电机都是针对上述控制方式进行包装的,也就是我们经常听到的——控制器。控制器的控制方案有很多种,不同的控制回路有不同的控制方案,如电流回路的FOC矢量控制,速度和位置回路的PID。当然,还有其他控制算法,但这里我们将只使用常用的。现在我们也可以开始讨论标题了。

1.PID控制器PID是一种传统而经典的控制算法,在工程中应用广泛。相对于其他只存在于纸面上的算法,PID是很接地气的。PID是比例、积分、微分的缩写。顾名思义,PID控制算法是比例、积分和微分的组合,定律可以描述为:u(t)= k p(e(t)+1t t∫0t e(t)d t+t d d e(t)d t u(t)= k _ p(e(t)+/frac{1}{t_t}/int_0^t e(t)dt+t _ d/frac { de(t)} { dt } u(t)= KP(e(t)+TT 1∫0t e(t)dt+TD T t t _ d TD为微分时间常数,u ( t ) u(t) u(t)为输入信号,e (t) e(t) e(t)为误差。

这三个环节在控制中也起着不同的控制作用。

2.比例环节P:比例环节与稳态误差有关。比例环节越大,上升速度越快,稳态误差越小。但是,再大也会有误差,误差是无法消除的,太大会导致震荡,但不稳定。

积分环节一:积分环节可以消除误差,合适的积分环节可以快速消除误差。但设定过大会造成超调,过大也会导致冲击和不稳定。

微分环节D:微分环节可以预测信号变化的方向,可以减少超调,提高响应速度,但过多会导致系统不稳定。

matlab PID的参考代码如下(上图是在下面代码的基础上修改的,但核心不变):

%%描述%受控系统:1/(0.1s+1)%控制器:PID%%clc,clearts = 0.001%采样时间= 0.001sys = TF (1,);%建立被控对象的传递函数dsys=c2d(sys,ts,“z”)%离散化);坚持住;命令信号(即期望输入)的%曲线p2=plot(时间,y,“--”);xlim();% PID曲线无积分分离保持;3.PID分类上面的PID宣传是针对连续的情况。在生活中,我们经常用到离散变量,比如时间,所以需要对PID公式进行离散化。根据离散化方法的不同,PID控制公式有两种,即位置PID和增量PID。

PID型u(n)= K p∫e(n)+K I∫e(n)+K d∫[e(n)e(n 1)]/T u(n)= K _ p * e(n)+K _ I */sum e(n)+K _ d *[e(n)-e(n-1)]/T u(n)= Kp∫e(n)+ki∑e(n)+KD[e(n)e当积分项饱和时,误差仍会累积。当误差反方向变化时,系统仍需要一定的时间退出饱和区,因此往往需要积分限幅和输出限幅。实际上,位置pid通常由PD控制。式中增量PIDδu(n)= K p∫[e(n)e(n 1)]+K I∫e(n)+K d∫[e(n)2∫e(n 1)+e(n 2)]/T/δu(n)= K _ p *[e(n)-e(n-1)]+K _ I * e(n)+K _ d *[e(n)-2 * e(n-1)+e(n4) 2e (n1)+e (n2)]/T增量公式不包含积分环节,控制增量只与前三个和后三个测量值有关,因此比位置公式对外界有更好的免疫性。 两者的关系可以看出,前者计算输入量,后者计算输入增量。很多同学可能都猜到了后者是前者的区别。想更详细的了解两者的关系,可以看看这位博主的:传送门。三、电机调整常用的参数调整方法比较开心。可以直接在厂商写的驱动下设置和测试参数,找到合适的参数,有的甚至有参数调整软件遍历参数找到合适的参数,这样就省去了。不过我这里要分享的参数调整方法,步骤需要多一点,但是大方向是一样的。这里以Tmotor的AK10-9和DJI的M2006无刷DC电机为例进行介绍。

1.Tmotor tuning Tmotor的电机本来是有调谐软件的,但是在开始的时候,由于资料不完善,加上它的控制回路不符合我们的应用要求,所以需要进行简单的修改。

1.1控制框图t电机的运动控制框图如下。正如你所看到的,他的电流回路采用FOC矢量控制,我们不能修改它。另外两个回路,速度回路和位置回路,只有比例环节,达不到无误差的目的,所以我们需要在他的电流回路上编写封装。我们需要的控制循环应该是这样的:先写控制程序吧。

1.2 PID程序在讨论离散PID之前,有位置PID算法和增量PID算法。以下是根据其公式编写的PID程序,使用前需要稍加修改。位置PID

* * * * * * * * * * * * * *位置PID * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *目标参考值浮动死区;//定义电机死区浮动err _ now//定义当前错误浮点err _ last//定义前一时刻的误差浮点KP;//比例环节系数浮动ki;//积分环节系数浮动KD;//微分环节系数,这里时间常数已经包含在float Pout中;//比例环节输出浮点Iout//积分环节输出浮点Dout//差分链路输出float IntegLimt//设置积分限幅浮点输出;//输出float OutputLimt//输出削波} PID _ PARM;//初始化PID参数的函数void PID _ parm _ init(PID _ parm * PID _ parm,floattarget,floatkp,floatki,floatkd,floatinteglimt,float output limt){ PID _ parm -> target = target;PID _ parm -> err _ now = 0;PID _ parm -> err _ last = 0;PID _ parm -> KP = KP;PID _ parm -> ki = ki;PID _ parm -> KD = KD;PID _ parm -> Pout = 0;PID _ parm -> Iout = 0;PID _ parm -> Dout = 0;PID _ parm -> IntegLimt = IntegLimt;PID _ parm -> output = 0;PID _ parm -> output limt = output limt;}//float PID _ cal(PID _ parm * PID _ parm,浮点反馈){ PID _ parm -> err _ now = PID _ parm -> target -反馈;PID _ parm -> Pout = PID _ parm -> KP * PID _ parm -> err _ now;PID _ parm -> Iout+= PID _ parm -> ki * PID _ parm -> err _ now;PID _ parm -> Dout = PID _ parm -> KD *(PID _ parm -> err _ now -PID _ parm -> err _ last);//积分限幅if(PID _ parm -> iout > PID _ parm -> integlimt)PID _ parm -> iout = PID _ parm -> integlimt;else if(PID _ parm -> Iout IntegLimt)PID _ parm -> Iout = -PID _ parm -> IntegLimt;//输出削波PID _ parm -> output = PID _ parm -> pout+PID _ parm -> iout+PID _ parm -> dout;if(PID _ parm -> output > PID _ parm -> output limt)PID _ parm -> output = PID _ parm -> output limt;else if(PID _ parm -> output output limt)PID _ parm -> output = -PID _ parm -> output limt;//数据更新PID _ parm -> err _ last = PID _ parm -> err _ now;返回pid_parm->输出;} float u;PID _ PARM PID _ parm;PID_parm_Init(&pid_parm,10,1,0.1,,0.5,50,100);//这里的参数是随机给定的,具体参数需要通过u = PID_cal(&pid_parm,fed)进行调整;//计算下一次输入的增量PID。

* * * * * * * * * * * * * *增量PID * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *目标参考值浮动死区;//定义电机死区浮动err _ now//定义当前错误浮点err _ last//定义前一时刻的误差浮点err _ llast//定义上下时间误差浮点KP;//比例环节系数浮动ki;//积分环节系数浮动KD;//微分环节系数,这里时间常数已经包含在float Pout中;//比例环节输出浮点Iout//积分环节输出浮点Dout//差分链路输出浮点输出;//输出增量float output _ last//最后一个输出浮点OutputLimt的增量;//输出削波} PID _ PARM;//初始化PID参数的函数void PID _ parm _ init(PID _ parm * PID _ parm,floattarget,floatkp,floatki,floatkd,float output limt){ PID _ parm -> target = target;PID _ parm -> err _ now = 0;PID _ parm -> err _ last = 0;PID _ parm -> err _ llast = 0;PID _ parm -> KP = KP;PID _ parm -> ki = ki;PID _ parm -> KD = KD;PID _ parm -> Pout = 0;fPID _ parm -> Iout = 0;PID _ parm -> Dout = 0;PID _ parm -> output = 0;PID _ parm -> output _ last = 0;PID _ parm -> output limt = output limt;}//float PID _ cal(PID _ parm * PID _ parm,浮点反馈){ PID _ parm -> err _ now = PID _ parm -> target -反馈;PID _ parm -> Pout = PID _ parm -> KP *(PID _ parm -> err _ now -PID _ parm -> err _ last);PID _ parm -> Iout = PID _ parm -> ki * PID _ parm -> err _ now;PID _ parm -> Dout = PID _ parm -> KD *(PID _ parm -> err _ now -2 * PID _ parm -> err _ last+PID _ parm -> err _ llast);//输出限幅PID _ parm -> output+= PID _ parm -> pout+PID _ parm -> iout+PID _ parm -> dout;if(PID _ parm -> output > PID _ parm -> output limt)PID _ parm -> output = PID _ parm -> output limt;else if(PID _ parm -> output output limt)PID _ parm -> output = -PID _ parm -> output limt;//数据更新PID _ parm -> err _ llast = PID _ parm -> err _ last;PID _ parm -> err _ last = PID _ parm -> err _ now;PID _ parm -> output _ last = PID _ parm -> output;返回pid_parm->输出;} float u;PID _ PARM PID _ parm;PID_parm_Init(&pid_parm,10,1,0.1,,0.5,100);//这里的参数是随机给定的,具体参数需要通过u = PID_cal(&pid_parm,fed)进行调整;//计算下一次输入1.3电机控制的完整程序。这里使用stm32进行控制,所有工程文件如下:

头文件密钥. h

# ifndef _ _ KEY _ h # define _ _ KEY _ h # include " sys . h "/*下面的方式是读取IO */# define KEY 0 gio _ ReadInputDataBit(GPIO e,GPIO _ Pin _ 4)//PE4 # define KEY 1 GPIO _ ReadInputDataBit(GPIO e,GPIO _ Pin _ 3)//PE3 # define KEY 2 GPIO _ ReadInputDataBit(GPIO e,GPIO _ Pin _ 2)//PE2 # define WK _ UP GPIO _ ReadInputDataBit(//IO初始化u8 KEY _ Scan(u8);//按键扫描功能#endif can.h

# ifndef _ _ CAN _ H # define _ _ CAN _ H # include " sys . H " void CAN 1 _ Init(void);//CAN1初始化u8 can 1 _ Send _ Msg(u8 * Msg);//发送数据u8 can 1 _ Receive _ Msg(u8 * buf);#endif pid.h

# ifndef _ _ PID _ H # define _ _ PID _ H # include " sys . H " # include " stdlib . H " typedef struct PID { float target;//目标参考值浮动死区;//定义电机死区浮动err _ now//定义当前错误浮点err _ last//定义前一时刻的误差浮点err _ llast//定义上下时间误差浮点KP;//比例环节系数浮动ki;//积分环节系数浮动KD;//微分环节系数,这里时间常数已经包含在float Pout中;//比例环节输出浮点Iout//积分环节输出浮点Dout//差分链路输出float IntegLimt//设置积分限幅浮点输出;//输出浮点output _ last//最后一个输出浮点OutputLimt的增量;//输出削波} PID _ PARM;void PID _ parm _ Init(PID _ PARM * PID _ parm,浮点目标,浮点死区,浮点kp,浮点ki,浮点kd,浮点IntegLimt,浮点输出limt);浮点Pos_PID_cal(PID_PARM *pid_parm,浮点反馈);浮点Inc_PID_cal(PID_PARM *pid_parm,浮点反馈);void PID_init(PID_PARM *Spd_PID,PID _ PARM * Pos _ PID);#endif电机. h

# ifndef _ _ MOTOR _ H # define _ _ MOTOR _ H # include " sys . H " # include " PID . H " # define pi 3.1415926 # define P _ MAX 12.5 # define P _ MIN -12.5 # define V _ MIN -46.57 # define KP _ MAX 500 # define KP _ MIN 0 # define KD _ MAX 5 # define KD _ MIN 0 # define T _ MAX 54 # define T _ MIN -typedef enum{Tmotor_Open = 0xfc,Tmotor_Close = 0xfd,Tmotor_SetZero = 0xfe,} Tmotor _ Modtypedef结构{ u8 id//idint 16 _ t speed _ RPS;//rad/Sint 16 _ t real _ torque;//反馈转矩uint16_t角度;//绝对角度} Tmotor _ measure _ textern Tmotor _ measure _ t TmotorData;//保存Tmotor motor int float _ to _ uint的状态(float x,float x _ min,float x _ max,int位);float uint_to_float(int x_int,float x_min,float x_max,int位);float limitf(float val,float min_val,float max _ val);void t motor _ mod(u8 mod);void get _ t motor _ measure(t motor _ measure _ t * ptr,CanRxMsg * Rxmsg);u8 set_Tmotor_torque(浮动扭矩);无效t电机速度控制(PID PARM

未经允许不得转载:主机频道 » 电机控制和参数调整(伺服电机参数调整)

评论 抢沙发

评论前必须登录!