Beruflich Dokumente
Kultur Dokumente
h>
#include<I2Cdev.h>
#include<MPU6050.h>
#ifndef _Kalman_h_
#define _Kalman_h_
float speeds;
const uint8_t IMUAddress = 0x68; // AD0 is logic low on the PCB
const uint16_t I2C_TIMEOUT = 1000; // Used to check for errors in I2C communication
void setAngle(float angle); // Used to set angle, this should be set as the
starting angle
float getRate(); // Return the unbiased rate
float getQangle();
float getQbias();
float getRmeasure();
private:
/* Kalman filter variables */
float Q_angle; // Process noise variance for the accelerometer
float Q_bias; // Process noise variance for the gyro bias
float R_measure; // Measurement noise variance - this is actually the variance
of the measurement noise
float angle; // The angle calculated by the Kalman filter - part of the 2x1
state vector
float bias; // The gyro bias calculated by the Kalman filter - part of the 2x1
state vector
float rate; // Unbiased rate calculated from the rate and the calculated bias -
you have to call getAngle to update the rate
#endif
MPU6050 mpu;
int IN1 = 4;
int IN2 = 8;
int IN3 = 5;
int IN4 = 7;
#define enA 3
#define enB 6
int16_t ay, az;
int16_t gx;
float a_goc;
float g_goc;
float KalAngleX;
float er, per = 0, ier =0;
unsigned long timer;
float goc;
uint8_t i2cData[14];
const float Kp = 30;
const float Ki = 1;
const float Kd = 8;
#define runEvery(t) for (static typeof(t) _lasttime;(typeof(t))((typeof(t))millis()
- _lasttime) > (t);_lasttime += (t))
void canbang(int left, int right)
{
if(left>=0)
{
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(enA,left);
}
else{
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(enA, 255+left);
}
if(right>=0)
{
digitalWrite(IN4, LOW);
digitalWrite(IN3, HIGH);
analogWrite(enB, right);
}
else{
digitalWrite(IN4,HIGH);
digitalWrite(IN3, LOW);
analogWrite(enB, 255+right);
}
}
void stop()
{
speeds = map(speeds,0,-150,0,150);
analogWrite(enA, speeds);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(enB, speeds);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
Wire.begin();
i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro
filtering, 8 KHz sampling
i2cData[2] = 0x00;
i2cData[3] = 0x00;
while(i2cWrite(0x19,i2cData,4,false));
while(i2cWrite(0x6B,0x01,true));
while(i2cRead(0x75,i2cData,1));
if(i2cData[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("Error reading sensor"));
while(1);
}
delay(100);
//Kalman====================================================
while(i2cRead(0x3B,i2cData,6));
ay = ((i2cData[2] << 8) | i2cData[3]);
az = ((i2cData[4] << 8) | i2cData[5]);
a_goc = (atan2(ay,az)+PI)*RAD_TO_DEG;
Kalman().setAngle(a_goc);
g_goc = a_goc;
timer = micros();
}
void loop()
{
Serial.println(ay);
Serial.println(az);
Serial.println(a_goc);
Serial.println(goc);
runEvery(25)
{
kal();
if(goc<=179&&goc>=178.5)
{
stop();
}
else{
if(goc<230&&goc>130)
{
pid();
canbang(speeds,speeds);
}
else{
stop();
}
}
}
}
void pid()
{
er = 180 - goc;
ier += er ;
speeds=constrain((Kd*er + Ki*er*0.005 + Kd*(er- per)/0.005), -255, 255);
per = er;
}
void kal()
{
while(i2cRead(0x3B,i2cData,14));
a_goc = (atan2(ay,az)+PI)*RAD_TO_DEG;
float gyroXrate = (double)gx/131.0;
goc = Kalman().getAngle(a_goc, gyroXrate, (float)(micros()-timer)/1000000);
timer = micros();
}