Question

Je dois écrire une application Compass dans Android. La seule chose que l'utilisateur voit à l'écran est un cube avec un mur rouge qui doit pointer vers le nord. Ce ne est pas important. Ce qui est important, c'est que je dois faire pivoter ce cube en conséquence à la rotation de l'appareil lui-même afin que la paroi rouge continue de pointer vers le nord, peu importe comment le téléphone est détenu. Mon code est simple et simple:

@Override
public void onSensorChanged(SensorEvent event) {
    synchronized (this) {
        switch (event.sensor.getType()){
        case Sensor.TYPE_ACCELEROMETER:
            direction = event.values[2];
            break;
        case Sensor.TYPE_ORIENTATION:
            if (direction < 0) {
                angleX = event.values[1];
                angleY = -event.values[2];
                angleZ = event.values[0];
            } else {
                angleX = -event.values[1];
                angleY = -event.values[2];
                angleZ = event.values[0];   
            }
            break;
        }
    }
}

J'ai ajouté cette variable de direction supplémentaire qui stocke simplement si l'affichage du téléphone pointe vers le bas ou vers le haut. Je ne sais pas si j'en ai besoin mais cela semble corriger certains bugs. J'utilise le Sensor-Wishator Pour Android, mais chaque fois que mon curseur de pitch va dans l'intervalle [-90, 90], les autres variables se mélangent. C'est comme s'ils obtenaient un décalage de 180. Mais je ne peux pas détecter quand je suis dans cet intervalle parce que la plage de la hauteur est de -90 à 90 afin que je puisse déplacer ce curseur de gauche à écrire et je serai toujours dans cet intervalle.

Tout cela était juste pour vous montrer jusqu'où mon code a-t-il progressé. Je ne dis pas comment ce problème devrait être résolu car je ne me remuerai probablement que dans une impasse. Vous voyez, j'essaie d'écrire cette application depuis 3 jours maintenant, et vous pouvez imaginer à quel point mon patron est énervé. J'ai lu toutes sortes de tutoriels et essayé toutes les formules que je pouvais trouver ou penser. Alors s'il vous plaît aidez-moi. Tout ce que j'ai à faire est de savoir faire tourner mon cube, dont les angles de rotation sont des angles d'Euler en degrés.

Était-ce utile?

La solution

Voici un code que j'ai écrit pour faire quelque chose d'assez similaire, ne se souciant vraiment que de la rotation de l'appareil dans la direction du roulis. J'espère que cela aide! Il utilise simplement les valeurs d'accéléromètre pour déterminer la hauteur, pas besoin d'obtenir l'orientation de la vue.

public void onSensorChanged(SensorEvent event) {
    float x = -1 * event.values[0] / SensorManager.GRAVITY_EARTH;
    float y = -1 * event.values[1] / SensorManager.GRAVITY_EARTH;
    float z = -1 * event.values[2] / SensorManager.GRAVITY_EARTH;

    float signedRawRoll = (float) (Math.atan2(x, y) * 180 / Math.PI);
    float unsignedRawRoll = Math.abs(signedRawRoll);
    float rollSign = signedRawRoll / unsignedRawRoll;
    float rawPitch = Math.abs(z * 180);

    // Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes
    // adjust the filter weight based on pitch, as roll is harder to define as pitch approaches 180.
    float filterWeight = rawPitch > 165 ? 0.85f : 0.7f;
    float newUnsignedRoll = filterWeight * Math.abs(this.roll) + (1 - filterWeight) * unsignedRawRoll;
    this.roll = rollSign * newUnsignedRoll;
    if (Float.isInfinite(this.roll) || Float.isNaN(this.roll)) {
        this.roll = 0;
    }
    this.pitch = filterWeight * this.pitch + (1 - filterWeight) * rawPitch;
    for (IAngleListener listener : listeners) {
        listener.deviceRollAndPitch(this.roll, this.pitch);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top