pww999 发表于 2012-8-21 09:54:51

Arduino双轮平行车m2560+mpu6050+l298

本帖最后由 pww999 于 2012-8-21 22:16 编辑

85mm轮
http://player.youku.com/player.php/sid/XNDQxODE5MjI0/v.swf


基本是 zlstone 的简版 , 传感器换成mpu6050

参数乱套的,还在调整,没有摇控功能,(电机没有码盘,摇控只能左右转, 前后控的话一下就截根头,调小了又只能侧下头就不动了~,(这个需要慢慢拆腾)" ")

mpu6050因为有库文件,所以直接调用,代码也简单

视频地址:

Arduino平行车(增加资料与视频讲解)

代码:

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"

MPU6050 accelgyro;
//#include <LiquidCrystal.h>;
//LiquidCrystal lcd( 12, 11, 10, 9, 8,7);

#define Gry_offset -20   // 陀螺仪偏移量
//#define Gyr_Gain 0.04      // 满量程2000dps时灵敏度(dps/digital)
#define Gyr_Gain 65.5
#define pi 3.14159

int16_t ax, ay, az;
int16_t gx, gy, gz;

//boolean OK=false;//这个是误差达到一定程度后的系统关闭开关.
/********** 互补滤波器参数 *********/
//unsigned long preTime = 0; // 采样时间
//float f_angle = 0.0;       // 滤波处理后的角度值


/*********** PID控制器参数 *********/
//unsigned long lastTime;
float Output;   //;, Setpoint,Input;
//double errSum, lastErr;
float kp, ki, kd,kpp;
//int SampleTime = 0.1; //1 sec
//float Outputa = 0.0;
float angleA,omega;
//double Kp, Ki, Kd;
float P = {{ 1, 0 },{ 0, 1 }};
float Pdot ={ 0,0,0,0};
static const double Q_angle=0.01, Q_gyro=0.03, R_angle=0.5,dtt=0.005,C_0 = 1;
float q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;
float angle, angle_dot,aaxdot,aax;
float position_dot,position_dot_filter,positiono;
//double Speed_Need=0;

//float K_angle=2;
//float K_angle_dot=0.5;       //换算系数:256/10 =25.6;
//float K_position=0.1;                //换算系数:(256/10) * (2*pi/(64*12))=0.20944;//256/10:电压换算至PWM,256对应10V;      
//float K_position_dot=1;                //换算系数:(256/10) * (25*2*pi/(64*12))=20.944;

//--------------------------------------

int oommm;
int ooommm;
//int oooommmm;
//double OLH= 10,ORH = 10;

int TN1=22;
int TN2=23;
int TN3=24;
int TN4=25;
int ENA=2;
int ENB=3;

//-------------------------------------
void setup() {
Wire.begin();
//lcd.begin(16, 2);
//lcd.print("hello, world!");
//delay(1000);

accelgyro.initialize();
    delay(500);
pinMode(22,OUTPUT);         
    pinMode(23,OUTPUT);
      pinMode(24,OUTPUT);
      pinMode(25,OUTPUT);
            pinMode(2,OUTPUT);
      pinMode(3,OUTPUT);
      
delay(100);
//Serial.begin(9600);
}

void loop() {
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
//-----------------------------------------------------------------------------------------------------------------

angleA= atan2(ay , az) * 180 / pi-0.2;   // 根据加速度分量得到的角度(degree)
//omega=Gyr_Gain * (gx +Gry_offset); // 当前角速度(degree/s)
   omega=(gx +Gry_offset)/Gyr_Gain; // 当前角速度(degree/s)
if (abs(angleA)<30) {

//OK = true;
Kalman_Filter(angleA,omega);
PIDD();
PWMB();
//LCDD();
   }
    else {
      //OK=false;
analogWrite(ENA, 0); //PWM调速a==0-255
analogWrite(ENB, 0);
}
   delay(10);
}
//=---------------------------------------------------------------


void Kalman_Filter(double angle_m,double gyro_m)
{
angle+=(gyro_m-q_bias) * dtt;
Pdot=Q_angle - P - P;
Pdot=- P;
Pdot=- P;
Pdot=Q_gyro;
P += Pdot * dtt;
P += Pdot * dtt;
P += Pdot * dtt;
P += Pdot * dtt;
angle_err = angle_m - angle;
PCt_0 = C_0 * P;
PCt_1 = C_0 * P;
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;
P -= K_0 * t_0;
P -= K_0 * t_1;
P -= K_1 * t_0;
P -= K_1 * t_1;
angle+= K_0 * angle_err;
q_bias += K_1 * angle_err;
angle_dot = gyro_m-q_bias;//也许应该用last_angle-angle
}

//-----------------------
voidPIDD(){
      kp=analogRead(8)*0.01;
      ki=analogRead(9)*0.007;
      kd=analogRead(10)*0.007;
      kpp=analogRead(11)*0.007;
aaxdot=0.5*aaxdot+0.5*angle_dot;
aax=0.5*aax+0.5*angle;
      position_dot=Output*0.04;                //利用PWM值代替轮速传感器的信号
      position_dot_filter*=0.9;                //车轮速度滤波
      position_dot_filter+=position_dot*0.1;      
      positiono+=position_dot_filter;      
      //positiono+=Speed_Need;         
positiono=constrain(positiono,-500,500);
Output= 2*aax *kp + 0.5*aaxdot *ki +0.02*positiono *kd + 1*position_dot_filter *kpp;
    //Output= K_angle*angle *kp + K_angle_dot*angle_dot *ki +K_position*positiono *kd + K_position_dot*position_dot_filter *kpp;
}
//-------------电机正反转 PWM输出-----------
void PWMB(){
if(Output<0)
{

    digitalWrite(TN1, HIGH);
    digitalWrite(TN2, LOW);
   digitalWrite(TN3, HIGH);
    digitalWrite(TN4, LOW);

}
if(Output>0)
{

    digitalWrite(TN1, LOW);
    digitalWrite(TN2, HIGH);
   digitalWrite(TN3, LOW);
    digitalWrite(TN4, HIGH);
}
    oommm=min(220,abs(Output));
    analogWrite(ENA, oommm+35); //PWM调速a==0-255
    analogWrite(ENB, oommm+30);
}

cooleaf 发表于 2012-8-21 16:22:40

鼓励一下楼主,希望有新消息!!

371278638 发表于 2012-12-6 09:29:23

{:lol:}楼主旁边的那个电机用的带劲么我也买了那个电机 模型还没组建完不知道效果如何!

rantingting 发表于 2012-12-6 10:01:08

还是德国那电机力矩猛,就是有点贵{:sad:}

beyondsunjun 发表于 2013-3-20 07:49:47

楼主滤波有问题吗?

lijungei 发表于 2013-5-17 16:55:50

好贴呀绝对顶
页: [1]
查看完整版本: Arduino双轮平行车m2560+mpu6050+l298