久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
二輪平衡機器人控制器代碼
[打印本頁]
作者:
liuqq
時間:
2015-5-22 01:06
標題:
二輪平衡機器人控制器代碼
//MCU:Mega16;晶振:8MHz;
//PWM:4KHz;濾波器頻率:100Hz;系統頻率:100Hz;10ms;
//二輪平衡機器人項目
#include <iom16v.h>
#include <macros.h>
#include <math.h>
//#define checkbit(var,bit) (var&(0x01<<(bit))) /*定義查詢位函數*/
//#define setbit(var,bit) (var|=(0x01<<(bit))) /*定義置位函數*/
//#define clrbit(var,bit) (var&=(~(0x01<<(bit)))) /*定義清零位函數*/
//-------------------------------------------------------
//輸出端口初始化
void PORT_initial(void)
{
DDRA=0B00000000;
PINA=0X00;
PORTA=0X00;
DDRB=0B00000000;
PINB=0X00;
PORTB=0X00;
DDRC=0B00010000;
PINC=0X00;
PORTC=0X00;
DDRD=0B11110010;
PIND=0X00;
PORTD=0X00;
}
//-------------------------------------------------------
//定時器1初始化
void T1_initial(void)
{
TCCR1A|=(1<<COM1A1)|(1<<WGM10)|(1<<COM1B1); //T1:8位快速PWM模式、匹配時清0,TOP時置位
TCCR1B|=(1<<WGM12)|(1<<CS11); //PWM:8分頻:8M/8/256=4KHz;
}
//-------------------------------------------------------
//定時器2初始化
void T2_initial(void) //T2:計數至OCR2時產生中斷
{
OCR2=0X4E; //T2:計數20ms(0X9C)10ms(0X4E)時產生中斷;
TIMSK|=(1<<OCIE2);
TCCR2|=(1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20); //CTC模式,1024分頻
}
//-------------------------------------------------------
//外部中斷初始化
void INT_initial(void)
{
MCUCR|=(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10); //INT0、INT1上升沿有效
GICR|=(1<<INT0)|(1<<INT1); //外部中斷使能
}
//-------------------------------------------------------
//串口初始化;
void USART_initial( void )
{
UBRRH = 0X00;
UBRRL = 51; //f=8MHz;設置波特率:9600:51;19200:25;
UCSRB = (1<<RXEN)|(1<<TXEN); //接收器與發送器使能;
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); //設置幀格式: 8 個數據位, 1 個停止位;
UCSRB|=(1<<RXCIE); //USART接收中斷使能
}
//-------------------------------------------------------
//串口發送數據;
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE))); //等待發送緩沖器為空;
UDR = data; //將數據放入緩沖器,發送數據;
}
//-------------------------------------------------------
//串口接收數據中斷,確定數據輸出的狀態;
#pragma interrupt_handler USART_Receive_Int:12
static char USART_State;
void USART_Receive_Int(void)
{
USART_State=UDR;//USART_Receive();
}
//-------------------------------------------------------
//計算LH側輪速:INT0中斷;
//-------------------------------------------------------
static int speed_real_LH;
//-------------------------------------------------------
#pragma interrupt_handler SPEEDLHINT_fun:2
void SPEEDLHINT_fun(void)
{
if (0==(PINB&BIT(0)))
{
speed_real_LH-=1;
}
else
{
speed_real_LH+=1;
}
}
//-------------------------------------------------------
//計算RH側輪速,:INT1中斷;
//同時將輪速信號統一成前進方向了;
//-------------------------------------------------------
static int speed_real_RH;
//-------------------------------------------------------
#pragma interrupt_handler SPEEDRHINT_fun:3
void SPEEDRHINT_fun(void)
{
if (0==(PINB&BIT(1)))
{
speed_real_RH+=1;
}
else
{
speed_real_RH-=1;
}
}
//-------------------------------------------------------
//ADport采樣:10位,采樣基準電壓Aref
//-------------------------------------------------------
static int AD_data;
//-------------------------------------------------------
int ADport(unsigned char port)
{
ADMUX=port;
ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADPS1)|(1<<ADPS0); //采樣頻率為8分頻;
while(!(ADCSRA&(BIT(ADIF))));
AD_data=ADCL;
AD_data+=ADCH*256;
AD_data-=512;
return (AD_data);
}
//*
//-------------------------------------------------------
//Kalman濾波,8MHz的處理時間約1.8ms;
//-------------------------------------------------------
static float angle, angle_dot; //外部需要引用的變量
//-------------------------------------------------------
static const float Q_angle=0.001, Q_gyro=0.003, R_angle=0.5, dt=0.01;
//注意:dt的取值為kalman濾波器采樣時間;
static float P[2][2] = {
{ 1, 0 },
{ 0, 1 }
};
static float Pdot[4] ={0,0,0,0};
static const char C_0 = 1;
static float q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;
//-------------------------------------------------------
void Kalman_Filter(float angle_m,float gyro_m) //gyro_m:gyro_measure
{
angle+=(gyro_m-q_bias) * dt;
Pdot[0]=Q_angle - P[0][1] - P[1][0];
Pdot[1]=- P[1][1];
Pdot[2]=- P[1][1];
Pdot[3]=Q_gyro;
P[0][0] += Pdot[0] * dt;
P[0][1] += Pdot[1] * dt;
P[1][0] += Pdot[2] * dt;
P[1][1] += Pdot[3] * dt;
angle_err = angle_m - angle;
PCt_0 = C_0 * P[0][0];
PCt_1 = C_0 * P[1][0];
E = R_angle + C_0 * PCt_0;
K_0 = PCt_0 / E;
K_1 = PCt_1 / E;
t_0 = PCt_0;
t_1 = C_0 * P[0][1];
P[0][0] -= K_0 * t_0;
P[0][1] -= K_0 * t_1;
P[1][0] -= K_1 * t_0;
P[1][1] -= K_1 * t_1;
angle += K_0 * angle_err;
q_bias += K_1 * angle_err;
angle_dot = gyro_m-q_bias;
}
//*/
/*
//-------------------------------------------------------
//互補濾波
//-------------------------------------------------------
static float angle,angle_dot; //外部需要引用的變量
//-------------------------------------------------------
static float bias_cf;
static const float dt=0.01;
//-------------------------------------------------------
void complement_filter(float angle_m_cf,float gyro_m_cf)
{
bias_cf*=0.998; //陀螺儀零飄低通濾波;500次均值;
bias_cf+=gyro_m_cf*0.002;
angle_dot=gyro_m_cf-bias_cf;
angle=(angle+angle_dot*dt)*0.90+angle_m_cf*0.05;
//加速度低通濾波;20次均值;按100次每秒計算,低通5Hz;
}
*/
//-------------------------------------------------------
//AD采樣;
//以角度表示;
//加速度計:1.2V=1g=90°;滿量程:1.3V~3.7V;
//陀螺儀:0.5V~4.5V=-80°~+80°;滿量程5V=200°=256=200°;
//-------------------------------------------------------
static float gyro,acceler;
//-------------------------------------------------------
void AD_calculate(void)
{
acceler=ADport(2)+28; //角度校正
gyro=ADport(3);
acceler*=0.004069; //系數換算:2.5/(1.2*512); // 5/(1.2*1024);5為參考電壓5V;1.2V靈敏度對應加速度1g;1024為AD精度
acceler=asin(acceler); //反正弦求角度
gyro*=0.00341; //角速度系數:(3.14/180)* 100/512=0.01364;//(3.14/180)* (200*0.025)/1024*0.025既5/1024*0.025
//求得角速度 單位 角度/秒
Kalman_Filter(acceler,gyro); //卡爾曼濾波 帶入角度。角速度
//complement_filter(acceler,gyro);
}
//-------------------------------------------------------
//PWM輸出
//-------------------------------------------------------
void PWM_output (int PWM_LH,int PWM_RH)
{
if (PWM_LH<0)
{
PORTD|=BIT(6);
PWM_LH*=-1;
}
else
{
PORTD&=~BIT(6);
}
if (PWM_LH>252)
{
PWM_LH=252;
}
if (PWM_RH<0)
{
PORTD|=BIT(7);
PWM_RH*=-1;
}
else
{
PORTD&=~BIT(7);
}
if (PWM_RH>252)
{
PWM_RH=252;
}
OCR1AH=0;
OCR1AL=PWM_LH; //OC1A輸出;
OCR1BH=0;
OCR1BL=PWM_RH; //OC1B輸出;
}
//-------------------------------------------------------
//計算PWM輸出值
//車輛直徑:76mm; 12*64pulse/rev; 1m=3216pulses;
//-------------------------------------------------------
//static int speed_diff,speed_diff_all,speed_diff_adjust;
//static float K_speed_P,K_speed_I;
static float K_voltage,K_angle,K_angle_dot,K_position,K_position_dot;
static float K_angle_AD,K_angle_dot_AD,K_position_AD,K_position_dot_AD;
static float position,position_dot;
static float position_dot_filter;
static float PWM;
static int speed_output_LH,speed_output_RH;
static int Turn_Need,Speed_Need;
//-------------------------------------------------------
void PWM_calculate(void)
{
if ( 0==(~PINA&BIT(1)) ) //左轉
{
Turn_Need=-40;
}
else if ( 0==(~PINB&BIT(2)) ) //右轉
{
Turn_Need=40;
}
else //不轉
{
Turn_Need=0;
}
if ( 0==(~PINC&BIT(0)) ) //前進
{
Speed_Need=-2;
}
else if ( 0==(~PINC&BIT(1)) ) //后退
{
Speed_Need=2;
}
else //不動
{
Speed_Need=0;
}
K_angle_AD=ADport(4)*0.007;
K_angle_dot_AD=ADport(5)*0.007;
K_position_AD=ADport(6)*0.007;
K_position_dot_AD=ADport(7)*0.007;
position_dot=PWM*0.04;
position_dot_filter*=0.9; //車輪速度濾波
position_dot_filter+=position_dot*0.1;
position+=position_dot_filter;
//position+=position_dot;
position+=Speed_Need;
if (position<-768) //防止位置誤差過大導致的不穩定
{
position=-768;
}
else if (position>768)
{
position=768;
}
PWM = K_angle*angle *K_angle_AD + K_angle_dot*angle_dot *K_angle_dot_AD +
K_position*position *K_position_AD + K_position_dot*position_dot_filter *K_position_dot_AD;
speed_output_RH = PWM;// - Turn_Need;
speed_output_LH = - PWM;// - Turn_Need ;
/*
speed_diff=speed_real_RH-speed_real_LH; //左右輪速差PI控制;
speed_diff_all+=speed_diff;
speed_diff_adjust=(K_speed_P*speed_diff+K_speed_I*speed_diff_all)/2;
*/
PWM_output (speed_output_LH,speed_output_RH);
}
//-------------------------------------------------------
//定時器2中斷處理
//-------------------------------------------------------
static unsigned char temp;
//-------------------------------------------------------
#pragma interrupt_handler T2INT_fun:4
void T2INT_fun(void)
{
AD_calculate();
PWM_calculate();
if(temp>=4) //10ms即中斷;每秒計算:100/4=25次;
{
if (USART_State==0X30) //ASCII碼:0X30代表字符'0'
{
USART_Transmit(angle*57.3+128);
USART_Transmit(angle_dot*57.3+128);
USART_Transmit(128);
}
else if(USART_State==0X31) //ASCII碼:0X30代表字符'1'
{
USART_Transmit(speed_output_LH+128);
USART_Transmit(speed_output_RH+128);
USART_Transmit(128);
}
else if(USART_State==0X32) //ASCII碼:0X30代表字符'2'
{
USART_Transmit(speed_real_LH+128);
USART_Transmit(speed_real_RH+128);
USART_Transmit(128);
}
else if(USART_State==0X33) //ASCII碼:0X30代表字符'3'
{
USART_Transmit(K_angle+128);
USART_Transmit(K_angle_dot+128);
USART_Transmit(K_position_dot+128);
}
temp=0;
}
speed_real_LH=0;
speed_real_RH=0;
temp+=1;
}
//-------------------------------------------------------
int i,j;
//-------------------------------------------------------
void main(void)
{
PORT_initial();
T2_initial();
INT_initial();
USART_initial ();
SEI();
K_position=0.8 * 0.209; //換算系數:(256/10) * (2*pi/(64*12))=0.20944;//256/10:電壓換算至PWM,256對應10V;
K_angle=34 * 25.6; //換算系數:256/10 =25.6;
K_position_dot=1.09 * 20.9; //換算系數:(256/10) * (25*2*pi/(64*12))=20.944;
K_angle_dot=2.2 * 25.6; //換算系數:256/10 =25.6;
for (i=1;i<=500;i++) //延時啟動PWM,等待卡爾曼濾波器穩定
{
for (j=1;j<=300;j++);;
}
T1_initial();
while(1)
{
;
}
}
復制代碼
作者:
dely2009
時間:
2015-6-10 10:06
先收藏再說,謝謝分享
作者:
dely2009
時間:
2015-6-14 11:25
先收藏備用,謝謝分享
作者:
tzyjf
時間:
2017-4-13 13:11
好復雜,先備著。謝謝樓主
作者:
leapyy
時間:
2017-7-11 03:47
謝謝分享,很好的學習資料
作者:
meilidianzhi
時間:
2017-8-16 10:33
學習一下謝謝!!。。。。。。。。。。。。。。。。
作者:
wzl570
時間:
2022-3-23 23:12
感覺有點復雜啊,有點頭痛
作者:
量子工業
時間:
2023-9-7 11:42
有沒有防止電動車摩托車自行車這種,左右歪倒的東西,比如陀螺儀啥的;
網上貌似很多了,腳踢也不會傾倒
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
精品欧美乱码久久久久久
|
青青草原精品99久久精品66
|
欧美激情精品久久久久久
|
中文字幕一区二区三区不卡在线
|
91精品免费视频
|
麻豆国产精品777777在线
|
中文字幕乱码一区二区三区
|
亚洲九色
|
精品国产乱码一区二区三区
|
亚洲 中文 欧美 日韩 在线观看
|
超碰免费在线观看
|
欧美在线视频一区
|
欧美区日韩区
|
日韩影音
|
成人免费xxxxx在线视频
|
色伊人网
|
日韩中文字幕网
|
久久出精品
|
日韩视频在线播放
|
国产精品久久久久久久久久
|
日韩电影中文字幕
|
久久久久久久一区
|
岛国精品
|
国产精彩视频在线观看
|
中文字幕在线视频观看
|
国产美女福利在线观看
|
成人在线精品视频
|
久久大香
|
影音先锋中文字幕在线观看
|
国产成人久久精品一区二区三区
|
五月激情综合网
|
日韩欧美在线观看
|
国产999精品久久久久久
|
日韩免费av一区二区
|
日韩日b视频
|
欧美一二精品
|
亚洲精彩视频在线观看
|
99精品一区二区
|
色视频在线播放
|
国产精品成人品
|
亚洲字幕在线观看
|