搜索
bottom↓
楼主: feng_matrix

4轴姿态控制算法讨论贴

[复制链接]

出0入0汤圆

发表于 2008-7-1 11:33:37 | 显示全部楼层
角速度数据 用离散卡尔曼滤波器 就可以计算出角度(而且不会有误差积累)?
Kalman(Gyro, AccelXY, AccelZ);
看你这个函数, 好像是综合了角速度和加速度。  能更仔细的讲解一下吗?

出0入0汤圆

发表于 2008-7-1 14:26:44 | 显示全部楼层
zhcool_521
                        抱歉, 我书写汉语的能力非常有限.

在UAV最常用的卡尔曼滤波器计算法是综合了传感器输出数据与预测数据混算.

仔细的讲解.
http://tom.pycke.be/mav/71/kalman-filtering-of-imu-data

出0入0汤圆

发表于 2008-7-1 17:30:24 | 显示全部楼层
kb6mcc    有 msn或者qq 吗?

出0入0汤圆

发表于 2008-7-2 01:36:01 | 显示全部楼层
my msn ID = kb6mcc@hotmail.com

出0入0汤圆

发表于 2008-7-9 11:45:13 | 显示全部楼层
kb6mcc   加你 好长时间了, 一直 没有碰到你上线 , 你一般什么时间 在线?

出0入0汤圆

发表于 2008-7-10 04:34:47 | 显示全部楼层
Hi zhcool,
         sorry, just too busy at works for pass few weeks..I'm normally online around 9:00am Pacific Time or you can email me if I'm not around. kb6mcc@yahoo.com

出0入0汤圆

发表于 2008-7-11 23:57:15 | 显示全部楼层
Hi zhcool, got your messages and I hopes the attached information is useful. Again, feelfree email me if you have any question.


点击此处下载 ourdev_345463.pdf(文件大小:454K) (原文件名:kalman_intro_chinese_V1.2.pdf)

出0入0汤圆

发表于 2008-7-12 10:11:27 | 显示全部楼层
Kalman filter   基本能看懂,
每次循环实际上需要 传递下来的参数是  上一次的高斯  和 上一次的 优估计值,还有当前测量值;并不需要传递 KG ,;        我觉得:
       
        参数传递:
        LastGaussCovariance = DATA_NextGaussCovariance;
       
        LastBestEstimate = DATA_BestEstimate;
       
        5个函数公式:
        Estimate = LastBestEstimate + Kalman_Wk;
       
        GaussCovariance = LastGaussCovariance + Kalman_Q;
       
        Kalman_KG = sqrt ( GaussCovariance / (GaussCovariance - Kalman_R) );
       
        BestEstimate = Estimate + Kalman_KG * (Measure - Estimate);
       
        NextGaussCovariance = (1 - Kalman_KG) * GaussCovariance;

我现在是概念的东西还是不太明白,比如:
  1.Kalman  得输入参数 是什么?是加速度还是角速度?
  2.还牵扯到一个 “四元数法” ,它得输入参数是什么?

总之,你能不能描述一下整个  姿态角  求解的流程?  我通过角速度传感器能得到角速度值,通过加速度传感器得到加速度值,通过这些参数如何得到所需要的 姿态角度?

出0入0汤圆

发表于 2008-7-13 02:58:16 | 显示全部楼层
zhcool,
        I thought you should come up the ideal howto by now so I can learn from you after I'm attached so much info on this forum:-)

Just want to let you know I'm just a guy like everyone in this forum who loves to build thing especially
quadcopter and/or UAV. So, I'm “no” expert here..:-))  All information from me may cause your QC/UAV crash without warning...oh your windows pc too.:-))

Kalman Filter, obviously just a series of algorithm that capable products a clean signal that we wants.

Your questions.

1.Kalman 得输入参数是什么?是加速度还是角速度?
This depended on what project working on? For QC, the minimum is 2axis gyro (roll and pitch) and 3axis Accel.

2 .还牵扯到一个“四元数法”,它得输入参数是什么?
Not 100% sure what is“ 四元数法" but i think is “matrix”  “feng_matrix” should knowns about this stuff.:-)

3你能不能描述一下整个姿态角求解的流程?
OK, I try but don't laugh....

Read all data form the sensors, Put all data into the matrix
and let the KMF do it tricks (predication, update and invariants)

Below is some codes I have for the adxl330 Idg300 IMU.  


#define SAMPLE_COUNT

// Sample data gathered directly from IMU every 1/20th of a second using 10-bit ADC // on an ATmega168.  The first
// column is the rate from the gyro (degrees/sec) and the second column is the
// pitch attitude from horizontal in degrees.
float sample_data[SAMPLE_COUNT][2] =
{
    {0.016088, 1.668337},
    {0.016088, 1.101706},
    {0.016088, 1.652305},
    {-0.273488, -66.801407},
    {-0.176963, -70.497551},
    {-0.370013, -73.094841},
    {-0.434363, -75.203239},
    {-0.241313, -70.346184},
    {-0.048263, -65.979752},
    {0.209137, -69.918022},
    {-0.016088, -2.223961},
    {0.016088, -2.202598},
    {0.016088, -2.202598}
};


static void matrix_multiply(float* A, float* B, int m, int p, int n, float* C)
// Matrix Multiplication Routine
{
    // A = input matrix (m x p)
    // B = input matrix (p x n)
    // m = number of rows in A
    // p = number of columns in A = number of rows in B
    // n = number of columns in B
    // C = output matrix = A*B (m x n)
    int i, j, k;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
        {
          C[n*i+j]=0;
          for (k=0;k<p;k++)
            C[n*i+j]= C[n*i+j]+A[p*i+k]*B[n*k+j];
        }
}

static void matrix_addition(float* A, float* B, int m, int n, float* C)
// Matrix Addition Routine
{
    // A = input matrix (m x n)
    // B = input matrix (m x n)
    // m = number of rows in A = number of rows in B
    // n = number of columns in A = number of columns in B
    // C = output matrix = A+B (m x n)
    int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[n*i+j]=A[n*i+j]+B[n*i+j];
}

static void matrix_subtraction(float* A, float* B, int m, int n, float* C)
// Matrix Subtraction Routine
{
    // A = input matrix (m x n)
    // B = input matrix (m x n)
    // m = number of rows in A = number of rows in B
    // n = number of columns in A = number of columns in B
    // C = output matrix = A-B (m x n)
    int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[n*i+j]=A[n*i+j]-B[n*i+j];
}

static void matrix_transpose(float* A, int m, int n, float* C)
// Matrix Transpose Routine
{
    // A = input matrix (m x n)
    // m = number of rows in A
    // n = number of columns in A
    // C = output matrix = the transpose of A (n x m)
    int i, j;
    for (i=0;i<m;i++)
        for(j=0;j<n;j++)
            C[m*j+i]=A[n*i+j];
}


static int matrix_inversion(float* A, int n, float* AInverse)
// Matrix Inversion Routine
{
    // A = input matrix (n x n)
    // n = dimension of A
    // AInverse = inverted matrix (n x n)
    // This function inverts a matrix based on the Gauss Jordan method.
    // The function returns 1 on success, 0 on failure.
    int i, j, iPass, imx, icol, irow;
    float det, temp, pivot, factor;
    float* ac = (float*)calloc(n*n, sizeof(float));
    det = 1;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            AInverse[n*i+j] = 0;
            ac[n*i+j] = A[n*i+j];
        }
        AInverse[n*i+i] = 1;
    }

    // The current pivot row is iPass.
    // For each pass, first find the maximum element in the pivot column.
    for (iPass = 0; iPass < n; iPass++)
    {
        imx = iPass;
        for (irow = iPass; irow < n; irow++)
        {
            if (fabs(A[n*irow+iPass]) > fabs(A[n*imx+iPass])) imx = irow;
        }

        // Interchange the elements of row iPass and row imx in both A and AInverse.
        if (imx != iPass)
        {
            for (icol = 0; icol < n; icol++)
            {
                temp = AInverse[n*iPass+icol];
                AInverse[n*iPass+icol] = AInverse[n*imx+icol];
                AInverse[n*imx+icol] = temp;
                if (icol >= iPass)
                {
                    temp = A[n*iPass+icol];
                    A[n*iPass+icol] = A[n*imx+icol];
                    A[n*imx+icol] = temp;
                }
            }
        }

        // The current pivot is now A[iPass][iPass].
        // The determinant is the product of the pivot elements.
        pivot = A[n*iPass+iPass];
        det = det * pivot;
        if (det == 0)
        {
            free(ac);
            return 0;
        }

        for (icol = 0; icol < n; icol++)
        {
            // Normalize the pivot row by dividing by the pivot element.
            AInverse[n*iPass+icol] = AInverse[n*iPass+icol] / pivot;
            if (icol >= iPass) A[n*iPass+icol] = A[n*iPass+icol] / pivot;
        }

        for (irow = 0; irow < n; irow++)
        {
            // Add a multiple of the pivot row to each row.  The multiple factor
            // is chosen so that the element of A on the pivot column is 0.
            if (irow != iPass) factor = A[n*irow+iPass];
            for (icol = 0; icol < n; icol++)
            {
                if (irow != iPass)
                {
                    AInverse[n*irow+icol] -= factor * AInverse[n*iPass+icol];
                    A[n*irow+icol] -= factor * A[n*iPass+icol];
                }
            }
        }
    }

    free(ac);
    return 1;
}

static void matrix_print(float* A, int m, int n)
// Matrix print.
{
    // A = input matrix (m x n)
    // m = number of rows in A
    // n = number of columns in A
    int i, j;
    for (i=0;i<m;i++)
    {
        printf("| ");
        for(j=0;j<n;j++)
        {
            printf("%7.3f ", A[n*i+j]);
        }
        printf("|\n");
    }
}


// n states
// m inputs
// r outputs
#define n 2
#define m 1
#define r 1

float kalman_update(float gyroscope_rate, float accelerometer_angle)
{
    // A is an n by n matrix
    // B is an n by m matrix
    // C is an r by n matrix
    // Sz is an r by r matrix
    // Sw is an n by n matrix
    // xhat is an n by 1 vector
    // P is an n by n matrix
    // y is an r by 1 vector
    // u is an m by 1 vector

    // Constants.
    static float A[n][n] = {{1.0, -0.019968}, {0.0, 1.0}};
    static float B[n][m] = {{0.019968}, {0.0}};
    static float C[r][n] = {{1.0, 0.0}};
    static float Sz[r][r] = {{17.2}};
    static float Sw[n][n] = {{0.005, 0.005}, {0.005, 0.005}};

    // Persistant states.
    static float xhat[n][1] = {{0.0}, {0.0}};
    static float P[n][n] = {{0.005, 0.005}, {0.005, 0.005}};

    // Inputs.
    float u[m][m];              // Gyroscope rate.
    float y[m][m];              // Accelerometer angle.

    // Temp values.
    float AP[n][n];             // This is the matrix A*P
    float CT[n][r];             // This is the matrix C'
    float APCT[n][r];           // This is the matrix A*P*C'
    float CP[r][n];             // This is the matrix C*P
    float CPCT[r][r];           // This is the matrix C*P*C'
    float CPCTSz[r][r];         // This is the matrix C*P*C'+Sz
    float CPCTSzInv[r][r];      // This is the matrix inv(C*P*C'+Sz)
    float K[n][r];              // This is the Kalman gain.
    float Cxhat[r][1];          // This is the vector C*xhat
    float yCxhat[r][1];         // This is the vector y-C*xhat
    float KyCxhat[n][1];        // This is the vector K*(y-C*xhat)
    float Axhat[n][1];          // This is the vector A*xhat
    float Bu[n][1];             // This is the vector B*u
    float AxhatBu[n][1];        // This is the vector A*xhat+B*u
    float AT[n][n];             // This is the matrix A'
    float APAT[n][n];           // This is the matrix A*P*A'
    float APATSw[n][n];         // This is the matrix A*P*A'+Sw
    float KC[n][n];             // This is the matrix K*C
    float KCP[n][n];            // This is the matrix K*C*P
    float KCPAT[n][n];          // This is the matrix K*C*P*A'

    // Fill in inputs.
    u[0][0] = gyroscope_rate;
    y[0][0] = accelerometer_angle;

#if 0
    // Print various matrices.
    printf("u =\n");
    matrix_print((float*) u, m, m);
    printf("y =\n");
    matrix_print((float*) y, m, m);
    printf("A =\n");
    matrix_print((float*) A, n, n);
    printf("B =\n");
    matrix_print((float*) B, n, m);
    printf("State =\n");
    matrix_print((float*) xhat, n, 1);
#endif

    // Update the state estimate by extrapolating estimate with gyroscope input.
    // xhat_est = A * xhat + B * u
    matrix_multiply((float*) A, (float*) xhat, n, n, 1, (float*) Axhat);
    matrix_multiply((float*) B, (float*) u, n, r, 1, (float*) Bu);
    matrix_addition((float*) Axhat, (float*) Bu, n, 1, (float*) AxhatBu);

#if 0
    printf("State Estimate =\n");
    matrix_print((float*) AxhatBu, n, 1);
#endif

    // Compute the innovation.
    // Inn = y - c * xhat;
    matrix_multiply((float*) C, (float*) xhat, r, n, 1, (float*) Cxhat);
    matrix_subtraction((float*) y, (float*) Cxhat, r, 1, (float*) yCxhat);

#if 0
    printf("Innovation =\n");
    matrix_print((float*) yCxhat, r, 1);
#endif

    // Compute the covariance of the innovation.
    // s = C * P * C' + Sz
    matrix_transpose((float*) C, r, n, (float*) CT);
    matrix_multiply((float*) C, (float*) P, r, n, n, (float*) CP);
    matrix_multiply((float*) CP, (float*) CT, r, n, r, (float*) CPCT);
    matrix_addition((float*) CPCT, (float*) Sz, r, r, (float*) CPCTSz);

    // Compute the kalman gain matrix.
    // K = A * P * C' * inv(s)
    matrix_multiply((float*) A, (float*) P, n, n, n, (float*) AP);
    matrix_multiply((float*) AP, (float*) CT, n, n, r, (float*) APCT);
    matrix_inversion((float*) CPCTSz, r, (float*) CPCTSzInv);
    matrix_multiply((float*) APCT, (float*) CPCTSzInv, n, r, r, (float*) K);

    // Update the state estimate.
    // xhat = xhat_est + K * Inn;
    matrix_multiply((float*) K, (float*) yCxhat, n, r, 1, (float*) KyCxhat);
    matrix_addition((float*) AxhatBu, (float*) KyCxhat, n, 1, (float*) xhat);

    // Compute the new covariance of the estimation error.
    // P = A * P * A' - K * C * P * A' + Sw
    matrix_transpose((float*) A, n, n, (float*) AT);
    matrix_multiply((float*) AP, (float*) AT, n, n, n, (float*) APAT);
    matrix_addition((float*) APAT, (float*) Sw, n, n, (float*) APATSw);
    matrix_multiply((float*) K, (float*) C, n, r, n, (float*) KC);
    matrix_multiply((float*) KC, (float*) P, n, n, n, (float*) KCP);
    matrix_multiply((float*) KCP, (float*) AT, n, n, n, (float*) KCPAT);
    matrix_subtraction((float*) APATSw, (float*) KCPAT, n, n, (float*) P);

    // Return the estimate.
    return xhat[0][0];
}

int main(int argc, char **argv)
{
    int i;
    float gyro_input;
    float accel_input;
    float kalman_output;

    for (i = 0; i < SAMPLE_COUNT; ++i)
    {
        // Get the gyro and accelerometer input.
        gyro_input = sample_data[0];
        accel_input = sample_data[1];

        // Update the Kalman filter and get the output.
        kalman_output = kalman_update(gyro_input, accel_input);

        // Print out input data and the kalman output.
        printf("%d gyro=%7.3f deg/sec  accel=%7.3f degrees  kalman_output=%5.1f degrees\n", i, gyro_input, accel_input, kalman_output);
    }

    return 0;
}



Get the headache yet?

出0入0汤圆

发表于 2008-7-14 00:49:13 | 显示全部楼层
to 【110楼】 kb6mcc  

Hey dude, one thing I can assure you is that the "Quaternion algorithm" does exist, and it is called “四元数法” in Chinese. Our friend zhcool here might be in need of a book like this:


INS (原文件名:Cover.JPG)

I got it from the book store at Xidan, Beijing. He can get it from Taobao or in whatever way necessary.

The Quaternion algorithm is actually pretty deep for me, coz I've never been into any algorithm before. Yet since I've got this book, I'm able to take some pics of the chapter regarding this algorithm for reference:


封面 (原文件名:Cover.JPG)


封底 (原文件名:Back.JPG)


1 (原文件名:ALGO-1.JPG)


2 (原文件名:ALGO-2.JPG)


3 (原文件名:ALGO-3.JPG)


4 (原文件名:ALGO-4.JPG)


5 (原文件名:ALGO-5.JPG)


6 (原文件名:ALGO-6.JPG)


7 (原文件名:ALGO-7.JPG)


8 (原文件名:ALGO-8.JPG)


9 (原文件名:ALGO-9.JPG)


10 (原文件名:ALGO-10.JPG)


11 (原文件名:ALGO-11.JPG)


12 (原文件名:ALGO-12.JPG)


13 (原文件名:ALGO-13.JPG)


14 (原文件名:ALGO-14.JPG)


15 (原文件名:ALGO-15.JPG)


16 (原文件名:ALGO-16.JPG)


17 (原文件名:ALGO-17.JPG)


18 (原文件名:ALGO-18.JPG)



BTW, when it comes to algorithm implementation, what software do you use to validate the formulas through simulation? MATLAB?

出0入0汤圆

发表于 2008-7-14 02:59:47 | 显示全部楼层
Hi Alex,
                Hay, I learns something new today about "Quaternion algorithm" =" 四元数法" .:-)) thanks
Matlab, matlib is most popular used by many others for simulation. However, majority of the aerospace or aviation firm
here are using their in-house developed simulator.
One company that I know they use 60 linux boxes running their 3d simulator.


Sounds like zhcool needs a PhD helping hand here...all these equation well over my head..sorry zhcool :-((

Attached is the web site I'm always handout there years ago but they closed the door for business reason.
Anyway, it still have some good information you can take a look about "matrix" and quaternion matrix" stuffs
         
http://www.flipcode.com/documents/matrfaq.html#Q47

出0入0汤圆

发表于 2008-7-14 10:28:46 | 显示全部楼层
这书我有,好象还不错.

出0入0汤圆

发表于 2008-7-14 10:58:58 | 显示全部楼层
to 【113楼】 xj_1232005

呃,有书还问啊……

出0入0汤圆

发表于 2008-7-14 11:38:13 | 显示全部楼层
thanks kb6mcc, 谢谢Alex_rcpilot,

研究一下kb6mcc的代码再向你请教。

出0入0汤圆

发表于 2008-7-14 16:01:52 | 显示全部楼层
//50mS采样得到的数据;包括 角速度和角度(还是加速度值?没看懂。)
float sample_data[SAMPLE_COUNT][2];

//矩阵乘法, A, B,是相乘的矩阵,C是结果矩阵;
//第一个矩阵为 m行,p列,第二个矩阵为,p行,n列。
static void matrix_multiply(float* A, float* B, int m, int p, int n, float* C)

//矩阵加法,A, B,是相加的矩阵,C是结果矩阵;
//矩阵均为m行,n列
static void matrix_addition(float* A, float* B, int m, int n, float* C)

//矩阵减法,A, B,是相减的矩阵,C是结果矩阵;
//矩阵均为m行,n列
static void matrix_subtraction(float* A, float* B, int m, int n, float* C)

//矩阵转置,A为转置前矩阵,c为结果矩阵;
//矩阵均为m行,n列
static void matrix_transpose(float* A, int m, int n, float* C)

//矩阵倒置,A为倒置前矩阵,AInverse为结果矩阵;
//矩阵均为n行,n列
static int matrix_inversion(float* A, int n, float* AInverse)

//矩阵输出,A为要输出的矩阵;为m行,n列
static void matrix_print(float* A, int m, int n)

//根据各类参数,实现卡尔曼滤波公式,返回计算所得的最佳估计值xhat[0][0]

//xhat_est上一状态预测的结果,xhat上一状态最优的结果,u  现在状态的控制量

float kalman_update(float gyroscope_rate, float accelerometer_angle)

xhat_est = A * xhat + B * u
Inn = y - c * xhat;
s = C * P * C' + Sz;  
K = A * P * C' * inv(s);
xhat = xhat_est + K * Inn;
P = A * P * A' - K * C * P * A' + Sw;

return xhat[0][0];


//主函数的递推过程,将两个采样信号分别作为kalman_update函数的输入参数,
//得到每一步计算出来的最佳估计值
int main(int argc, char **argv)

出0入0汤圆

发表于 2008-7-14 16:12:14 | 显示全部楼层
kb6mcc  上述函数 float kalman_update(float gyroscope_rate, float accelerometer_angle)  中有几点没看懂:

1. gyroscope_rate  是角速度值?  accelerometer_angle 是加速度值还是通过3轴角速度计算得到的角度?

2.函数返回值  return xhat[0][0]  是角度?

3.  // Update the state estimate by extrapolating estimate with gyroscope input.
    // xhat_est = A * xhat + B * u   
    matrix_multiply((float*) A, (float*) xhat, n, n, 1, (float*) Axhat);
    matrix_multiply((float*) B, (float*) u, n, r, 1, (float*) Bu);
    matrix_addition((float*) Axhat, (float*) Bu, n, 1, (float*) AxhatBu);

    B  的值为[0.019968,0]  ,那么 B * u  是否为 角度?
4.  如果 B * u 是角度,那么 accelerometer_angle  和  return xhat[0][0]   也为角度。

出0入0汤圆

发表于 2008-7-22 00:06:41 | 显示全部楼层
Hi guys,
        Can’t answer your questions sooner due to offsite training last week.
Just to make sure you aware of all these codes are conceptual only and more then a year old.


yyroscope_rate 是角速度值  accelerometer_angle 是通过3轴角速度计算得到的角度

gyroscope_rate and accelerometer_angle data is processed and pulled from the STK500 with the following methods
http://tom.pycke.be/mav/70/gyroscope-to-roll-pitch-and-yaw


accelerometer_angle
http://tom.pycke.be/mav/69/accelerometer-to-attitude

(原文件名:accl.png)

example codes for the AVR. I don't have the completed codes any more. I can dig around on the net if you guys need more on this.   


    //   Initialize the pitch and roll estimate.
    roll_est = atan2(accel_y, accel_z);
    pitch_est = atan2(accel_x, accel_z);

    // Loop forever.
    for (;;)
    {
        // Get the gyro values.
        if (adc_is_ready())
        {
            // Get the x and y gyro values.
            gyro_x = (float) adc_get_gyro_x();
            gyro_y = (float) adc_get_gyro_y();

            // Get the x, y and z accelerometer values.
            accel_x = (float) adc_get_accel_x();
            accel_y = (float) adc_get_accel_y();
            accel_z = (float) adc_get_accel_z();

            // Reset the ready flag.
            adc_reset_ready();

            // Zero adjust the gyro values.  
            gyro_x -= 470.5;
            gyro_y -= 440.5;

            // Zero adjust the accelerometer values.  .
            accel_x -= 506.0;
            accel_y -= 506.0;
            accel_z -= 506.0;

            // Determine the pitch and roll in radians.  X and Z acceleration determines the
            // pitch and Y and Z acceleration determines roll.  Note the accelerometer vectors
            // that are perpendicular to the rotation of the axis are used.  We can compute the
            // angle for the full 360 degree rotation with no linearization errors by using the
            // arctangent of the two accelerometer readings.  The accelerometer values do not
            // need to be scaled into actual units, but must be zeroed and have the same scale.
            // Note that we manipulate the sign of the acceleration so the sign of the accelerometer
            // derived angles match the gyro rates.
            roll = atan2(accel_y, accel_z);
            pitch = atan2(-accel_x, accel_z);

            // Determine gyro angular rate from raw analog values.
            // Each ADC unit: 3300 / 1024 = 3.222656 mV
            // Gyro measures rate: 2.0 mV/degrees/second
            // Gyro measures rate: 114.591559 mV/radians/second
            // Each ADC unit equals: 3.222656 / 2.0 = 1.611328 degrees/sec
            // Each ADC unit equals: 3.222656 / 114.591559 = 0.0281230 radians/sec
            // Gyro rate: adc * 0.0281230 radians/sec
            roll_rate = gyro_x * 0.0281230;
            pitch_rate = gyro_y * 0.0281230;

出0入0汤圆

 楼主| 发表于 2008-7-29 13:09:37 | 显示全部楼层
to : 【118楼】 kb6mcc

大侠继续讲下去啊,我们都等在聆听!

此处由三轴加速度算出仰俯角与横滚角
            roll = atan2(accel_y, accel_z);
            pitch = atan2(-accel_x, accel_z);

此处由三轴陀螺仪算出当前仰俯角速度与横滚角速度
            roll_rate = gyro_x * 0.0281230;
            pitch_rate = gyro_y * 0.0281230;

三轴加速度算出的角度容易受到非重力加速度的影响而偏差
三轴陀螺仪算出的角速度,只有当前瞬时值,没有绝对参照角度
如何将二者“结合”啊?迫切期待下文

出0入0汤圆

发表于 2008-7-29 13:55:26 | 显示全部楼层
我用的全部都是矢量

极径 极角   


效率很高   折算到推力上  可以用近似计算

出0入0汤圆

发表于 2008-7-30 15:33:59 | 显示全部楼层
【119楼】 feng_matrix

kb6mcc 迟迟没有回答。我来说说我的理解吧,大家批判!

三轴加速度算出仰俯角与横滚角
            roll = atan2(accel_y, accel_z);  
            pitch = atan2(-accel_x, accel_z);  

三轴陀螺仪算出当前仰俯角速度与横滚角速度
            roll_rate = gyro_x * 0.0281230;  
            pitch_rate = gyro_y * 0.0281230;
然后 kalman_update(roll_rate , roll)
     kalman_update(pitch_rate ,  pitch)

常量B[0.019968,0]  ,那么 B * u  是角度(B是采样时间)?

这样理解不就能理顺了吗?

出0入0汤圆

 楼主| 发表于 2008-7-30 20:45:36 | 显示全部楼层
【121楼】 zhcool_521

其实kb6mcc贴的这个卡尔曼滤波算法输入量只有【三轴加速度算出仰俯角或横滚角】与
【三轴陀螺仪算出当前仰俯角速度或横滚角速度】两个
输入常量有ENC-03的灵敏度、采样间隔dt,输出就是经过校正的【仰俯角或横滚角】
其它算法中使用的矩阵、卡尔曼增益、预测协方差、测量协方差只要设好初值
算法会自动在递归过程中维护的,目前还未完全看懂kb6mcc的程序
但已经对卡尔曼产生无限敬仰了

出0入0汤圆

发表于 2008-7-31 08:18:33 | 显示全部楼层
我也是这么理解!

出0入0汤圆

 楼主| 发表于 2008-7-31 22:06:12 | 显示全部楼层
非常感谢 kb6mcc 大侠的讲解,正在努力学习KALMAN滤波算法中
kb6mcc内功外功俱强是真的高人,惭愧啊!
这个是我参照 kb6mcc 程序做的效果,白色线是三轴加速度计算的X轴倾角,红色是经过kalman滤波后的
测量协方差、预测协方差参数还不怎么会选择,白色红色基本吻合,滤波效果不大
下方两个圆是用来直观显示陀螺仪硬件倾角的,从网上视频学来的
PC程序用DIRECT X SDK做的

(原文件名:CIMG0212.JPG)


(原文件名:CIMG0215.JPG)


(原文件名:CIMG0216.JPG)


(原文件名:CIMG0219.JPG)


(原文件名:CIMG0223.JPG)

出0入0汤圆

 楼主| 发表于 2008-7-31 22:09:00 | 显示全部楼层
这个把KALMAN滤波后的角度信息传送到PC屏幕中的3D坐标系里,用DIRECTX绘制的四轴倾角效果
目前只接收了一个轴的倾转,三轴同时倾斜效果,需要写大量的坐标变换矩阵,实在静不下心来写了


(原文件名:CIMG0224.JPG)


(原文件名:CIMG0225.JPG)


(原文件名:CIMG0223.JPG)

出0入0汤圆

 楼主| 发表于 2008-7-31 22:19:49 | 显示全部楼层
陀螺仪_加速度_卡尔曼滤波

http://6.cn/watch/6508494.html

http://6.cn/watch/6508516.html

http://6.cn/watch/6508516.html

http://6.cn/watch/6508503.html

出0入0汤圆

 楼主| 发表于 2008-8-1 08:53:08 | 显示全部楼层
视频 陀螺仪_加速度_卡尔曼滤波3D

http://6.cn/watch/6508463.html

http://6.cn/watch/6508634.html

http://6.cn/watch/6508636.html

出0入0汤圆

发表于 2008-8-1 09:56:36 | 显示全部楼层
滤波效果一般,和我现在做的差不多!  比kb6mcc 老兄自己做的视频 效果差的较多!剧烈变速运动或者剧烈震动的时候效果 不好!

你的卡尔曼滤波程序 是作在单片机上的? 还是做在pc 上?

出0入0汤圆

发表于 2008-8-1 10:00:35 | 显示全部楼层
kb6mcc  给的这段  离散式曼滤波  有漏洞,具体漏洞我还不敢妄言,至少和资料上的算法有差别!

老觉得  离散式曼滤波  只能做到这种效果了,楼主 是不是 试验一下  扩展卡曼?

出0入0汤圆

 楼主| 发表于 2008-8-1 12:24:31 | 显示全部楼层
卡尔曼滤波写在单片机中的,M16资源刚好,再复杂程序就写不下了,PC端只接收算好的角度值并显示

你说的漏洞指什么?算法缺陷?

出0入0汤圆

发表于 2008-8-1 14:21:18 | 显示全部楼层
到现在我还不能确定到底是我理解问题,还是他算法问题。

1.Inn = y - c * xhat;    c是1*2矩阵,xhat是2*1矩阵那么c * xhat是2*1矩阵,而y是1*1矩阵,他们不能减法
2.我觉得Inn = y - c * xhat中的xhat应该是xhat_est。
3.P = A * P * A' - K * C * P * A' + Sw 中的p 应该是k+1次的先验估计误差协方差 ,我觉得这个推倒公式有问题。

以上问题我都在程序里面试过了,但是效果没有改进!

出0入0汤圆

发表于 2008-8-1 18:15:04 | 显示全部楼层

(原文件名:更新.JPG)

更新后的kalman  效果!

出0入0汤圆

 楼主| 发表于 2008-8-2 22:29:48 | 显示全部楼层
上面这个已经做的很不错了

出0入0汤圆

发表于 2008-8-3 00:30:21 | 显示全部楼层
我觉得只能这样了,因为 kalman输入本身就有毛刺!胎里带来的毛病!

出0入0汤圆

发表于 2008-8-3 01:38:26 | 显示全部楼层
kalman算是很标准了。
楼上的能不能贴出效果图?

另外是不是另起一帖,这个帖子已经太长了。

出0入0汤圆

发表于 2009-4-10 15:12:16 | 显示全部楼层
TO  feng_matrix:
请问能共享你的DELPHI + DIRECT X SDK展示程序么?

出0入0汤圆

发表于 2009-4-10 16:33:19 | 显示全部楼层
还有个方法,就是建立飞行器的动态模型, dynamic model,用 dynamic model 做observer,去constrain 惯导的误差。我看到过一些论文是这么做的。

出0入0汤圆

发表于 2009-4-10 16:34:58 | 显示全部楼层
还有个方法,就是建立飞行器的动态模型, dynamic model,用 dynamic model 做observer,去constrain 惯导的误差。我看到过一些论文是这么做的。

出0入0汤圆

发表于 2009-4-11 22:36:11 | 显示全部楼层
感觉kalman对变速直线运动的处理还不太好,可能是kalman自身的限制了,对变速直线运动的情况可能需要进一步特殊处理,另外,对于陀螺的时漂也是需要特殊处理的,毕竟大部分人用的低档陀螺中点飘移都很快。。。这样,kalman远远不够了

出0入25汤圆

发表于 2009-4-28 16:34:46 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2009-4-29 03:22:13 | 显示全部楼层
回141, 这个和Kalman filter无关,和你的系统模型有关,你的系统模型建的越好,结果越好。

出0入0汤圆

发表于 2009-5-5 22:09:32 | 显示全部楼层
这个主题太强大了,继续学习

出0入0汤圆

发表于 2009-5-6 08:43:57 | 显示全部楼层
to 【楼主位】 feng_matrix

请教,关于仿真德国四轴中没有要到原来的加速度传感器,用了个MMA7261来代替它,当热程序也就没有用德国的原程序了,用的是Pitolan四轴提供的644p(MMA7260)的程序。。。结果测试发现:会出现加速度和陀螺仪的波形重合不怎么好的问题。经过对比
MMA7261 每G输出: 480mv/g
MMA7260 每G输出: 800mv/g  

难怪的了,加速度表现的不是非常敏感! 所以我改在源程序的那段代码进行更改下!TKS

哦!不知道pitolan 老兄有没有注意到这个问题??

出0入0汤圆

发表于 2009-11-29 03:10:35 | 显示全部楼层
mark,慢慢看

出0入0汤圆

发表于 2010-3-8 17:12:33 | 显示全部楼层
MARK 强贴

出0入0汤圆

发表于 2010-3-8 18:21:50 | 显示全部楼层
mark
慢慢消化

出0入0汤圆

发表于 2010-4-9 16:17:18 | 显示全部楼层
不讨论了么,卡尔曼太强大了,还没有找到入口

出0入0汤圆

发表于 2010-5-24 16:18:59 | 显示全部楼层
what's the function of  // Zero adjust the gyro values.  
                         gyro_x -= 470.5;
                         gyro_y -= 440.5;

                        // Zero adjust the accelerometer values.  .
                           accel_x -= 506.0;
                           accel_y -= 506.0;
                           accel_z -= 506.0;
Is it according to the AD com?(com is the voltage reference point of the AD)

出0入0汤圆

发表于 2010-9-20 21:26:16 | 显示全部楼层
回复【楼主位】feng_matrix 悟
-----------------------------------------------------------------------

最近在论坛吗,可以问你几个关于惯性测姿的问题吗

出0入0汤圆

发表于 2010-9-20 21:29:06 | 显示全部楼层
回复【23楼】kennyzhao
-----------------------------------------------------------------------

最近在论坛吗,可以问你几个关于惯性测姿的问题吗

出0入0汤圆

 楼主| 发表于 2010-9-21 09:56:27 | 显示全部楼层
回复【151楼】yihuiqiao
回复【楼主位】feng_matrix 悟
-----------------------------------------------------------------------
最近在论坛吗,可以问你几个关于惯性测姿的问题吗
-----------------------------------------------------------------------

说吧,网络上总有人能提出点建议的

出0入0汤圆

发表于 2010-10-1 20:18:22 | 显示全部楼层
说说我的想法吧,基本上是瞎讲,各位就瞎听下.

首先用陀螺仪解算出姿态(无论用欧拉角方向余玄,四元数无所谓啊,数学问题而已的)

然后根据姿态解算出重力在3个轴上的分量,根据实际测量的加速度值和解算出重力值做比较,

然后用把螺仪解算出的姿态和测量的加速度值做数据融合(如果实际测量的加速度值和解算出重力值相差大就多相信姿态陀螺仪解算出的数据,如果相差很小就多相信加速度计的值)

如果有办法测量出运动加速度就好了.

出0入0汤圆

发表于 2010-11-6 01:23:08 | 显示全部楼层
回复【60楼】Alex_rcpilot
-----------------------------------------------------------------------

还可以用空速管

出0入0汤圆

发表于 2010-11-6 01:27:52 | 显示全部楼层
回复【154楼】hare1207
-----------------------------------------------------------------------

回复【154楼】hare1207
说说我的想法吧,基本上是瞎讲,各位就瞎听下.
首先用陀螺仪解算出姿态(无论用欧拉角方向余玄,四元数无所谓啊,数学问题而已的)
然后根据姿态解算出重力在3个轴上的分量,根据实际测量的加速度值和解算出重力值做比较,
然后用把螺仪解算出的姿态和测量的加速度值做数据融合(如果实际测量的加速度值和解算出重力值相差大就多相信姿态陀螺仪解算出的数据,如果相差很小就多相信加速度计的值)
如果有办法测量出运动加速度就好了.
-----------------------------------------------------------------------
“然后根据姿态解算出重力在3个轴上的分量,根据实际测量的加速度值和解算出重力值做比较,
然后用把螺仪解算出的姿态和测量的加速度值做数据融合(如果实际测量的加速度值和解算出重力值相差大就多相信姿态陀螺仪解算出的”

逻辑有问题,不可行

出0入0汤圆

 楼主| 发表于 2010-11-6 15:44:30 | 显示全部楼层
回复【156楼】skystalker
回复【154楼】hare1207  
-----------------------------------------------------------------------
回复【154楼】hare1207  
说说我的想法吧,基本上是瞎讲,各位就瞎听下.  
首先用陀螺仪解算出姿态(无论用欧拉角方向余玄,四元数无所谓啊,数学问题而已的)  
然后根据姿态解算出重力在3个轴上的分量,根据实际测量的加速度值和解算出重力值做比较,  
然后用把螺仪解算出的姿态和测量的加速度值做数据融合(如果实际测量的加速度值和解算出重力值相差大就多相信姿态陀螺仪解算出的数据,如果相差很小就多相信加速度计的值)  
如果有办法测量出运动加速度就好了.
-----------------------------------------------------------------------
“然后根据姿态解算出重力在3个轴上的分量,根据实际测量的加速度值和解算出重力值做比较,  
然后用把螺仪解算出的姿态和测量的加速度值做数据融合(如果实际测量的加速度值和解算出重力值相差大就多相信姿态陀螺仪解算出的”

逻辑有问题,不可行

-----------------------------------------------------------------------


逻辑确实有问题,在有外力影响的情况下,很容易创造一个3轴加速度矢量和为1G,但方向不指向地心的情况,比如飞机定速盘旋
重力加速度与外力加速度都是惯性加速度,都是万有引力的表现,只靠3轴加速度计根本不能确定自身的运动姿态。

调节陀螺与加速度倾角权重的依据,不是“相差大小”,而是时间尺度
短时间尺度,陀螺仪积分角相对真实,但陀螺仪长期积分误差会累积
长时间尺度,加速度角没有误差累积,但瞬时值会被外力加速度干扰

出0入0汤圆

发表于 2010-11-7 10:58:35 | 显示全部楼层
如果把传感器部署在四周的顶端(靠近四个顶点的位置)会不会效果更好一点啊?是否能放大灵敏度?
当然算法也需要改了

出0入0汤圆

发表于 2010-11-9 21:46:13 | 显示全部楼层
请教下:matrix 的显示陀螺仪的图片:

      陀螺仪的数据坐标图上怎么都有那样多的反冲,如果Y轴是角速度值,matrix的图片的积分应该大概是零吧,

      用的是ENC 03 的陀螺仪吗,感觉怎么有不停的过冲现象,不知道是不是用的ENC 推荐的电路,感觉ENC 推荐的电路

      的RC对低频起的是微分作用(不知道如果用ENC推荐电路,如果角速度值恒定,陀螺仪输出的电压值恒定,经过RC电路后不就输出为Ref脚电压,交速度为零了吗)

      所以波形看起来有反冲,对高频起的是耦合作用, 感觉陀螺仪out角输出的波形应该是下面的样子,但经过RC电路后变成了matrix的图片的样子,

      但疑惑的是最终结构确实正确的,软件做的两次积分吗?

      为了大家看起来方便,也附上ENC 推荐电路

(原文件名:未命名.jpg)


(原文件名:未命名1.jpg)

出0入0汤圆

发表于 2010-11-10 01:49:15 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-11-13 23:18:09 | 显示全部楼层
说不讨论硬件,但还是多问一下,LZ是用三个enc-03合成三轴的?

出0入0汤圆

发表于 2010-11-29 09:03:38 | 显示全部楼层
回复【楼主位】feng_matrix 悟
-----------------------------------------------------------------------

mark

出0入0汤圆

发表于 2010-12-6 23:18:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-23 19:50:01 | 显示全部楼层
经典贴 留名

出0入0汤圆

发表于 2011-2-10 00:52:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-23 17:31:08 | 显示全部楼层
好长的帖子,mark一下,回来好好研究!

出0入0汤圆

发表于 2011-2-23 21:16:01 | 显示全部楼层
悲剧啊!
kb6mcc 大侠发的网址都上不去的
http://www.youtube.com/watch?v=1DDEH2n2_hY
“YouTube在中国无法浏览
Google旗下的YouTube视频网站含有不合法的视频、图像、言论等内容,违反了中国互联网审查标准。自YouTube香港分站2007年10月18日推出后,2007年11月份YouTube在中国国内便被收录互联网关键字阻断过滤的范畴,并使用IP封锁、URL关键词过滤、DNS域名劫持污染、TCP连接重置、主干网路由器侦测拦截等方法进行阻断屏蔽,同时中国三大主要互联网服务提供商〈ISP〉封锁了YouTube的DNS服务器端口的接入,屏蔽了YouTube的所有国际IP地址,故中国国内地区无法浏览访问YouTube,在华外籍人士和留学生一般通过使用VPN或其他代理服务进行访问。”------YouTube  百度百科

出0入0汤圆

发表于 2011-5-16 15:32:27 | 显示全部楼层
经典啊

出0入0汤圆

发表于 2011-5-22 18:32:24 | 显示全部楼层
学习下

出0入0汤圆

发表于 2011-5-31 13:19:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-15 10:46:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-15 15:50:54 | 显示全部楼层
没消化了啊,,,,

Kalman滤波

出0入0汤圆

发表于 2011-6-15 20:45:26 | 显示全部楼层
没看到几个人说算法,还有关键的传感器补偿。凡是真做过惯导的人都知道,四元数算法和KF都很现成不是什么难题,最为关键的是怎么补偿传感器。

出0入0汤圆

发表于 2011-6-15 21:08:58 | 显示全部楼层
樓上沒看到就由你先開頭囉!!^_^

出0入0汤圆

发表于 2011-6-16 01:23:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-16 23:18:14 | 显示全部楼层
回复【174楼】g921002
-----------------------------------------------------------------------

好,开个头。对于姿态解算方面有很多方法,余弦法,欧拉角法,四元数法,等效旋转矢量法这些都是很成熟的算法,对于姿态的圆锥运动和线速度的划桨效应都有很好的补偿。但是,因为成本或者工艺的问题,传感器的零位精度和标度因数精度很难达到令人满意的程度,特别是在全温度下更是不能让人满意。因此需要对传感器做补偿,一般通过实验的方法来获得传感器的零位,零偏稳定性,标度因数,标度因数稳定性,零位随温度的安装误差,标度因数随温度的变化曲线。当然就算知道了这些还是很难使得传感器的应用得心应手,因此传感器的零位漂移很大,几天就可能偏离,因此,大部分应用中会在程序里进行自标定。当然这是建立在认为传感器处在0——0——g的环境下,忽略了排放和安装误差角还有陀螺的g值敏感项。当然如果想更准确点,可以采用椭球拟合算取零位,这样会很准确。还有就是大家一般会用加速度传感器来补偿,但是这里面会有杆臂效应,可以通过安装对称加速度传感器来消除。

出0入0汤圆

发表于 2011-6-17 00:23:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-19 12:01:01 | 显示全部楼层
void angle()         //姿态矩阵
{
float DX,DX1,DX2,DX3,DY,DY1,DY2,DY3,DZ,DZ1,DZ2,DZ3;
float model,q0,q1,q2,q3;
float d0,d1,d2,d3;
float model_q;
float T11,T12,T13,T21,T22,T23,T31,T32,T33;
DX=DX1+DX2+DX3+(9/20)*(DY1*DZ3+DZ1*DY3)+(27/40)*(DY2*(DZ3-DZ1)+DX2*(DX3-DX1));
DY=DY1+DY2+DY3+(9/20)*(DY1*DY3+DX1*DZ3)+(27/40)*(DZ2*(DX3-DX1)+DY2*(DY3-DY1));
DZ=DZ1+DZ2+DZ3+(9/20)*(DZ1*DZ3+DY1*DX3)+(27/40)*(DX2*(DY3-DY1)+DY2*(DZ3-DZ1));
model=sqrt(DX*DX+DY*DY+DZ*DZ);
if(model==0)
{
q0=1;
q1=0;
q2=0;
q3=0;
}
else
{
q0=cos(model/2);
q1=(DX/model)*sin(model/2);
q2=(DY/model)*sin(model/2);
q3=(DZ/model)*sin(model/2);
}
d0=q0*q0-q1*q1-q2*q2-q3*q3;
d1=q0*q1+q1*q0+q3*q2-q2*q3;
d2=q2*q0-q3*q2+q0*q3+q1*q3;
d3=q3*q0+q2*q1-q1*q2+q0*q3;

q0=d0;
q1=d1;
q2=d2;
q3=d3;

//四元数归一
model_q=sqrt(q0*q0+q1*q1+q2*q2+q3*q3);
d0=q0/model_q;
d1=q1/model_q;
d2=q2/model_q;
d3=q3/model_q;
q0=d0;
q1=d1;
q2=d2;
q3=d3;
//
//解算姿态
T11=q0*q0+q1*q1-q2*q2-q3*q3;
T12=2*(q1*q2-q0*q3);
T13=2*(q1*q3+q0*q2);
T21=2*(q1*q2+q0*q3);
T22=q0*q0-q1*q1+q2*q2-q3*q3;
T23=2*(q2*q3-q0*q1);
T31=2*(q1*q3-q0*q2);
T32=2*(q2*q3+q0*q1);
T33=q0*q0-q1*q1-q2*q2+q3*q3;
pitch=asin(T32);
if(T22==0&&T12>0)
yaw=pi/2;
if(T22==0&&T12<0)
yaw=-pi/2;
if(T22>0&&T12>0)
yaw=atan(-T31/T33);
if(T22>0&&T12<0)
yaw=atan(-T31/T33);
if(T22<0&&T12>0)
yaw=atan(-T31/T33)+2*pi;
if(T22<0&&T12<0)
yaw=atan(-T31/T33)-2*pi;

}
四元数解算程序,大家有会的却没发,本来我也不想发,实际想想也没个什么用,给大家发下看看,本来是用DSP实现的,现在用单片机来玩,速度可能慢,也不定一下就能用,QQ1487494416

出0入0汤圆

发表于 2011-7-7 18:47:06 | 显示全部楼层
回复【楼主位】feng_matrix 悟
-----------------------------------------------------------------------

mark,学习下

出0入0汤圆

发表于 2011-8-22 23:46:32 | 显示全部楼层
Mark

出0入0汤圆

发表于 2011-8-24 15:32:13 | 显示全部楼层
回复【23楼】kennyzhao
-----------------------------------------------------------------------

”但是要计算飞行器的轨迹就要有三轴线加速度系统,(比如:算出向左,向上,向前运动了多少米))“
用加速度计计算速度和距离可靠吗

出0入0汤圆

发表于 2011-9-16 16:11:02 | 显示全部楼层
mark 学习

出0入0汤圆

发表于 2011-9-16 19:10:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-4 19:55:01 | 显示全部楼层
好贴,学习了。

出0入0汤圆

发表于 2011-10-7 20:43:32 | 显示全部楼层
好深呐

出0入0汤圆

发表于 2011-10-8 08:35:10 | 显示全部楼层
楼主,您好,能给说说陀螺仪和加速度计在四轴飞行器中的作用么,二者的数据是如何结合使用的。我刚开始接触,谢谢

出0入0汤圆

发表于 2011-10-16 16:29:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-24 19:08:05 | 显示全部楼层
加个DSP做大量运算,用mega16做判断主控。新手,飘过

出0入0汤圆

发表于 2011-10-26 10:14:48 | 显示全部楼层
现在大家的效果表现怎么样了,有没有人出来秀一下。

出0入0汤圆

发表于 2011-10-28 16:14:12 | 显示全部楼层
还在电机启动阶段,希望早日达到算法阶段

出0入0汤圆

发表于 2011-10-30 16:46:38 | 显示全部楼层
学习中

出0入0汤圆

发表于 2011-10-30 17:01:29 | 显示全部楼层
高端了 先MARK一下

出0入0汤圆

发表于 2011-11-16 13:30:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-16 13:46:54 | 显示全部楼层
回复【190楼】fkepdcjgd  雾都溪风
-----------------------------------------------------------------------

我做的,刷锅只需要航向和倾斜打到底,控制好油门就行

出0入0汤圆

发表于 2011-11-16 14:03:20 | 显示全部楼层
回复【178楼】asha  
-----------------------------------------------------------------------
无然,我们又见面啦。

你那个程序好,配合辛普森积分,可以补偿圆锥运动和划桨运动误差。

出0入0汤圆

发表于 2011-11-16 17:04:17 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-11-16 23:42:04 | 显示全部楼层
新手。。。。 马克下         以后要用了在来看看

出0入0汤圆

发表于 2011-11-23 13:37:38 | 显示全部楼层
% 建模数据;
% 陀螺仪选用ADXRS150,灵敏度为15mv/°/s;
% 采样点个数 N=2500;
% 采样周期 T=0.002s;
% angle_KF 经过滤波后的角度;
% velocity_KF 经过滤波后的角速率;
% Y=[angle_KF(n);velocity_KF(n)];

t=0.002:0.002:5;    % 共5秒时间;
T=0.002;            % 采样周期;
% load test_velocity_vol test_velocity_vol;% 陀螺仪读数(电压值),1*2500;
load data2 data2;% 陀螺仪读数(电压值),1*2500;
test_velocity_vol = data2;
temp = ones(1,2500);
temp = temp * 2.7;               
velocity_vol = test_velocity_vol - temp% 陀螺仪静态输出2.5V;
velocity = velocity_vol / (15 / 1000);   % 陀螺仪角速率;
angle(1) =0;       % 陀螺仪初始位置;
for n=2:2500;
    angle(n) = angle(n-1) + velocity(n)*T;  % 在迭代过程中实际角度
end
save angle angle
save velocity velocity

load angle angle; % 陀螺仪积分得到的角度,未滤波;
load velocity velocity % 陀螺角速率,未滤波;
T = 0.002;        % 采样周期;
Y=zeros(2,2500);  % 初值为0;
Y0=[0.5;2];       % 系统状态初始值;
Y(:,1)=Y0;
A=[1,T;0,1];      % 系统状态转移矩阵;     
B=[1/2*(T)^2 T]'; % 噪声输入矩阵;
H=[1 1];          % 观测阵;

C0=[0.1,0;0,1];     % cov 初始值;
C=[C0 zeros(2,2*2499)];
Q=(0.25)^2;       % 过程噪声;
R=(0.25)^2;       % 观测噪声;

% 卡尔曼算法;
for n=1:2500
    i=(n-1)*2+1;
    K=C(:,i:i+1)*H'*inv(H*C(:,i:i+1)*H'+R);
    Y(:,n)=Y(:,n)+K*(angle(:,n)-H*Y(:,n));
    Y(:,n+1)=A*Y(:,n);
    C(:,i:i+1)=(eye(2,2)-K*H)*C(:,i:i+1);
    C(:,i+2:i+3)=A*C(:,i:i+1)*A'+B*Q*B';
end

figure(6)
t=0.002:0.002:5;
plot(t,angle_KF,'r',t,angle,'b',t,velocity_KF,'c',t,velocity,'g');
legend('angle after KF','angle','velocity after KF','velocity');
grid;
xlabel('time');
ylabel('four status');
title('KF VS NoKF');

下面这个图是滤波效果,有个疑问:陀螺仪是手拿着来回旋转的,为啥积分后的角度输出始终增大呢?


(原文件名:最新.jpg)

出0入0汤圆

发表于 2011-11-23 13:44:27 | 显示全部楼层
是不是零漂没能完全抵消,然后随时间累计增大了?

出0入0汤圆

发表于 2011-12-1 22:57:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-6 10:37:13 | 显示全部楼层
认真拜读了这个帖子,感觉坛里真是高人辈出啊。小弟刚刚开始学习惯性导航和卡尔曼滤波等,希望大家多多指导,多多交流……

出0入0汤圆

发表于 2011-12-6 10:50:10 | 显示全部楼层
我现在用的是ADIS16405,想通过feng_matrix的那个算法把3陀螺仪、3加速度计和3磁航向都用起来,但是下手困难啊,能否给点代码练习下呢。

msn:bianjiangnan@hotmail.com

出0入0汤圆

发表于 2011-12-29 17:11:00 | 显示全部楼层
弱弱的问一句,现在的四元法和卡尔曼滤波都这么成熟了,感觉是不是没有很大的改进空间。看了一些姿态解算的书,基本上都是默认这种算法组合。我毕设是做四旋翼的飞机系统,涉及到姿态解算这块,但是一直都没有什么创新的好想法
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-20 23:52

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

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