¿Cómo calcular la orientación de un sensor IMU?

2

Con un BLE CPro sensor estoy intentando "construir" un control remoto para un juego de teléfono inteligente. ¿Cómo puedo reconocer la orientación (pref. Grads) del sensor si está a la izquierda o a la derecha sin verse afectado por su gravedad? es decir, en un entorno sacudido / en movimiento?

Mi problema es que si calculo la orientación con el acelerómetro, cada vez que se agita el sensor, la gravedad cambia drásticamente, lo que dificulta conocer la orientación actual.

Este sensor de CPro ofrece un ejemplo sobre cómo calcular sus cuaterniones. Como salida, muestra un gráfico de cubo utilizando OpenGL ES que sigue la orientación / rotación del sensor. Lamentablemente no entiendo bien cómo puedo obtener de los cuaterniones la orientación de los graduados ...

//src https://github.com/mbientlab-projects/iOSSensorFusion/tree/master
- (void)performKalmanUpdate
{
    [self.estimator readAccel:self.accelData
                        rates:self.gyroData
                        field:self.magnetometerData];

    if (self.estimator.compassCalibrated && self.estimator.gyroCalibrated)
    {
        auto q = self.estimator.eskf->getState();
        auto g = self.estimator.eskf->getAPred();

        auto a = self.accelData;
        auto w = self.gyroData;

        auto mp = self.estimator.eskf->getMPred();
        auto m = self.estimator.eskf->getMMeas();

        _s->qvals[0] = q.a();
        _s->qvals[1] = q.b();
        _s->qvals[2] = q.c();
        _s->qvals[3] = q.d();

        //  calculate un-filtered angles
        float ay = -a.y;
        if (ay < -1.0f) {
            ay = -1.0f;
        } else if (ay > 1.0f) {
            ay = 1.0f;
        }
        _s->ang[1] = std::atan2(-a.x, -a.z);
        _s->ang[0] = std::asin(-ay);
        _s->ang[2] = std::atan2(m(1), m(0)); //  hack: using the filtered cos/theta to tilt-compensate here

        //  send transform to render view
        auto R = q.to_matrix();

        GLKMatrix4 trans = GLKMatrix4Identity;
        auto M = GLKMatrix4MakeAndTranspose(R(0,0), R(0,1), R(0,2), 0.0f,
                                            R(1,0), R(1,1), R(1,2), 0.0f,
                                            R(2,0), R(2,1), R(2,2), 0.0f,
                                            0.0f, 0.0f, 0.0f, 1.0f);

        trans = GLKMatrix4Multiply(trans, M);
        self.renderVC.cubeOrientation = trans;
    }
}
    
pregunta Pompeyo

1 respuesta

1

Como has descubierto, un acelerómetro de tres ejes solo te dirá la orientación cuando algo es básicamente estable. O, estable en promedio si puede tolerar una respuesta lenta debido al filtrado requerido para filtrar el componente vibrante de la señal. En cambio, para encontrar la orientación del sensor en tales condiciones, puede usar un giroscopio de 3 ejes, que no es muy sensible a la vibración, y tomar la integral de la velocidad de giro que da para encontrar la orientación, y corregir la deriva del giroscopio. utilizando algún tipo de información adicional, generalmente de acelerómetros y magnetómetros, que le proporcionan los vectores de la gravedad y el campo magnético de la tierra. Los esquemas de filtro de Kalman son comunes aquí.

Hoy en día, puede comprar sensores que hacen esto por usted y que generan los ángulos de Euler o una representación de cuaternión de la orientación del sensor con respecto a ser plana. Busque los sensores de unidad de medida inercial (IMU) que anuncian que tienen Sensor Fusion .

Su ejemplo de código anterior está haciendo esto, utilizando los otros sensores presentes en su sensor de CPro con un filtro de Kalman para obtener una mejor estimación de la orientación del sensor como un cuaternión, que luego se convierte en una matriz de transformación por la to_matrix () método. Puede encontrar más información sobre cómo convertir un cuaternión a los ángulos de Euler, que es lo que creo que quiere, de este artículo: Conversión entre quaternions y Euler Angles

    
respondido por el alexwarrior

Lea otras preguntas en las etiquetas