摘要:有刷電機(jī)結(jié)構(gòu)簡單開發(fā)久技術(shù)成熟響應(yīng)速度快,起動(dòng)扭矩大運(yùn)行平穩(wěn),起制動(dòng)效果好控制精度高使用成本低,維修方便而無刷電機(jī)由于無電刷,具有低干擾噪音低運(yùn)轉(zhuǎn)順暢壽命長低維護(hù)成本等優(yōu)點(diǎn)。電機(jī)控制方式力矩控制指定電機(jī)提供設(shè)置大小的力矩。
電機(jī)作為一種能將電能轉(zhuǎn)化為機(jī)械能的裝置,其在制造、醫(yī)療、運(yùn)動(dòng)控制等等許多地方都起著重要的作用。想學(xué)習(xí)了解機(jī)器人的小伙伴,從電機(jī)了解起走也是一條不錯(cuò)(坎坷)的道路。
???其實(shí)電機(jī)對(duì)于我來說是接觸的比較多了的,記得小時(shí)候玩四驅(qū)車,就特意將“馬達(dá)”拆開來看過想搞懂原理,也多帶帶將電機(jī)拿出來制作了一些小的diy,后來到了高中在學(xué)到了電磁學(xué),算是了解了基礎(chǔ)的原理了(在不停的刷題后),再后來到大學(xué)就是真正的使用了。第一次使用應(yīng)該是在大一買的單片機(jī),配了一個(gè)電機(jī),有程序可以進(jìn)行調(diào)速,但當(dāng)時(shí)由于一些原因,沒有再去使用。又到了大三,學(xué)習(xí)了電機(jī)拖動(dòng),對(duì)電機(jī)的認(rèn)識(shí)又深了一點(diǎn),也做了一些關(guān)于電機(jī)的實(shí)驗(yàn)。但是,令我難以忘記的是研究生開始調(diào)試電機(jī)的時(shí)候,真的是…一言難盡,之前也參考過許多大佬的博客,所以想把自己的這段難忘的經(jīng)歷做個(gè)總結(jié),也給有需要的朋友一個(gè)參考。
按電源種類分為:直流電機(jī)和交流電機(jī)。我們常見常用的電機(jī)大多是直流電機(jī),相比前者,交流電機(jī)不需要換向器和電刷轉(zhuǎn)換電流方向,與直流電機(jī)相比它的結(jié)構(gòu)更簡單,功率更大,在工業(yè)領(lǐng)域被廣泛應(yīng)用
根據(jù)有無電刷分為:有刷電機(jī)和無刷電機(jī)。有刷電機(jī)結(jié)構(gòu)簡單、開發(fā)久技術(shù)成熟、響應(yīng)速度快,起動(dòng)扭矩大、運(yùn)行平穩(wěn),起制動(dòng)效果好、控制精度高、使用成本低,維修方便;而無刷電機(jī)由于無電刷,具有低干擾、噪音低、運(yùn)轉(zhuǎn)順暢、壽命長、低維護(hù)成本等優(yōu)點(diǎn)。于是我接觸的以無刷電機(jī)為主。
根據(jù)有無反饋分為:步進(jìn)電機(jī)和伺服電機(jī)。前者沒有反饋信號(hào),位置精度不夠高,且轉(zhuǎn)速遠(yuǎn)遠(yuǎn)小于后者。在需要精確的控制,伺服電機(jī)更加常用。
| |
由于位置是速度的積分,所以三種控制方式的控制框圖是有要求的,下面是一種常見的控制結(jié)構(gòu)圖,當(dāng)然,如果只針對(duì)某一兩種控制模式,其控制方案將比這個(gè)更加簡易。
????為了方便用戶的使用,市面上許多電機(jī)都是針對(duì)上面的控制方式進(jìn)行了封裝的,也就是我們常聽說的——控制器。控制器的控制方案有許多,針對(duì)不同的控制環(huán)也有不同的控制方案,例如:對(duì)于電流環(huán),有FOC矢量控制,速度、位置環(huán)有PID。當(dāng)然,也有其他的控制算法,但這里我們就使用常用的就行了。現(xiàn)在我們也可以開始談?wù)剺?biāo)題了。
????PID 是一種傳統(tǒng)且經(jīng)典的控制算法,在工程中應(yīng)用非常廣泛,相比其他高大上甚至只存在于 paper 上的算法, PID 是非常接地氣的。
????PID ,即:Proportional(比例)、Integral(積分)、Differential(微分)的縮寫。顧名思義,PID 控制算法是結(jié)合比例、積分和微分的融合怪,其規(guī)律可以描述為:
u ( t ) = K p ( e ( t ) + 1 T t ∫ 0 t 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?dtde(t)?
????其中 K p K_p Kp? 是比例增益, T t T_t Tt? 是積分時(shí)間常數(shù), T d T_d Td? 是微分時(shí)間常數(shù), u ( t ) u(t) u(t) 是輸入信號(hào), e ( t ) e(t) e(t) 是誤差。
????三個(gè)環(huán)節(jié)在控制中也分別起著不同的控制作用。
比例環(huán)節(jié) P:比例環(huán)節(jié)與穩(wěn)態(tài)誤差相關(guān),比例環(huán)節(jié)越大,上升速度越快,且穩(wěn)態(tài)誤差越小,但無論怎樣多大都會(huì)存在誤差,不能消除誤差,而且過大還會(huì)導(dǎo)致震蕩,反而不穩(wěn)定
積分環(huán)節(jié) I:積分環(huán)節(jié)則可以消除誤差,合適的積分環(huán)節(jié)可以很快的消除誤差,但是設(shè)置較大會(huì)產(chǎn)生超調(diào),并且過大也會(huì)導(dǎo)致震蕩,從而不穩(wěn)定
微分環(huán)節(jié) D:微分環(huán)節(jié)具有預(yù)測(cè)作用,可以預(yù)測(cè)信號(hào)的變化方向,從而可以減小超調(diào),提高響應(yīng)速度,但過大會(huì)導(dǎo)致系統(tǒng)不穩(wěn)定
matlab PID 的參考代碼如下(上面的圖是在下面代碼基礎(chǔ)上修改了一點(diǎn),但是核心沒有變):
%% 說明% 被控系統(tǒng): 1/(0.1s+1)% 控制器: PID%%clc,clearts=0.001; %采樣時(shí)間=0.001ssys=tf(1,[0.1,1]); %建立被控對(duì)象傳遞函數(shù)dsys=c2d(sys,ts,"z") % 離散化[num,den]=tfdata(dsys,"v"); % 得到差分方程系數(shù) y(k) = -den[2]*y(k-1) + num[2]*u(k-1)e_last=0; %前一時(shí)刻的偏差 E_integ=0; %累積偏差u_last=0.0; %前一時(shí)刻的控制量y_last=0; %前一時(shí)刻的輸出% PID參數(shù)kp=1; ki=0;kd=0;u=zeros(1,10000); %設(shè)置仿真長度time=zeros(1,10000); %時(shí)刻點(diǎn)(設(shè)定10000個(gè))for k=1:1:10000 time(k)=k*ts; %時(shí)間 r(k)=100; %期望值 y(k)=-1*den(2)*y_last + num(2)*u_last; %系統(tǒng)響應(yīng)輸出序列 e(k)=r(k)-y(k); %誤差信號(hào) u(k)=kp*e(k)+ki*E_integ+kd*(e(k)-e_last); %系統(tǒng)PID控制器輸出序列 E_integ=E_integ+e(k); %誤差的累加和 u_last=u(k); %前一個(gè)的控制器輸出值 y_last=y(k); %前一個(gè)的系統(tǒng)響應(yīng)輸出值 e_last=e(k); %前一個(gè)誤差信號(hào)的值endp1=plot(time,r,"-.");xlim([0,1]);hold on; %指令信號(hào)的曲線(即期望輸入)p2=plot(time,y,"--");xlim([0,1]); %不含積分分離的PID曲線hold on;
????上面的 PID公示 是針對(duì)連續(xù)情況下的,而在生活中,我們常常使用的是離散型的變量,比如時(shí)間,于是我們需要將 PID 的公式進(jìn)行離散化,根據(jù)離散化的方法不同,PID 控制的公式就有兩種,即位置式 PID 和增量式 PID,
????常見的調(diào)參方式是比較快樂的,直接在生產(chǎn)商寫好的驅(qū)動(dòng)下進(jìn)行參數(shù)的設(shè)置以及測(cè)試,找到合適的參數(shù),更有的還有調(diào)參軟件,遍歷參數(shù)尋找合適的參數(shù),從而省去人工調(diào)試的復(fù)雜環(huán)節(jié)。
????但這里想要分享的調(diào)參方法要多一點(diǎn)步驟,但是大體方向是不變的,這里以 Tmotor 的 AK10-9 與 大疆的 M2006 兩款無刷直流電機(jī)為例子進(jìn)行介紹。
????Tmotor 的電機(jī)本來是有調(diào)參軟件的,但是最開始的時(shí)候由于資料不完善,加上他的控制環(huán)不符合我們的應(yīng)用要求,所以我們需要進(jìn)行簡單的修改。
Tmotor 的運(yùn)動(dòng)控制框圖如下,可以看到他的電流環(huán)采用 FOC 矢量控制,我們不能修改,另外兩個(gè)環(huán),速度環(huán)和位置環(huán),只有比例環(huán)節(jié),不能達(dá)到無誤差的目標(biāo),所以我們需要在他的電流環(huán)上進(jìn)行編寫封裝。
我們需要的控制環(huán)應(yīng)該如下:
下面我們先編寫控制程序。
之前探討過離散 PID 有位置式 PID 算法和增量式 PID 算法,下面是根據(jù)其公式編寫的 PID 程序,在使用之前需要稍稍修改一下參數(shù)。
位置式 PID
********************位置式 PID***************************** 輸入?yún)?shù):電機(jī)電流速度位置等反饋值fed ***********************************************************typedef struct PID{ float target; //目標(biāo)參考值 float deadband; //定義電機(jī)死區(qū) float err_now; //定義當(dāng)前誤差 float err_last; //定義上一時(shí)刻誤差 float kp; //比例環(huán)節(jié)系數(shù) float ki; //積分環(huán)節(jié)系數(shù) float kd; //微分環(huán)節(jié)系數(shù),這里已將時(shí)間常數(shù)包含進(jìn)去 float Pout; //比例環(huán)節(jié)輸出 float Iout; //積分環(huán)節(jié)輸出 float Dout; //微分環(huán)節(jié)輸出 float IntegLimt; //設(shè)置積分限幅 float output; //輸出量 float OutputLimt;//輸出限幅}PID_PARM;//初始化PID參數(shù)的函數(shù)void PID_parm_Init(PID_PARM *PID_parm,float target,float kp,float ki,float kd,float IntegLimt,float OutputLimt){ 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->OutputLimt = OutputLimt;}//計(jì)算PID的函數(shù)float PID_cal(PID_PARM *pid_parm,float feedback){ pid_parm->err_now = pid_parm->target - feedback; 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 < -pid_parm->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->OutputLimt) pid_parm->output = pid_parm->OutputLimt; else if(pid_parm->output < -pid_parm->OutputLimt) pid_parm->output = -pid_parm->OutputLimt; //數(shù)據(jù)更新 pid_parm->err_last = pid_parm->err_now; return pid_parm->output;}float u; PID_PARM pid_parm;PID_parm_Init(&pid_parm,10,1,0.1,,0.5,50,100); //這里的參數(shù)隨機(jī)給的,具體參數(shù)需要調(diào)節(jié)u = PID_cal(&pid_parm,fed); //計(jì)算出來的下一次輸入
增量式 PID
********************增量式 PID***************************** 輸入?yún)?shù):電機(jī)電流速度位置等反饋值fed ***********************************************************typedef struct PID{ float target; //目標(biāo)參考值 float deadband; //定義電機(jī)死區(qū) float err_now; //定義當(dāng)前誤差 float err_last; //定義上一時(shí)刻誤差 float err_llast; //定義上上時(shí)刻誤差 float kp; //比例環(huán)節(jié)系數(shù) float ki; //積分環(huán)節(jié)系數(shù) float kd; //微分環(huán)節(jié)系數(shù),這里已將時(shí)間常數(shù)包含進(jìn)去 float Pout; //比例環(huán)節(jié)輸出 float Iout; //積分環(huán)節(jié)輸出 float Dout; //微分環(huán)節(jié)輸出 float output; //輸出增量 float output_last; //上一次輸出的增量 float OutputLimt; //輸出限幅}PID_PARM;//初始化PID參數(shù)的函數(shù)void PID_parm_Init(PID_PARM *PID_parm,float target,float kp,float ki,float kd,float OutputLimt){ 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->OutputLimt = OutputLimt;}//計(jì)算PID的函數(shù)float PID_cal(PID_PARM *pid_parm,float feedback){ pid_parm->err_now = pid_parm->target - feedback; 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->OutputLimt) pid_parm->output = pid_parm->OutputLimt; else if(pid_parm->output < -pid_parm->OutputLimt) pid_parm->output = -pid_parm->OutputLimt; //數(shù)據(jù)更新 pid_parm->err_llast = pid_parm->err_last; pid_parm->err_last = pid_parm->err_now; pid_parm->output_last = pid_parm->output; return pid_parm->output;}float u; PID_PARM pid_parm;PID_parm_Init(&pid_parm,10,1,0.1,,0.5,100); //這里的參數(shù)隨機(jī)給的,具體參數(shù)需要調(diào)節(jié)u = PID_cal(&pid_parm,fed); //計(jì)算出來的下一次輸入
這里采用的 stm32 進(jìn)行控制的,工程文件全部在下面:
key.h
#ifndef __KEY_H#define __KEY_H #include "sys.h" /*下面的方式是通過直接操作庫函數(shù)方式讀取IO*/#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //PE4#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) //PE3 #define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //PA0#define KEY0_PRES 1#define KEY1_PRES 2#define KEY2_PRES 3#define WKUP_PRES 4void KEY_Init(void); //IO初始化u8 KEY_Scan(u8); //按鍵掃描函數(shù) #endif
can.h
#ifndef __CAN_H#define __CAN_H #include "sys.h" void CAN1_Init(void);//CAN1初始化 u8 CAN1_Send_Msg(u8* msg); //發(fā)送數(shù)據(jù) u8 CAN1_Receive_Msg(u8 *buf);#endif
pid.h
#ifndef __PID_H#define __PID_H #include "sys.h" #include "stdlib.h"typedef struct PID{ float target; //目標(biāo)參考值 float deadband; //定義電機(jī)死區(qū) float err_now; //定義當(dāng)前誤差 float err_last; //定義上一時(shí)刻誤差 float err_llast; //定義上上時(shí)刻誤差 float kp; //比例環(huán)節(jié)系數(shù) float ki; //積分環(huán)節(jié)系數(shù) float kd; //微分環(huán)節(jié)系數(shù),這里已將時(shí)間常數(shù)包含進(jìn)去 float Pout; //比例環(huán)節(jié)輸出 float Iout; //積分環(huán)節(jié)輸出 float Dout; //微分環(huán)節(jié)輸出 float IntegLimt; //設(shè)置積分限幅 float output; //輸出量 float output_last; //上一次輸出的增量 float OutputLimt; //輸出限幅}PID_PARM;void PID_parm_Init(PID_PARM *PID_parm,float target,float deadband,float kp,float ki,float kd,float IntegLimt,float OutputLimt);float Pos_PID_cal(PID_PARM *pid_parm,float feedback);float Inc_PID_cal(PID_PARM *pid_parm,float feedback);void PID_init(PID_PARM *Spd_PID,PID_PARM *Pos_PID);#endif
motor.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_MAX 46.57#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 -54extern u8 Tmotor_Mod_Buf[3][8];typedef enum{ Tmotor_Open = 0xfc, Tmotor_Close = 0xfd, Tmotor_SetZero = 0xfe,}Tmotor_Mod;typedef struct{ u8 id; // id int16_t speed_rps; // rad/s int16_t real_torque; // 反饋力矩 uint16_t angle; // 絕對(duì)角度}Tmotor_measure_t;extern Tmotor_measure_t TmotorData; // 保存Tmotor電機(jī)的狀態(tài)int float_to_uint(float x, float x_min, float x_max, int bits);float uint_to_float(int x_int, float x_min, float x_max, int bits);float limitf(float val, float min_val, float max_val);void Tmotor_mod(u8 mod);void get_Tmotor_measure(Tmotor_measure_t *ptr, CanRxMsg *Rxmsg);u8 set_Tmotor_torque(float torque);void Tmotor_Speed_Control(PID_PARM
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/125303.html
摘要:起因及介紹在處理原始對(duì)賬文件的時(shí)候,我將數(shù)據(jù)歸類后批量存入相應(yīng)的表中。結(jié)論事務(wù)只能管著開啟事務(wù)的線程,其他子線程出了問題都感知不到,所以在多線程環(huán)境操作要慎重。高頻容易搞死服務(wù)器,低頻會(huì)阻塞自身程序。重試次數(shù)和超時(shí)時(shí)間根據(jù)業(yè)務(wù)情況設(shè)置。 起因及介紹 在處理原始對(duì)賬文件的時(shí)候,我將數(shù)據(jù)歸類后批量存入相應(yīng)的表中。在持久化的時(shí)候,用了parallelStream(),想著同時(shí)存入很多表這樣可...
摘要:力矩控制模式電機(jī)在運(yùn)行過程的電流,始終等于給定的值。設(shè)定電流為零,彈簧不被拉伸。比如機(jī)械臂從點(diǎn)運(yùn)動(dòng)到點(diǎn),并限制揮舞過程中的最大速度和最大力矩。 目錄 說明一、電機(jī)...
摘要:一硬件框架與模型設(shè)計(jì)機(jī)械臂最核心的部分應(yīng)該就是關(guān)節(jié)部分的伺服電機(jī)了,針對(duì)與文稿中的設(shè)計(jì)思路,每個(gè)伺服電機(jī)都為一獨(dú)立的控制系統(tǒng),并通過總線的形式獲取數(shù)據(jù)并控制。 ##...
摘要:每個(gè)控制周期需要做的內(nèi)容包括獲取陀螺儀和編碼器兩個(gè)傳感器的數(shù)據(jù),傳入直立環(huán)和速度環(huán)算法中進(jìn)行計(jì)算得到控制量,將控制量作用于直流電機(jī)上。 Ruff Lite Ruff Lite 是 Ruff 團(tuán)隊(duì)針對(duì) MCU(MicroController Unit,微控制器)推出的 Ruff OS,具有高實(shí)時(shí)性,占用內(nèi)存小等特點(diǎn)。目前官方支持的開發(fā)板為TI TM4C1294-LaunchPad ,R...
摘要:綜合諸多考慮與相應(yīng)調(diào)研,我們希望能夠制作出一款宿舍升降機(jī)為同學(xué)們提供更方便安全的上下床方式。摘要本設(shè)計(jì)采用開發(fā)板作為主控,結(jié)合壓力傳感器紅外避障傳感器電機(jī)驅(qū)動(dòng)模塊實(shí)現(xiàn)了一個(gè)可以自動(dòng)升降自動(dòng)停止自動(dòng)調(diào)速的宿舍升降機(jī)模型系統(tǒng)。 (第一次寫博客,記錄下自己大一時(shí)做的一個(gè)課設(shè),如有不妥之處,還望多...
閱讀 3792·2023-01-11 11:02
閱讀 4299·2023-01-11 11:02
閱讀 3121·2023-01-11 11:02
閱讀 5231·2023-01-11 11:02
閱讀 4793·2023-01-11 11:02
閱讀 5568·2023-01-11 11:02
閱讀 5371·2023-01-11 11:02
閱讀 4070·2023-01-11 11:02