如何解决sg90舵机自动回转问题

我用arduino uno和mpu6050控制sg90舵机 ,使舵机随着mpu6050的转动而转动,代码范围设置的是0-90°,传感器转动时,舵机可以跟着转动,但是传感器一停下,舵机就自动回归原位。求解。




```#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h" 
/*舵机*/#include <Servo.h>
Servo myservo;  //创建一个舵机控制对象
MPU6050 accelgyro;
unsigned long now, 
lastTime = 0;float dt;                                          //微分时间 
int16_t ax, ay, az, gx, gy, gz;                   //加速度计和陀螺仪的原始数据
float aax=0, aay=0,aaz=0, agx=0, agy=0, agz=0;    //角度变量
long axo = 0, ayo = 0, azo = 0;                   //加速度计偏移量
long gxo = 0, gyo = 0, gzo = 0;                   //陀螺仪偏移量
 float pi = 3.1415926; float AcceRatio = 16384.0;                       //加速度计比例系数
float GyroRatio = 131.0;                          //陀螺仪比例系数 
uint8_t n_sample = 8;                            //加速度计滤波算法采样个数
float aaxs[8] = {0}, aays[8] = {0}, aazs[8] = {0};         //x,y轴采样队列
long aax_sum, aay_sum,aaz_sum;                       //x,y轴采样和 
float a_x[10]={0}, a_y[10]={0},a_z[10]={0} ,g_x[10]={0} ,g_y[10]={0},g_z[10]={0}; 
float Px=1, Rx, Kx, Sx, Vx, Qx;             //x轴卡尔曼变量float Py=1, Ry, Ky, Sy, Vy, Qy;             //y轴卡尔曼变量
float Pz=1, Rz, Kz, Sz, Vz, Qz;             //z轴卡尔曼变量int16_t value;                             //定义一个整形变量用于存放读取到的信号值
bool blinkState = false;
 void setup(){    
Wire.begin();    Serial.begin(115200);     
accelgyro.initialize();                 //初始化     unsigned short times = 200;             //采样次数    
for(int i=0;i<times;i++)   
 {        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值     
   axo += ax; ayo += ay; azo += az;          
    gxo += gx; gyo += gy; gzo += gz;        }      
  axo /= times; ayo /= times; azo /= times; //计算加速度计偏移
gxo /= times; gyo /= times; gzo /= times; //计算陀螺仪偏移
Serial.println("Initializing I2C devices...");      //显示变量名      
accelgyro.initialize();     
 Serial.println("Testing device connections...");    //显示通信连接名      
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");   //显示传感器是否成功连接  
myservo.attach(9);  // 该舵机由arduino第九脚控制} 
void loop(){   
 unsigned long now = millis();              //当前时间   
 dt = (now - lastTime) / 1000.0;             //微分时间   
 lastTime = now;                            //上一次采样时间     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);  //读取六轴原始数值     
float accx = ax / AcceRatio;                //x轴加速度    
float accy = ay / AcceRatio;                //y轴加速度   
 float accz = az / AcceRatio;                //z轴加速度     aax = atan(accy / accz) * (-180) / pi;    //y轴对于z轴的夹角   
 aay = atan(accx / accz) * 180 / pi;       //x轴对于z轴的夹角    
aaz = atan(accz / accy) * 180 / pi;       //z轴对于y轴的夹角     
aax_sum = 0;                               // 对于加速度计原始数据的滑动加权滤波算法    
aay_sum = 0;    aaz_sum = 0;      
for(int i=1;i<n_sample;i++) 
   {        
aaxs[i-1] = aaxs[i];       
 aax_sum += aaxs[i] * i;     
   aays[i-1] = aays[i];        
aay_sum += aays[i] * i;       
 aazs[i-1] = aazs[i];      
  aaz_sum += aazs[i] * i;        }     
   aaxs[n_sample-1] = aax;  
  aax_sum += aax * n_sample;    
aax = (aax_sum / (11*n_sample/2.0)) * 9 / 7.0;    //角度调幅至0-90°   
 aays[n_sample-1] = aay;                          //此处应用实验法取得合适的系数    
aay_sum += aay * n_sample;                        //本例系数为9/7    
aay = (aay_sum / (11*n_sample/2.0)) * 9 / 7.0;   
 aazs[n_sample-1] = aaz;     
aaz_sum += aaz * n_sample;    
aaz = (aaz_sum / (11*n_sample/2.0)) * 9 / 7.0;     
float gyrox = - (gx-gxo) / GyroRatio * dt;     //x轴角速度    
float gyroy = - (gy-gyo) / GyroRatio * dt;    //y轴角速度    
float gyroz = - (gz-gzo) / GyroRatio * dt;    //z轴角速度    
agx += gyrox;                                //x轴角速度积分   
 agy += gyroy;                             //y轴角速度积分   
 agz += gyroz;      
  /* kalman start */    Sx = 0; Rx = 0;    Sy = 0; Ry = 0;    Sz = 0; Rz = 0;        
for(int i=1;i<10;i++)  
  {                                     
     //测量值平均值运算     
   a_x[i-1] = a_x[i];                        //即加速度平均值        Sx += a_x[i];        a_y[i-1] = a_y[i];        Sy += a_y[i];        a_z[i-1] = a_z[i];        Sz += a_z[i];        }        a_x[9] = aax;    
Sx += aax;    Sx /= 10;                                  //x轴加速度平均值   
 a_y[9] = aay;    Sy += aay;    Sy /= 10;                                  //y轴加速度平均值   
 a_z[9] = aaz;     Sz += aaz;    Sz /= 10;     
for(int i=0;i<10;i++)    
{       
 Rx += sq(a_x[i] - Sx);        Ry += sq(a_y[i] - Sy);        Rz += sq(a_z[i] - Sz);        }        Rx = Rx / 9;                               //得到方差    Ry = Ry / 9;                           
 Rz = Rz / 9;      Px = Px + 0.0025;                           // 0.0025在下面有说明...    
Kx = Px / (Px + Rx);                       //计算卡尔曼增益    agx = agx + Kx * (aax - agx);              //陀螺仪角度与加速度计速度叠加    
Px = (1 - Kx) * Px;                        //更新p值     
Py = Py + 0.0025;    Ky = Py / (Py + Ry);    agy = agy + Ky * (aay - agy);     Py = (1 - Ky) * Py;      Pz = Pz + 0.0025;    Kz = Pz / (Pz + Rz);    agz = agz + Kz * (aaz - agz);     Pz = (1 - Kz) * Pz;      
Serial.print(agx);Serial.print(",");    
Serial.print(agy);Serial.print(",");    
Serial.print(agz);Serial.println();    
myservo.write(agx);        // 指定舵机转向的角度    
delay(15);             

- 

```