微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > Arduino自平衡小车的问题,恳请各位帮忙

Arduino自平衡小车的问题,恳请各位帮忙

时间:10-02 整理:3721RD 点击:

小弟才接触Arduino

最近想做一个Arduino自平衡小车

三轴角加速度传感器用ADXL335       陀螺仪用IDG300        电机采用Pololu的29:1减速电机( 用串口传输方式进行调速,范围0~127)

控制思路采用卡尔曼滤波+PID控制的方法

但是遇到两个问题

第一是卡尔曼滤波后发现计算所得的角度值有一定的滞后

其次是在调试PID参数Kp时发现小车在晃动的同时会不由自主的变快最后无法控制,不知这是否和卡尔曼滤波没有处理好有关

想请各位大侠帮忙,能否告知一二

以下是我的代码(PID参数还未设定):


#include <SoftwareSerial.h>

#include <math.h>

SoftwareSerial mySerial(5, 6);

const int xpin = A0;                  // x-axis of the accelerometer

const int ypin = A1;                  // y-axis

const int zpin = A2;                  // z-axis (only on 3-axis models)

const int x_gyro = A4;

int e, motor_speed, x_g;

long z_average, y_average;

float z_acc, angle_sum, y_acc, x_rate;

double Kp, Ki,Kd, angle_acc, actAngle0, actAngle;

int sensorValue[2]  = { 0, 0}; //y,z accelerameter

int sensorZero[2]   = { 336, 340}; //y,z accelerameter

int STD_LOOP_TIME = 9;

int lastLoopTime = STD_LOOP_TIME;

int lastLoopUsefulTime = STD_LOOP_TIME;

unsigned long loopStartTime = 0;

void setup()

{

  Serial.begin(9600);

/***************电机初始化******************/

  mySerial.begin(19200);

  mySerial.write(0xAA);

  mySerial.write(0x88);

  mySerial.write(127);

  mySerial.write(0xAA);

  mySerial.write(0x8E);

  mySerial.write(127);

/*********************************************/

  Kp = 0;

  Ki = 0;

  Kd = 0;

}

void loop()

{


  getangle_accelerameter();

  getangle_gyro();

  

  lastLoopUsefulTime = millis()-loopStartTime;

  if(lastLoopUsefulTime<STD_LOOP_TIME)         

  delay(STD_LOOP_TIME-lastLoopUsefulTime);

  lastLoopTime = millis() - loopStartTime;

  loopStartTime = millis();

  actAngle = kalmanCalculate(angle_acc, x_rate, lastLoopTime);


  /*******************PID算法**************************/

  e = actAngle - actAngle0;

  angle_sum += actAngle;

   actAngle0 = actAngle;

  if (angle_sum>50) angle_sum = 50;

  if (angle_sum<-50) angle_sum = -50;

  motor_speed = (Kp * actAngle) + (Ki * angle_sum) + (Kd * e);

/*****************************************************/

  

  if(motor_speed > 0)  //run forward

  {

    motor_speed = motor_speed;

    mySerial.write(0x8A);

    mySerial.write(motor_speed);

    mySerial.write(0x8C);

    mySerial.write(motor_speed);

  }

  if(motor_speed < 0)  //run backward

  {

    motor_speed = 0 - motor_speed;

    mySerial.write(0x88);

    mySerial.write(motor_speed);

    mySerial.write(0x8E);

    mySerial.write(motor_speed);

  }

  

}

void getangle_accelerameter()

{

  y_average = 0;

  z_average = 0;

  for(int i=0;i<15;i++)

  {

    for(int n=0;n<2;n++)

    sensorValue[n]=analogRead(n+1)-sensorZero[n];

    y_average = y_average + sensorValue[0];

    z_average = z_average + sensorValue[1];

  }

  y_acc = y_average / 15.0;

  z_acc = z_average / 15.0;

  angle_acc = atan(z_acc/y_acc) * 180 / 3.14 - 2;

}

void getangle_gyro()

{

  x_g = analogRead(4);

  x_rate = (x_g - 308) * 2.44;

}

/*************************卡尔曼滤波(从网上参考的)**************/

    float Q_angle  =  0.001;

    float Q_gyro   =  0.003;

    float R_angle  =  0.03;

    float x_angle = 0;

    float x_bias = 0;

    float P_00 = 0, P_01 = 0, P_10 = 0, P_11 = 0;

    float dt, y, S;

    float K_0, K_1;

  float kalmanCalculate(float newAngle, float newRate,int looptime)

  {

    dt = float(looptime)/1000;

    x_angle += dt * (newRate - x_bias);

    P_00 +=  - dt * (P_10 + P_01) + Q_angle * dt;

    P_01 +=  - dt * P_11;

    P_10 +=  - dt * P_11;

    P_11 +=  + Q_gyro * dt;

    y = newAngle - x_angle;

    S = P_00 + R_angle;

    K_0 = P_00 / S;

    K_1 = P_10 / S;

    x_angle +=  K_0 * y;

    x_bias  +=  K_1 * y;

    P_00 -= K_0 * P_00;

    P_01 -= K_0 * P_01;

    P_10 -= K_1 * P_00;

    P_11 -= K_1 * P_01;

    return x_angle;

  }


学习了!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top