/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// adapted from frameworks/native/services/sensorservice/Fusion.cpp

#include <algos/fusion.h>
#include <algos/mat.h>

#include <errno.h>
#include <nanohub_math.h>
#include <stdio.h>

#include <seos.h>

#ifdef DEBUG_CH
// change to 0 to disable fusion debugging output
#define DEBUG_FUSION  0
#endif

#define ACC     1
#define MAG     2
#define GYRO    4

#define DEFAULT_GYRO_VAR         1e-7f
#define DEFAULT_GYRO_BIAS_VAR    1e-12f
#define DEFAULT_ACC_STDEV        5e-2f
#define DEFAULT_MAG_STDEV        5e-1f

#define GEOMAG_GYRO_VAR          2e-4f
#define GEOMAG_GYRO_BIAS_VAR     1e-4f
#define GEOMAG_ACC_STDEV         0.02f
#define GEOMAG_MAG_STDEV         0.02f

#define SYMMETRY_TOLERANCE       1e-10f
#define FAKE_MAG_INTERVAL        1.0f  //sec

#define NOMINAL_GRAVITY          9.81f
#define FREE_FALL_THRESHOLD      (0.1f * NOMINAL_GRAVITY)
#define FREE_FALL_THRESHOLD_SQ   (FREE_FALL_THRESHOLD * FREE_FALL_THRESHOLD)

#define MAX_VALID_MAGNETIC_FIELD    75.0f
#define MAX_VALID_MAGNETIC_FIELD_SQ (MAX_VALID_MAGNETIC_FIELD * MAX_VALID_MAGNETIC_FIELD)

#define MIN_VALID_MAGNETIC_FIELD    20.0f   //norminal mag field strength is 25uT in some area
#define MIN_VALID_MAGNETIC_FIELD_SQ (MIN_VALID_MAGNETIC_FIELD * MIN_VALID_MAGNETIC_FIELD)

#define MIN_VALID_CROSS_PRODUCT_MAG     1.0e-3
#define MIN_VALID_CROSS_PRODUCT_MAG_SQ  (MIN_VALID_CROSS_PRODUCT_MAG * MIN_VALID_CROSS_PRODUCT_MAG)

#define DELTA_TIME_MARGIN 1.0e-9f

#define TRUST_DURATION_MANUAL_MAG_CAL      5.f  //unit: seconds

void initFusion(struct Fusion *fusion, uint32_t flags) {
    fusion->flags = flags;

    if (flags & FUSION_USE_GYRO) {
        // normal fusion mode
        fusion->param.gyro_var = DEFAULT_GYRO_VAR;
        fusion->param.gyro_bias_var = DEFAULT_GYRO_BIAS_VAR;
        fusion->param.acc_stdev = DEFAULT_ACC_STDEV;
        fusion->param.mag_stdev = DEFAULT_MAG_STDEV;
    } else {
        // geo mag mode
        fusion->param.gyro_var = GEOMAG_GYRO_VAR;
        fusion->param.gyro_bias_var = GEOMAG_GYRO_BIAS_VAR;
        fusion->param.acc_stdev = GEOMAG_ACC_STDEV;
        fusion->param.mag_stdev = GEOMAG_MAG_STDEV;
    }

    if (flags & FUSION_REINITIALIZE)
    {
        initVec3(&fusion->Ba, 0.0f, 0.0f, 1.0f);
        initVec3(&fusion->Bm, 0.0f, 1.0f, 0.0f);

        initVec4(&fusion->x0, 0.0f, 0.0f, 0.0f, 0.0f);
        initVec3(&fusion->x1, 0.0f, 0.0f, 0.0f);

        fusion->mInitState = 0;

        fusion->mPredictDt = 0.0f;
        fusion->mCount[0] = fusion->mCount[1] = fusion->mCount[2] = 0;

        initVec3(&fusion->mData[0], 0.0f, 0.0f, 0.0f);
        initVec3(&fusion->mData[1], 0.0f, 0.0f, 0.0f);
        initVec3(&fusion->mData[2], 0.0f, 0.0f, 0.0f);

    } else  {
        // mask off disabled sensor bit
        fusion->mInitState &= (ACC
                               | ((fusion->flags & FUSION_USE_MAG) ? MAG : 0)
                               | ((fusion->flags & FUSION_USE_GYRO) ? GYRO : 0));
    }

    fusionSetMagTrust(fusion, NORMAL);
    fusion->lastMagInvalid = false;
}

int fusionHasEstimate(const struct Fusion *fusion) {
    // waive sensor init depends on the mode
    return fusion->mInitState == (ACC
                                  | ((fusion->flags & FUSION_USE_MAG) ? MAG : 0)
                                  | ((fusion->flags & FUSION_USE_GYRO) ? GYRO : 0));
}

static void updateDt(struct Fusion *fusion, float dT) {
    if (fabsf(fusion->mPredictDt - dT) > DELTA_TIME_MARGIN) {
        float dT2 = dT * dT;
        float dT3 = dT2 * dT;

        float q00 = fusion->param.gyro_var * dT +
                    0.33333f * fusion->param.gyro_bias_var * dT3;
        float q11 = fusion->param.gyro_bias_var * dT;
        float q10 = 0.5f * fusion->param.gyro_bias_var * dT2;
        float q01 = q10;

        initDiagonalMatrix(&fusion->GQGt[0][0], q00);
        initDiagonalMatrix(&fusion->GQGt[0][1], -q10);
        initDiagonalMatrix(&fusion->GQGt[1][0], -q01);
        initDiagonalMatrix(&fusion->GQGt[1][1], q11);
        fusion->mPredictDt = dT;
    }
}

static int fusion_init_complete(struct Fusion *fusion, int what, const struct Vec3 *d, float dT) {
    if (fusionHasEstimate(fusion)) {
        return 1;
    }

    switch (what) {
        case ACC:
        {
            if (!(fusion->flags & FUSION_USE_GYRO)) {
                updateDt(fusion, dT);
            }
            struct Vec3 unityD = *d;
            vec3Normalize(&unityD);

            vec3Add(&fusion->mData[0], &unityD);
            ++fusion->mCount[0];

            if (fusion->mCount[0] == 8) {
                fusion->mInitState |= ACC;
            }
            break;
        }

        case MAG:
        {
            struct Vec3 unityD = *d;
            vec3Normalize(&unityD);

            vec3Add(&fusion->mData[1], &unityD);
            ++fusion->mCount[1];

            fusion->mInitState |= MAG;
            break;
        }

        case GYRO:
        {
            updateDt(fusion, dT);

            struct Vec3 scaledD = *d;
            vec3ScalarMul(&scaledD, dT);

            vec3Add(&fusion->mData[2], &scaledD);
            ++fusion->mCount[2];

            fusion->mInitState |= GYRO;
            break;
        }

        default:
            // assert(!"should not be here");
            break;
    }

    if (fusionHasEstimate(fusion)) {
        vec3ScalarMul(&fusion->mData[0], 1.0f / fusion->mCount[0]);

        if (fusion->flags & FUSION_USE_MAG) {
            vec3ScalarMul(&fusion->mData[1], 1.0f / fusion->mCount[1]);
        } else {
            fusion->fake_mag_decimation = 0.f;
        }

        struct Vec3 up = fusion->mData[0];

        struct Vec3 east;
        if (fusion->flags & FUSION_USE_MAG) {
            vec3Cross(&east, &fusion->mData[1], &up);
            vec3Normalize(&east);
        } else {
            findOrthogonalVector(up.x, up.y, up.z, &east.x, &east.y, &east.z);
        }

        struct Vec3 north;
        vec3Cross(&north, &up, &east);

        struct Mat33 R;
        initMatrixColumns(&R, &east, &north, &up);

        //Quat q;
        //initQuat(&q, &R);

        initQuat(&fusion->x0, &R);
        initVec3(&fusion->x1, 0.0f, 0.0f, 0.0f);

        initZeroMatrix(&fusion->P[0][0]);
        initZeroMatrix(&fusion->P[0][1]);
        initZeroMatrix(&fusion->P[1][0]);
        initZeroMatrix(&fusion->P[1][1]);

        fusionSetMagTrust(fusion, INITIALIZATION);
    }

    return 0;
}

static void matrixCross(struct Mat33 *out, struct Vec3 *p, float diag) {
    out->elem[0][0] = diag;
    out->elem[1][1] = diag;
    out->elem[2][2] = diag;
    out->elem[1][0] = p->z;
    out->elem[0][1] = -p->z;
    out->elem[2][0] = -p->y;
    out->elem[0][2] = p->y;
    out->elem[2][1] = p->x;
    out->elem[1][2] = -p->x;
}

static void fusionCheckState(struct Fusion *fusion) {

    if (!mat33IsPositiveSemidefinite(&fusion->P[0][0], SYMMETRY_TOLERANCE)
            || !mat33IsPositiveSemidefinite(
                &fusion->P[1][1], SYMMETRY_TOLERANCE)) {

        initZeroMatrix(&fusion->P[0][0]);
        initZeroMatrix(&fusion->P[0][1]);
        initZeroMatrix(&fusion->P[1][0]);
        initZeroMatrix(&fusion->P[1][1]);
    }
}

#define kEps 1.0E-4f

UNROLLED
static void fusionPredict(struct Fusion *fusion, const struct Vec3 *w) {
    const float dT = fusion->mPredictDt;

    Quat q = fusion->x0;
    struct Vec3 b = fusion->x1;

    struct Vec3 we = *w;
    vec3Sub(&we, &b);

    struct Mat33 I33;
    initDiagonalMatrix(&I33, 1.0f);

    struct Mat33 I33dT;
    initDiagonalMatrix(&I33dT, dT);

    struct Mat33 wx;
    matrixCross(&wx, &we, 0.0f);

    struct Mat33 wx2;
    mat33Multiply(&wx2, &wx, &wx);

    float norm_we = vec3Norm(&we);

    if (fabsf(norm_we) < kEps) {
        return;
    }

    float lwedT = norm_we * dT;
    float hlwedT = 0.5f * lwedT;
    float ilwe = 1.0f / norm_we;
    float k0 = (1.0f - cosf(lwedT)) * (ilwe * ilwe);
    float k1 = sinf(lwedT);
    float k2 = cosf(hlwedT);

    struct Vec3 psi = we;
    vec3ScalarMul(&psi, sinf(hlwedT) * ilwe);

    struct Vec3 negPsi = psi;
    vec3ScalarMul(&negPsi, -1.0f);

    struct Mat33 O33;
    matrixCross(&O33, &negPsi, k2);

    struct Mat44 O;
    uint32_t i;
    for (i = 0; i < 3; ++i) {
        uint32_t j;
        for (j = 0; j < 3; ++j) {
            O.elem[i][j] = O33.elem[i][j];
        }
    }

    O.elem[3][0] = -psi.x;
    O.elem[3][1] = -psi.y;
    O.elem[3][2] = -psi.z;
    O.elem[3][3] = k2;

    O.elem[0][3] = psi.x;
    O.elem[1][3] = psi.y;
    O.elem[2][3] = psi.z;

    struct Mat33 tmp = wx;
    mat33ScalarMul(&tmp, k1 * ilwe);

    fusion->Phi0[0] = I33;
    mat33Sub(&fusion->Phi0[0], &tmp);

    tmp = wx2;
    mat33ScalarMul(&tmp, k0);

    mat33Add(&fusion->Phi0[0], &tmp);

    tmp = wx;
    mat33ScalarMul(&tmp, k0);
    fusion->Phi0[1] = tmp;

    mat33Sub(&fusion->Phi0[1], &I33dT);

    tmp = wx2;
    mat33ScalarMul(&tmp, ilwe * ilwe * ilwe * (lwedT - k1));

    mat33Sub(&fusion->Phi0[1], &tmp);

    mat44Apply(&fusion->x0, &O, &q);

    if (fusion->x0.w < 0.0f) {
        fusion->x0.x = -fusion->x0.x;
        fusion->x0.y = -fusion->x0.y;
        fusion->x0.z = -fusion->x0.z;
        fusion->x0.w = -fusion->x0.w;
    }

    // Pnew = Phi * P

    struct Mat33 Pnew[2][2];
    mat33Multiply(&Pnew[0][0], &fusion->Phi0[0], &fusion->P[0][0]);
    mat33Multiply(&tmp, &fusion->Phi0[1], &fusion->P[1][0]);
    mat33Add(&Pnew[0][0], &tmp);

    mat33Multiply(&Pnew[0][1], &fusion->Phi0[0], &fusion->P[0][1]);
    mat33Multiply(&tmp, &fusion->Phi0[1], &fusion->P[1][1]);
    mat33Add(&Pnew[0][1], &tmp);

    Pnew[1][0] = fusion->P[1][0];
    Pnew[1][1] = fusion->P[1][1];

    // P = Pnew * Phi^T

    mat33MultiplyTransposed2(&fusion->P[0][0], &Pnew[0][0], &fusion->Phi0[0]);
    mat33MultiplyTransposed2(&tmp, &Pnew[0][1], &fusion->Phi0[1]);
    mat33Add(&fusion->P[0][0], &tmp);

    fusion->P[0][1] = Pnew[0][1];

    mat33MultiplyTransposed2(&fusion->P[1][0], &Pnew[1][0], &fusion->Phi0[0]);
    mat33MultiplyTransposed2(&tmp, &Pnew[1][1], &fusion->Phi0[1]);
    mat33Add(&fusion->P[1][0], &tmp);

    fusion->P[1][1] = Pnew[1][1];

    mat33Add(&fusion->P[0][0], &fusion->GQGt[0][0]);
    mat33Add(&fusion->P[0][1], &fusion->GQGt[0][1]);
    mat33Add(&fusion->P[1][0], &fusion->GQGt[1][0]);
    mat33Add(&fusion->P[1][1], &fusion->GQGt[1][1]);

    fusionCheckState(fusion);
}

void fusionHandleGyro(struct Fusion *fusion, const struct Vec3 *w, float dT) {
    if (!fusion_init_complete(fusion, GYRO, w, dT)) {
        return;
    }

    updateDt(fusion, dT);

    fusionPredict(fusion, w);
}

UNROLLED
static void scaleCovariance(struct Mat33 *out, const struct Mat33 *A, const struct Mat33 *P) {
    uint32_t r;
    for (r = 0; r < 3; ++r) {
        uint32_t j;
        for (j = r; j < 3; ++j) {
            float apat = 0.0f;
            uint32_t c;
            for (c = 0; c < 3; ++c) {
                float v = A->elem[c][r] * P->elem[c][c] * 0.5f;
                uint32_t k;
                for (k = c + 1; k < 3; ++k) {
                    v += A->elem[k][r] * P->elem[c][k];
                }

                apat += 2.0f * v * A->elem[c][j];
            }

            out->elem[r][j] = apat;
            out->elem[j][r] = apat;
        }
    }
}

static void getF(struct Vec4 F[3], const struct Vec4 *q) {
    F[0].x = q->w;      F[1].x = -q->z;         F[2].x = q->y;
    F[0].y = q->z;      F[1].y = q->w;          F[2].y = -q->x;
    F[0].z = -q->y;     F[1].z = q->x;          F[2].z = q->w;
    F[0].w = -q->x;     F[1].w = -q->y;         F[2].w = -q->z;
}

static void fusionUpdate(
        struct Fusion *fusion, const struct Vec3 *z, const struct Vec3 *Bi, float sigma) {
    struct Mat33 A;
    quatToMatrix(&A, &fusion->x0);

    struct Vec3 Bb;
    mat33Apply(&Bb, &A, Bi);

    struct Mat33 L;
    matrixCross(&L, &Bb, 0.0f);

    struct Mat33 R;
    initDiagonalMatrix(&R, sigma * sigma);

    struct Mat33 S;
    scaleCovariance(&S, &L, &fusion->P[0][0]);

    mat33Add(&S, &R);

    struct Mat33 Si;
    mat33Invert(&Si, &S);

    struct Mat33 LtSi;
    mat33MultiplyTransposed(&LtSi, &L, &Si);

    struct Mat33 K[2];
    mat33Multiply(&K[0], &fusion->P[0][0], &LtSi);
    mat33MultiplyTransposed(&K[1], &fusion->P[0][1], &LtSi);

    struct Mat33 K0L;
    mat33Multiply(&K0L, &K[0], &L);

    struct Mat33 K1L;
    mat33Multiply(&K1L, &K[1], &L);

    struct Mat33 tmp;
    mat33Multiply(&tmp, &K0L, &fusion->P[0][0]);
    mat33Sub(&fusion->P[0][0], &tmp);

    mat33Multiply(&tmp, &K1L, &fusion->P[0][1]);
    mat33Sub(&fusion->P[1][1], &tmp);

    mat33Multiply(&tmp, &K0L, &fusion->P[0][1]);
    mat33Sub(&fusion->P[0][1], &tmp);

    mat33Transpose(&fusion->P[1][0], &fusion->P[0][1]);

    struct Vec3 e = *z;
    vec3Sub(&e, &Bb);

    struct Vec3 dq;
    mat33Apply(&dq, &K[0], &e);


    struct Vec4 F[3];
    getF(F, &fusion->x0);

    // 4x3 * 3x1 => 4x1

    struct Vec4 q;
    q.x = fusion->x0.x + 0.5f * (F[0].x * dq.x + F[1].x * dq.y + F[2].x * dq.z);
    q.y = fusion->x0.y + 0.5f * (F[0].y * dq.x + F[1].y * dq.y + F[2].y * dq.z);
    q.z = fusion->x0.z + 0.5f * (F[0].z * dq.x + F[1].z * dq.y + F[2].z * dq.z);
    q.w = fusion->x0.w + 0.5f * (F[0].w * dq.x + F[1].w * dq.y + F[2].w * dq.z);

    fusion->x0 = q;
    quatNormalize(&fusion->x0);

    if (fusion->flags & FUSION_USE_MAG) {
        // accumulate gyro bias (causes self spin) only if not
        // game rotation vector
        struct Vec3 db;
        mat33Apply(&db, &K[1], &e);
        vec3Add(&fusion->x1, &db);
    }

    fusionCheckState(fusion);
}

#define ACC_TRUSTWORTHY(abs_norm_err)  ((abs_norm_err) < 1.f)
#define ACC_COS_CONV_FACTOR  0.01f
#define ACC_COS_CONV_LIMIT   3.f

int fusionHandleAcc(struct Fusion *fusion, const struct Vec3 *a, float dT) {
    if (!fusion_init_complete(fusion, ACC, a,  dT)) {
        return -EINVAL;
    }

    float norm2 = vec3NormSquared(a);

    if (norm2 < FREE_FALL_THRESHOLD_SQ) {
        return -EINVAL;
    }

    float l = sqrtf(norm2);
    float l_inv = 1.0f / l;

    if (!(fusion->flags & FUSION_USE_GYRO)) {
        // geo mag mode
        // drive the Kalman filter with zero mean dummy gyro vector
        struct Vec3 w_dummy;

        // avoid (fabsf(norm_we) < kEps) in fusionPredict()
        initVec3(&w_dummy, fusion->x1.x + kEps, fusion->x1.y + kEps,
                 fusion->x1.z + kEps);

        updateDt(fusion, dT);
        fusionPredict(fusion, &w_dummy);
    }

    struct Mat33 R;
    fusionGetRotationMatrix(fusion, &R);

    if (!(fusion->flags & FUSION_USE_MAG) &&
        (fusion->fake_mag_decimation += dT) > FAKE_MAG_INTERVAL) {
        // game rotation mode, provide fake mag update to prevent
        // P to diverge over time
        struct Vec3 m;
        mat33Apply(&m, &R, &fusion->Bm);

        fusionUpdate(fusion, &m, &fusion->Bm,
                      fusion->param.mag_stdev);
        fusion->fake_mag_decimation = 0.f;
    }

    struct Vec3 unityA = *a;
    vec3ScalarMul(&unityA, l_inv);

    float d = fabsf(l - NOMINAL_GRAVITY);
    float p;
    if (fusion->flags & FUSION_USE_GYRO) {
        float fc = 0;
        // Enable faster convergence
        if (ACC_TRUSTWORTHY(d)) {
            struct Vec3 aa;
            mat33Apply(&aa, &R, &fusion->Ba);
            float cos_err = vec3Dot(&aa, &unityA);
            cos_err = cos_err < (1.f - ACC_COS_CONV_FACTOR) ?
                (1.f - ACC_COS_CONV_FACTOR) : cos_err;
            fc = (1.f - cos_err) *
                    (1.0f / ACC_COS_CONV_FACTOR * ACC_COS_CONV_LIMIT);
        }
        p = fusion->param.acc_stdev * expf(3 * d - fc);
    } else {
        // Adaptive acc weighting (trust acc less as it deviates from nominal g
        // more), acc_stdev *= e(sqrt(| |acc| - g_nominal|))
        //
        // The weighting equation comes from heuristics.
        p = fusion->param.acc_stdev * expf(sqrtf(d));
    }

    fusionUpdate(fusion, &unityA, &fusion->Ba, p);

    return 0;
}

#define MAG_COS_CONV_FACTOR   0.02f
#define MAG_COS_CONV_LIMIT    3.5f
#define MAG_STDEV_REDUCTION   0.005f // lower stdev means more trust

int fusionHandleMag(struct Fusion *fusion, const struct Vec3 *m, float dT) {
    if (!fusion_init_complete(fusion, MAG, m, 0.0f /* dT */)) {
        return -EINVAL;
    }

    float magFieldSq = vec3NormSquared(m);

    if (magFieldSq > MAX_VALID_MAGNETIC_FIELD_SQ
            || magFieldSq < MIN_VALID_MAGNETIC_FIELD_SQ) {
        fusionSetMagTrust(fusion, NORMAL);
        fusion->lastMagInvalid = true;
        return -EINVAL;
    }

    struct Mat33 R;
    fusionGetRotationMatrix(fusion, &R);

    struct Vec3 up;
    mat33Apply(&up, &R, &fusion->Ba);

    struct Vec3 east;
    vec3Cross(&east, m, &up);

    if (vec3NormSquared(&east) < MIN_VALID_CROSS_PRODUCT_MAG_SQ) {
        fusionSetMagTrust(fusion, NORMAL);
        fusion->lastMagInvalid = true;
        return -EINVAL;
    }

    if (fusion->lastMagInvalid) {
        fusion->lastMagInvalid = false;
        fusionSetMagTrust(fusion, BACK_TO_VALID);
    }

    struct Vec3 north;
    vec3Cross(&north, &up, &east);

    float invNorm = 1.0f / vec3Norm(&north);
    vec3ScalarMul(&north, invNorm);

    float p = fusion->param.mag_stdev;

    if (fusion->flags & FUSION_USE_GYRO) {
        struct Vec3 mm;
        mat33Apply(&mm, &R, &fusion->Bm);
        float cos_err = vec3Dot(&mm, &north);

        if (fusion->trustedMagDuration > 0) {
            // if the trust mag time period is not finished
            if (cos_err < (1.f - MAG_COS_CONV_FACTOR/4)) {
                // if the mag direction and the fusion north has not converged, lower the
                // standard deviation of mag to speed up convergence.
                p *= MAG_STDEV_REDUCTION;
                fusion->trustedMagDuration -= dT;
            } else {
                // it has converged already, so no need to keep the trust period any longer
                fusionSetMagTrust(fusion, NORMAL);
            }
        } else {
            cos_err = cos_err < (1.f - MAG_COS_CONV_FACTOR) ?
                (1.f - MAG_COS_CONV_FACTOR) : cos_err;

            float fc;
            fc = (1.f - cos_err) * (1.0f / MAG_COS_CONV_FACTOR * MAG_COS_CONV_LIMIT);
            p *= expf(-fc);
        }
    }

    fusionUpdate(fusion, &north, &fusion->Bm, p);

    return 0;
}

void fusionSetMagTrust(struct Fusion *fusion, int mode) {
    switch(mode) {
        case NORMAL:
            fusion->trustedMagDuration = 0; // disable
            break;
        case INITIALIZATION:
        case BACK_TO_VALID:
            fusion->trustedMagDuration = 0; // no special treatment for these two
            break;
        case MANUAL_MAG_CAL:
            fusion->trustedMagDuration = TRUST_DURATION_MANUAL_MAG_CAL;
            break;
        default:
            fusion->trustedMagDuration = 0; // by default it is disable
            break;
    }
}

void fusionGetAttitude(const struct Fusion *fusion, struct Vec4 *attitude) {
    *attitude = fusion->x0;
}

void fusionGetBias(const struct Fusion *fusion, struct Vec3 *bias) {
    *bias = fusion->x1;
}

void fusionGetRotationMatrix(const struct Fusion *fusion, struct Mat33 *R) {
    quatToMatrix(R, &fusion->x0);
}
