搜索
bottom↓
回复: 5

Arduino双轮平行车m2560+mpu6050+l298

[复制链接]

出0入0汤圆

发表于 2012-8-21 09:54:51 | 显示全部楼层 |阅读模式
本帖最后由 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[2][2] = {{ 1, 0 },{ 0, 1 }};
float Pdot[4] ={ 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[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] * dtt;
P[0][1] += Pdot[1] * dtt;
P[1][0] += Pdot[2] * dtt;
P[1][1] += Pdot[3] * dtt;
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;//也许应该用last_angle-angle
}

//-----------------------
void  PIDD(){
        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);
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2012-8-21 16:22:40 | 显示全部楼层
鼓励一下楼主,希望有新消息!!

出0入0汤圆

发表于 2012-12-6 09:29:23 | 显示全部楼层
楼主旁边的那个电机用的带劲么我也买了那个电机 模型还没组建完不知道效果如何!

出0入0汤圆

发表于 2012-12-6 10:01:08 | 显示全部楼层
还是德国那电机力矩猛,就是有点贵

出0入0汤圆

发表于 2013-3-20 07:49:47 | 显示全部楼层
楼主滤波有问题吗?

出0入0汤圆

发表于 2013-5-17 16:55:50 | 显示全部楼层
好贴呀  绝对顶
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-28 10:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表