Пример #1
0
void mf16_fill_diagonal(mf16 *dest, fix16_t value)
{
    int row;
    
    mf16_fill(dest, 0);
    
    for (row = 0; row < dest->rows; row++)
    {
        dest->data[row][row] = value;
    }
}
Пример #2
0
void mf16_qr_decomposition(mf16 *q, mf16 *r, const mf16 *matrix, int reorthogonalize)
{
    int i, j, reorth;
    fix16_t dot, norm;
    
    uint8_t stride = FIXMATRIX_MAX_SIZE;
    uint8_t n = matrix->rows;
    
    // This uses the modified Gram-Schmidt algorithm.
    // subtract_projection takes advantage of the fact that
    // previous columns have already been normalized.
    
    // We start with q = matrix
    if (q != matrix)
    {
        *q = *matrix;
    }
    
    // R is initialized to have square size of cols(A) and zeroed.
    r->columns = matrix->columns;
    r->rows = matrix->columns;
    r->errors = 0;
    mf16_fill(r, 0);
    
    // Now do the actual Gram-Schmidt for the rows.
    for (j = 0; j < q->columns; j++)
    {
        for (reorth = 0; reorth <= reorthogonalize; reorth++)
        {
            for (i = 0; i < j; i++)
            {
                fix16_t *v = &q->data[0][j];
                fix16_t *u = &q->data[0][i];
                
                dot = fa16_dot(v, stride, u, stride, n);
                subtract_projection(v, u, dot, n, &q->errors);
                
                if (dot == fix16_overflow)
                    q->errors |= FIXMATRIX_OVERFLOW;
                
                r->data[i][j] += dot;
            }
        }
        
        // Normalize the row in q
        norm = fa16_norm(&q->data[0][j], stride, n);
        r->data[j][j] = norm;
        
        if (norm == fix16_overflow)
            q->errors |= FIXMATRIX_OVERFLOW;
        
        if (norm < 5 && norm > -5)
        {
            // Nearly zero norm, which means that the row
            // was linearly dependent.
            q->errors |= FIXMATRIX_SINGULAR;
            continue;
        }
        
        for (i = 0; i < n; i++)
        {
            // norm >= v[i] for all i, therefore this division
            // doesn't overflow unless norm approaches 0.
            q->data[i][j] = fix16_div(q->data[i][j], norm);
        }
    }
    
    r->errors = q->errors;
}
Пример #3
0
/*!
* \brief Initializes the gravity Kalman filter
*/
static void kalman_gravity_init()
{
    /************************************************************************/
    /* initialize the filter structures                                     */
    /************************************************************************/
#if USE_UNCONTROLLED
    kalman_filter_initialize_uc(&kf, KALMAN_NUM_STATES);
#else
    kalman_filter_initialize(&kf, KALMAN_NUM_STATES, KALMAN_NUM_INPUTS);
#endif
    kalman_observation_initialize(&kfm, KALMAN_NUM_STATES, KALMAN_NUM_MEASUREMENTS);

    /************************************************************************/
    /* set initial state                                                    */
    /************************************************************************/
#if USE_UNCONTROLLED
    mf16 *x = kalman_get_state_vector_uc(&kf);
#else
    mf16 *x = kalman_get_state_vector(&kf);
#endif
    x->data[0][0] = 0; // s_i
    x->data[1][0] = 0; // v_i
    x->data[2][0] = fix16_from_float(6); // g_i

    /************************************************************************/
    /* set state transition                                                 */
    /************************************************************************/
#if USE_UNCONTROLLED
    mf16 *A = kalman_get_state_transition_uc(&kf);
#else
    mf16 *A = kalman_get_state_transition(&kf);
#endif
    
    // set time constant
    const fix16_t T = fix16_one;
    const fix16_t Tsquare = fix16_sq(T);

    // helper
    const fix16_t fix16_half = fix16_from_float(0.5);

    // transition of x to s
    matrix_set(A, 0, 0, fix16_one);   // 1
    matrix_set(A, 0, 1, T);   // T
    matrix_set(A, 0, 2, fix16_mul(fix16_half, Tsquare)); // 0.5 * T^2
    
    // transition of x to v
    matrix_set(A, 1, 0, 0);   // 0
    matrix_set(A, 1, 1, fix16_one);   // 1
    matrix_set(A, 1, 2, T);   // T

    // transition of x to g
    matrix_set(A, 2, 0, 0);   // 0
    matrix_set(A, 2, 1, 0);   // 0
    matrix_set(A, 2, 2, fix16_one);   // 1

    /************************************************************************/
    /* set covariance                                                       */
    /************************************************************************/
#if USE_UNCONTROLLED
    mf16 *P = kalman_get_system_covariance_uc(&kf);
#else
    mf16 *P = kalman_get_system_covariance(&kf);
#endif

    matrix_set_symmetric(P, 0, 0, fix16_half);   // var(s)
    matrix_set_symmetric(P, 0, 1, 0);   // cov(s,v)
    matrix_set_symmetric(P, 0, 2, 0);   // cov(s,g)

    matrix_set_symmetric(P, 1, 1, fix16_one);   // var(v)
    matrix_set_symmetric(P, 1, 2, 0);   // cov(v,g)

    matrix_set_symmetric(P, 2, 2, fix16_one);   // var(g)

    /************************************************************************/
    /* set system process noise                                             */
    /************************************************************************/
#if USE_UNCONTROLLED
    mf16 *Q = kalman_get_system_process_noise_uc(&kf);
    mf16_fill(Q, F16(0.0001));
#endif

    /************************************************************************/
    /* set measurement transformation                                       */
    /************************************************************************/
    mf16 *H = kalman_get_observation_transformation(&kfm);

    matrix_set(H, 0, 0, fix16_one);     // z = 1*s 
    matrix_set(H, 0, 1, 0);     //   + 0*v
    matrix_set(H, 0, 2, 0);     //   + 0*g

    /************************************************************************/
    /* set process noise                                                    */
    /************************************************************************/
    mf16 *R = kalman_get_observation_process_noise(&kfm);

    matrix_set(R, 0, 0, fix16_half);     // var(s)
}