Unity Spain

Post Antiguos => General (Antiguo) => Mensaje iniciado por: iRobb en Octubre 01, 2015, 07:36:21 PM

Título: Compass & Heading
Publicado por: iRobb en Octubre 01, 2015, 07:36:21 PM
Hola a todos! Hacía tiempo que no planteaba una pregunta. Ya toca!Estoy tratando de conseguir el heading (true, orientado al N, no al magnético) a través de las funciones de Unity y me encuentro con un montón de problemas paralelos.Según la documentación y la puesta en práctica, el trueHeading es el valor en ángulos del vector respecto al N que surge de la parte superior del móvil puesto en vertical. Si yo apunto con él al N mirándolo de cara me da 0 grados. BienAhora bien, si yo muevo el teléfono en cualquier ángulo, rotándolo p.ej., al ser un vector respecto a, el valor de trueHeading comienza a cambiar ya que el vector cambia. Como es lógico.Según he estado encontrando por mil sitios, se recomienda utlizar el resto de sensores (gyro, acelerómetro) para compensar los valores y tratar de obtener un valor adecuado. Bueno vale, pensé, dicho y hecho. Pero es que los valores devuelven una cantidad de ruido de espanto. Desde otros sitios leo que recomiendan aplicar un filtro de Kalman a los resultados debido a esto. Otros sitios que los chipsets son tan sofisticados que ya lo llevan aplicado, con creces y mejores variaciones del algoritmo.Pues no sé por donde continuar. Si alguien ha trabajado con el valor del trueHeading en aplicaciones serias, me podría echar una mano? Una orientación de qué tipo de sensores utilizar y, si debo aplicar o no filtros y de qué tipo.Muchas gracias a todos!   
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 02, 2015, 01:01:14 PM
Interesante, voy a investigar. ..En la documentación no habla nada del ruido ni de aplicar un filtro para el cálculo del true heading, solo indica que también se debe iniciar la actualización de la ubicación llamando a  Input.location.Start()
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 02, 2015, 02:10:33 PM
Sin embargo,  leyendo esto:http://developer.android.com/guide/topics/sensors/sensors_overview.html#sensors-configs veo que el  calculo del rumbo del sensor magnético es dejado netamente al hardware, entonces es deducible que su error también va a depender de este.Por ahí en algunos app indican mover el dispositivo en forma de 8 para calibrar el compás interno.También interesante sería el averiguar un poco más de como aplicar una corrección al compás, supongo que para eso unity usa esta función:

Compass.headingAccuracy

Título: Compass & Heading
Publicado por: iRobb en Octubre 02, 2015, 02:36:41 PM
El heading accuracy devuelve 0 en mi s4, o sea que no lo soporta. Supongo que la mayoría. Lo de calibrarlo moviéndolo lo he hecho y lo del location además del compass también. En general los valores son dispares a veces y a veces no. Yo que me muevo por patrones, me vuelve loco. Puede estar registrando el 0 grados norte, moverlo 45 grados e indicar 0 norte igual. En otro momento, lo indica bien. Sé que influyen todos los ejes, pero esto parece ridículo. Añadí una flecha de compass que me indica exactamente donde debo apuntar, así y todo, da extraños valores a veces.Lo de los filtros es por la cantidad de ruido (un lowpass como mínimo habría que añadir). Puedes ver bailar los valores a una velocidad tremenda entre dos o tres decimales. Para que sea práctico, le llego a aplicar hasta variaciones de 5 grados.Gracias por el interés. Puedes probarlo tu mismo, es sencillo. Sino, te paso un código de base. 
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 02, 2015, 02:37:55 PM
En el avión se usa la variación magnética para calcular el true heading, esta variación es el ángulo formado entre el norte geográfico, el norte magnético,  y la posición actual de el avión en el mundo. Si tienes alguna aplicación de prueba, y si lo deseas puedes pasarmela para comparar sus lecturas con los instrumentos del avión,  sin embargo también puedes hacer el procedimiento de calibración (compass swing), tu mismo, lo recomendable es usar un compás maestro,  e ir rotando cada 30° y anotar la desviación comparándola entre ambos luego de esperar un tiempo de estabilización. (El dispositivo móvil y el compás maestro).También es necesario que no haya interferencias como las producidas por construcciones o herramientas, en el caso de las construcciones, lo mínimo recomendable es que estén alejadas del lugar de pruebas unos 300 mts mínimo,  por esto muchas veces hacemos el compass swing en vuelo, sale muy caro  
También tenemos un compás maestro que induce una señal sobre el compás magnético y no es requerido el salir a volar, y se puede usar bajo techo. 
Título: Compass & Heading
Publicado por: iRobb en Octubre 02, 2015, 02:42:58 PM
Hago pruebas fuera tambíén (aunque debería hacer más). Estoy rodeado de wifis, hd's, monitores, amplificadores, altavoces, transformadores de 12v, en fin. Ahora en serio, ya te pasaré algo sencillo para que se pueda toquetear fácilmente. Y si averiguas algo, genial!
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 02, 2015, 02:50:26 PM
[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="27938" data-ipsquote-contentcommentid="115513">Hago pruebas fuera tambíén (aunque debería hacer más). Estoy rodeado de wifis, hd's, monitores, amplificadores, altavoces, transformadores de 12v, en fin. Ahora en serio, ya te pasaré algo sencillo para que se pueda toquetear fácilmente. Y si averiguas algo, genial![/quote]jajajaja la desventaja del avance tecnológico.  :) Título: Compass & Heading
Publicado por: iRobb en Octubre 02, 2015, 03:03:21 PM
Sabía que tenías algo que ver
Título: Compass & Heading
Publicado por: iRobb en Octubre 03, 2015, 02:28:13 AM
Ya he encontrado la solución!
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 03, 2015, 07:04:21 AM
Ciertamente requiere de atención,  ya que he probado con un script hecho netamente con el manual de Unity y en ambos heading indica el mismo rumbo,  comparado a los indicadores del avión el desface es mínimo, máximo 2°, desde mi posición geográfica es muy difícil percibir la diferencia entre los heading, esto debido a la distancia que hay entre en mag north,, el true north ,  y mi present position, por ejemplo uno de los aviones me indicaba 355° mag y 358° true, el teléfono móvil 358° en ambos,  en otro avión 40° mag y 38° true, el teléfono móvil 40° en ambos heading. Y con respecto a la posición geográfica el desface era de unos 15 o 20mts, en general normal para un sistema menos certero. [quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="27938" data-ipsquote-contentcommentid="115656">Ya he encontrado la solución![/quote]Tal vez lo que encontraste pueda sacar la respuesta definitiva de si las indicaciones eran true o mag en el móvil, así nada mas ( como esta puesto en el manual de unity) o si realmente requiere de una corrección. Me hubiera gustado tener un avión apuntando a cada punto cardinal, pero me salio trabajo extra en un avión,  jajaja   <_< Título: Compass & Heading
Publicado por: iRobb en Octubre 03, 2015, 09:48:13 AM
Espera, espera, que pare la música. Mi problema no es la diferencia entre el magnético y en el N geográfico. Mi problema es que al leer el trueheading no hay mucha precisión al ir cambiando de orientación. O sea:- Coger el móvil y apuntar a 0 grados.- Girar 45 grados a la derecha, y a veces dar lo mismo, o sea casi 0 o 358 gradosTu has conseguido que la medida sea coherente entonces?Saludos
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 03, 2015, 06:54:44 PM
Según las pruebas es coherente solo en los polos N y S, pero en E y W es sospechoso,  pareciera apuntar en los 90° y los 270° en una dirección mas cerca de los 45° y 315°, por eso requiere atención en esos polos, en ocasiones he reparado algunos compaces magnéticos con este tipo de falla, pero por la construcción del móvil podría deberse a interferencia en el flujo magnético producto de alguna instalación cercana. Simplemente podría requerir de algún script para compensar en esos polos, o mi teléfono móvil posee un sensor de flujo magnético dañado ya que otra aplicación que instalé da el mismo problema. Igual me interesa ver la solución que posees, tal vez mi script y la aplicación que descargue estan mal el Smart Tools.
Por cierto siempre tengo que calibrar el móvil antes de iniciar las pruebas,  luego trabaja de la forma que te describí,  no trabaja de otra forma siempre igual. 
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 03, 2015, 07:43:23 PM
Se me olvidaba mencionar que también en mi dispositivo el heading accuracy devuelve 0 igual al tuyo.
Título: Compass & Heading
Publicado por: iRobb en Octubre 03, 2015, 08:57:29 PM
Toda vía no lo tengo conseguido a la práctica, pero creo que la teoría de mi solución es correcta. Te cuento.Inicialmente yo obtenía una localización basándome en mi posición GPS y el objetivo, utilizando la distancia total respecto al destino + el bearing o ángulo respecto al destino. Este dato me lo guardaba y luego al dibujarlo, colocaba el destino basándome en los datos anteriores y mi orientación de compass, escalado en un minimap. Que ocurre cuando la lectura de compass es mala? Que todo se va al garete. Nada funciona y comienza y a bailar. Terrible.Objetivo: No depender del compass prácticamente para nada.Segunda solución. Obtener la distancia de dos puntos GPS tanto en la latitud, como en la longitud. Sin ángulo. Luego dibujarlos en el minimap a escala basándome solamente en la distancia (son dos ejes, es fácil), solo que las distancias está calculado por harvesine.Que me falta ahora... Pues rotar el minimap basándome en el giroscopio, obteniendo valores puntuales del compass que sean coherentes para corregir la rotación. En ello estoy. Si lo consigo, tendré un compass tremendamente fiable y prácticamente sin interferencias de campos magnéticos. 
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 04, 2015, 05:18:03 AM
[quote author=iRobb date=1443898649" data-ipsquote="" data-cite="iRobb">Toda vía no lo tengo conseguido a la práctica, pero creo que la teoría de mi solución es correcta. Te cuento.Inicialmente yo obtenía una localización basándome en mi posición GPS y el objetivo, utilizando la distancia total respecto al destino + el bearing o ángulo respecto al destino. Este dato me lo guardaba y luego al dibujarlo, colocaba el destino basándome en los datos anteriores y mi orientación de compass, escalado en un minimap. Que ocurre cuando la lectura de compass es mala? Que todo se va al garete. Nada funciona y comienza y a bailar. Terrible.Objetivo: No depender del compass prácticamente para nada.Segunda solución. Obtener la distancia de dos puntos GPS tanto en la latitud, como en la longitud. Sin ángulo. Luego dibujarlos en el minimap a escala basándome solamente en la distancia (son dos ejes, es fácil), solo que las distancias está calculado por harvesine.Que me falta ahora... Pues rotar el minimap basándome en el giroscopio, obteniendo valores puntuales del compass que sean coherentes para corregir la rotación. En ello estoy. Si lo consigo, tendré un compass tremendamente fiable y prácticamente sin interferencias de campos magnéticos. [/quote]Entiendo que quieres triangular la posición del norte magnético?o tal vez requires la posición aproximada del norte magnético, este sistema de navegación seria dependiente de la actualización de su ubicación, si es así puedes ver este link:http://wdc.kugi.kyoto-u.ac.jp/poles/polesexp.html (http://wdc.kugi.kyoto-u.ac.jp/poles/polesexp.html) Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 04, 2015, 09:57:55 AM
Justamente, Unity recibe la señal del sensor de flujo magnético con muchísima interferencia y no la atenúa, luego cree unas funciones para atenuar algo la señal que le paso al puntero de una brújula de pruebas, esto disminuyendo la velocidad del puntero al acercarse al heading que debe mostrar.tal vez si no leo una vez por frame la señal se estabilice mas.ese ruido hace que la indicación oscile a veces unos 10 grados,  estoy pensando seriamente lo del Filtro de Kalman, sin embargo nunca he hecho tal cosa CompassOakAndroid.apk
Cita de: iRobb date=1443898649" data-ipsquote="" data-cite="iRobb Que me falta ahora... Pues rotar el minimap basándome en el giroscopio, obteniendo valores puntuales del compass que sean coherentes para corregir la rotación. En ello estoy. Si lo consigo, tendré un compass tremendamente fiable y prácticamente sin interferencias de campos magnéticos. 
si creas un sistema de navegación sin usar el flujo magnético, Incluso serviría para navegar cerca de los polos... los aviones que navegan cerca de los polos se desconectan de la señal entregada por sensores de flujo magnético, esto debido a el desorden que existe en las líneas de fuerza del flujo magnético terrestre a altas latitudes.
En los sistemas mas avanzados de navegación en aviación comercial se usan los inerciales, los cuales poseen sensores con laser... son capaces hasta de calcular la velocidad de rotación de la tierra durante un tiempo de inicialización que esta entre unos 7 a 10 minutos, luego a estos se les entrega la posición inicial (de GPS o manualmente) y desde ahi comienzan a navegar por si mismos (sin GPS) usando una base de datos que contiene un mapa mundial y sus GyroLaser, acelerómetros y quien sabe que mas escondido
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 01:18:02 AM
Vale, te cuento. No te lo vas a creer. Estaba con código que compensa el compass, el giróscopo, bla bla. No había manera, ninguna de que fuera algo fiable. Había tomado nota de donde estaba el N antes con el maps. Nada encender y apagarlo. Y como estaba ya totalmente mosca, me he instalado una brújula. Nada. No funcionaba tampoco. Daba los mismo giros que en mi código a lo loco. Y pienso, esto ya es de manicomio.Busco por Internet y... el Samsung S4 no viene con el compass calibrado de fábrica. Hay un montón de vídeos que te explican como hacerlo con una app gratuita. Lo saco de la funda, calibro y pam! Brújula funcionando. Te lo puedes creer? Siempre me ha estado funcionando el código. Donde está el icono de llorar, pues este 
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 03:09:52 AM
Luego de un rato, ha dejado de funcionar. Así que he repasado mi proceso, paso por paso. No es solamente el calibrado (o a lo mejor ni ha influido) sino, la funda! Meter el móvil en la funda con gps, compass, acelerómetro, bla bla bla es una auténtica barbaridad.Como lo saqué de la funda para calibrarlo, pensé que era eso. Al volverlo a meter y probar, todo mal. Y pensando, pues, la fuuuuundaaaaaaa de los chinos (realmente es de El Corte Inglés, pero es que parece de los chinos). Ahora he probado, reprobado y creo que lo tengo comprobado.Y lo bestial es que ahora, al mover arriba y abajo (y) no me afecta en la z. Te puedes creer como de increíble ha cambiado todo. Antes en la funda, mueves en un eje y te afecta a todos, sea acelerómetro, compass o lo que quieras. Por eso no entendía ni papa.
De todos modos, no todo ha sido tiempo perdido. Al final hice el código de compass con compensación por giroscopio, o sea, no tomo el truehading a saco y ya está. Eso ayuda a compensar movimientos bruscos a través del giroscopio y que no le afecten al compass, sino suave con un slerp.
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 03:19:13 AM
Yo acabo de probar mi aplicación a campo traviesa y funciona perfectamente,  pero no hago más que  acercarme a un edificio o dentro de mi automóvil y apunta a cualquier parte, es muy susceptible a interferencias. 
Dentro del automóvil apunta hacia mi radio, le encanta la música 
Dentro del automóvil apunta hacia mi radio, le encanta la música 
Y por que salio dos veces eso?
En otras palabras funciona como un compás magnético
Por que ya se me esta ocurriendo instanciar un objeto en la posición del norte y usarlo para el heading.
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 03:54:00 AM
Claro, es eso. Utilizas los tres ejes para rotar o solo en z? Que te paso el código de rotación.
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 04:55:34 AM
Solo roto usando el eje Y,
void PointerMotion (Transform pointerRx, Vector3 pointerRotationRx)
{
   smoothSpeed = Mathf.DeltaAngle(pointerRx.localEulerAngles.y, pointerRotationRx.y);
   if (smoothSpeed < 0) {
      smoothSpeed *= -1;
   }

   smoothSpeed *= pointerSpeed;
   if (smoothSpeed < nullPointerRange) {
      smoothSpeed = nullPointerSpeed;
   }
   // Orient at the pointerRx
   pointerRx.localRotation =
      Quaternion.Euler(pointerRotationRx.x,
           Mathf.MoveTowardsAngle(pointerRx.localEulerAngles.y, pointerRotationRx.y, smoothSpeed * Time.deltaTime),
           pointerRotationRx.z);
}
pero se ve que es fácilmente modificable
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 05:12:09 AM
Lo encontré en Internet e hice mis variaciones. Siempre comento en inglés. Está adaptado para que rote en z con el eje y. Eso lo verás fácil.Está un poco guarri porqué lo hice esta noche y tal como funcionó lo dejé de cara a mañana.
    private void Update() {
        // The gyro is very effective for high frequency movements, but drifts its
        // orientation over longer periods, so we want to use the compass to correct it.
        // The iPad's compass has low time resolution, however, so we let the gyro be
        // mostly in charge here.

        // First we take the gyro's orientation and make a change of basis so it better
        // represents the orientation we'd like it to have
        Quaternion gyroOrientation = Quaternion.Euler(90, 0, 0) * Input.gyro.attitude * Quaternion.Euler(0, 0, 90);

        // See if the compass has new data
        if (Input.compass.timestamp > _lastCompassUpdateTime) {
            _lastCompassUpdateTime = Input.compass.timestamp;

            // Work out an orientation based primarily on the compass
            Vector3 gravity = Input.gyro.gravity.normalized;
            Vector3 flatNorth = Input.compass.rawVector - Vector3.Dot(gravity, Input.compass.rawVector) * gravity;
            _compassOrientation = Quaternion.Euler(180f, 0f, 0f) * Quaternion.Inverse(Quaternion.LookRotation(flatNorth, -gravity)) * Quaternion.Euler(0f, 0f, 90f);

            // Calculate the target correction factor
            _targetCorrection = _compassOrientation * Quaternion.Inverse(gyroOrientation);
        }

        // Jump straight to the target correction if it's a long way; otherwise, slerp towards it very slowly
        if (Quaternion.Angle(_correction, _targetCorrection) > 45f)
            _correction = _targetCorrection;
        else
            _correction = Quaternion.Slerp(_correction, _targetCorrection, 0.02f);

        // Easy bit :)
        Quaternion q = _correction * gyroOrientation;
        // Only y value and 90 degrees. Can change before, but I prefer to do it afterwards. No correction is like a compass holding
        this.transform.localEulerAngles = new Vector3(0f, 0f, q.eulerAngles.y - 90f);

        //this.txtDebug.text = _compassOrientation.eulerAngles.ToString();
    }
 
Como puedes ver se calcula la orientación en base a un punto N y se aplica la corrección por gravedad. El rawVector es el magnetómetro. De este modo el up/down queda corregido. Y si el giro es superior a 45 pues el slerp. Si quieres todos los ejes, no apliques 0's al Vector3 del localrotation.Es muy estable.
Y los -90f son para tenerlo de cara (o sea en vertical). Si lo quieres en horizontal, elimina los -90f.
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 05:30:11 AM
Como inicializas el valor de _correction?
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 05:33:16 AM
Perdón. Todos son identities:   private double _lastCompassUpdateTime = 0;
    private Quaternion _correction = Quaternion.identity;
    private Quaternion _targetCorrection = Quaternion.identity;
    private Quaternion _compassOrientation = Quaternion.identity; 
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 05:42:03 AM
lo sospechaba, pero pensé que aplicabas una corrección diferente de 0. //this.transform.localEulerAngles = new Vector3(0f, 0f, q.eulerAngles.y - 90f);
   pointer2.localEulerAngles = new Vector3(0f, q.eulerAngles.y - 90f, 0f);Tks   
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 06:25:44 AM
Jajajaj me acabo d enterar que mi teléfono no tiene Sensor Gyroscopico , por lo cual el puntero 2 constantemente apunta a los 270 grados, el puntero 1 no se vio afectado y sigue funcionando tal como siempre.
aquí queda el Apk que cree para la posteridad
CompassiRobbOakAndroid.apk
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 08:13:10 AM
Por supuesto.
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 09:54:25 AM
Un poco mejor:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class cGyroManager : MonoBehaviour {
    [Tooltip("Below this angle a slerp will be done otherwise straight forward")]
    public float angleSlerp = 45f;
    [Tooltip("t value for Slerp")]
    [Range(0f, 1f)]
    public float angleSlerpClamp = 0.02f;
    public Text txtDebug;
   
    private bool _enable;

    private double _lastCompassUpdateTime = 0;
    private Quaternion _correction = Quaternion.identity;
    private Quaternion _targetCorrection = Quaternion.identity;
    private Quaternion _compassOrientation = Quaternion.identity;
    private Quaternion _gyroOrientation = Quaternion.identity;
    private Quaternion _finalOrientation = Quaternion.identity;
    private Vector3 _flatNorth;
    private Vector3 _gravity;
   
    /// <summary>
    ///  Method to initalize the gyro at start of game
    /// </summary>
    private void Start() {
        this._enable = false;
    }

    public bool enable {
        get { return (this._enable); }
        set { this._enable = value; }
    }

    private void Update() {
        if (this._enable == true) {
            this.set();
        }
    }

    public Vector3 flatNorth {
        get { return (this._flatNorth); }
    }

    public Vector3 gravity {
        get { return (this._gravity); }
    }

    public Quaternion compassOrientation {
        get { return (this._compassOrientation); }
    }

    public Quaternion gyroOrientation {
        get { return (this._gyroOrientation); }
    }

    private void set() {
        // The gyro is very effective for high frequency movements, but drifts its
        // orientation over longer periods, so we want to use the compass to correct it.
        // The iPad's compass has low time resolution, however, so we let the gyro be
        // mostly in charge here.

        // First we take the gyro's orientation and make a change of basis so it better
        // represents the orientation we'd like it to have
        this._gyroOrientation = Quaternion.Euler(90f, 0f, 0f) * Input.gyro.attitude * Quaternion.Euler(0f, 0f, 90f);

        // See if the compass has new data
        if (Input.compass.timestamp > this._lastCompassUpdateTime) {
            this._lastCompassUpdateTime = Input.compass.timestamp;

            // Work out an orientation based primarily on the compass
            this._gravity = Input.gyro.gravity.normalized;
            this._flatNorth = Input.compass.rawVector - Vector3.Dot(this._gravity, Input.compass.rawVector) * this._gravity;
            this._compassOrientation = Quaternion.Euler(180f, 0f, 0f) * Quaternion.Inverse(Quaternion.LookRotation(this._flatNorth, -this._gravity)) * Quaternion.Euler(0f, 0f, 90f);

            // Calculate the target correction factor
            this._targetCorrection = this._compassOrientation * Quaternion.Inverse(this._gyroOrientation);
        }

        // Jump straight to the target correction if it's a long way; otherwise, slerp towards it very slowly
        if (Quaternion.Angle(this._correction, this._targetCorrection) > this.angleSlerp)
            this._correction = _targetCorrection;
        else
            this._correction = Quaternion.Slerp(this._correction, this._targetCorrection, this.angleSlerpClamp);

        // Easy bit :)
        this._finalOrientation = this._correction * this._gyroOrientation;
        // Only y value and 90 degrees. Can change before, but I prefer to do it afterwards. No correction is like a compass holding
        this.transform.localEulerAngles = new Vector3(0f, 0f, this._finalOrientation.eulerAngles.y - 90f);

        //this.txtDebug.text = this.flatNorth.ToString();
    }
}
 
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 02:34:42 PM
[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="27938" data-ipsquote-contentcommentid="116123">Un poco mejor:
using UnityEngine;using UnityEngine.UI;
using System.Collections;

public class cGyroManager : MonoBehaviour {
    [Tooltip("Below this angle a slerp will be done otherwise straight forward")]
    public float angleSlerp = 45f;
    [Tooltip("t value for Slerp")]
    [Range(0f, 1f)]
    public float angleSlerpClamp = 0.02f;
    public Text txtDebug;
   
    private bool _enable;

    private double _lastCompassUpdateTime = 0;
    private Quaternion _correction = Quaternion.identity;
    private Quaternion _targetCorrection = Quaternion.identity;
    private Quaternion _compassOrientation = Quaternion.identity;
    private Quaternion _gyroOrientation = Quaternion.identity;
    private Quaternion _finalOrientation = Quaternion.identity;
    private Vector3 _flatNorth;
    private Vector3 _gravity;
   
    /// <summary>
    ///  Method to initalize the gyro at start of game
    /// </summary>
    private void Start() {
        this._enable = false;
    }

    public bool enable {
        get { return (this._enable); }
        set { this._enable = value; }
    }

    private void Update() {
        if (this._enable == true) {
            this.set();
        }
    }

    public Vector3 flatNorth {
        get { return (this._flatNorth); }
    }

    public Vector3 gravity {
        get { return (this._gravity); }
    }

    public Quaternion compassOrientation {
        get { return (this._compassOrientation); }
    }

    public Quaternion gyroOrientation {
        get { return (this._gyroOrientation); }
    }

    private void set() {
        // The gyro is very effective for high frequency movements, but drifts its
        // orientation over longer periods, so we want to use the compass to correct it.
        // The iPad's compass has low time resolution, however, so we let the gyro be
        // mostly in charge here.

        // First we take the gyro's orientation and make a change of basis so it better
        // represents the orientation we'd like it to have
        this._gyroOrientation = Quaternion.Euler(90f, 0f, 0f) * Input.gyro.attitude * Quaternion.Euler(0f, 0f, 90f);

        // See if the compass has new data
        if (Input.compass.timestamp > this._lastCompassUpdateTime) {
            this._lastCompassUpdateTime = Input.compass.timestamp;

            // Work out an orientation based primarily on the compass
            this._gravity = Input.gyro.gravity.normalized;
            this._flatNorth = Input.compass.rawVector - Vector3.Dot(this._gravity, Input.compass.rawVector) * this._gravity;
            this._compassOrientation = Quaternion.Euler(180f, 0f, 0f) * Quaternion.Inverse(Quaternion.LookRotation(this._flatNorth, -this._gravity)) * Quaternion.Euler(0f, 0f, 90f);

            // Calculate the target correction factor
            this._targetCorrection = this._compassOrientation * Quaternion.Inverse(this._gyroOrientation);
        }

        // Jump straight to the target correction if it's a long way; otherwise, slerp towards it very slowly
        if (Quaternion.Angle(this._correction, this._targetCorrection) > this.angleSlerp)
            this._correction = _targetCorrection;
        else
            this._correction = Quaternion.Slerp(this._correction, this._targetCorrection, this.angleSlerpClamp);

        // Easy bit :)
        this._finalOrientation = this._correction * this._gyroOrientation;
        // Only y value and 90 degrees. Can change before, but I prefer to do it afterwards. No correction is like a compass holding
        this.transform.localEulerAngles = new Vector3(0f, 0f, this._finalOrientation.eulerAngles.y - 90f);

        //this.txtDebug.text = this.flatNorth.ToString();
    }
}
 [/quote]Mucho mas ordenado , pero sigo sin giroscopio, mi teléfono no tiene el hardware, existirá una solución para la compensación?, voy a buscar por ahí,  ya que tengo un GPS que funciona perfecto, pero tengo que empezar a moverme para que calcule bien la dirección.
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 08:13:38 PM
Me la he instalado y probado tu app, y no me da la misma orientación al N. Me da como unos 20 grados este respecto al N (no magnético).
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 09:58:01 PM
En mi app, El puntero delgado es el que utiliza netamente la librería de Unity para obtener el true heading o el magnetic heading, según la selección en el GUI, el puntero grueso posee el script que me pasaste y es el que utiliza el giroscopio para estabilización.Ahora recuerdo los sistemas de compás de los aviones más antiguos que utilizaban una valvula deflujo magnetico para detectar la posición del Norte magnetico y un gyro direccional para la estabilización, ademas algunos tenían la posibilidad de poder compensarlos en los puntos cardinales N - S o E - W. La gracia de algunos de estos sistemas era que poseían un switch el cual tenia dos posiciones una de ellas era para obtener el N desde la válvula de flujo magnético y la otra era para desconectar la señal proveniente de dicha valvula para volar sobre los polos, quedaba solo el directional gyro entregando la información de heading, pero el directional gyro para poder entregar el heading tenia que previamente haber recibido tal información desde la flux valve o manualmente, luego cada cierto tiempo habia que corregir el rumbo debido a desviaciones propias del directional gyro. Tal vez el gyro de los teléfonos sea una tecnología mas avanzada que esta pero con la misma teoria.Por cierto al abrir mi app el puntero delgado muestra el true heaging usando la documantacion de Unity.
Título: Compass & Heading
Publicado por: iRobb en Octubre 05, 2015, 10:03:37 PM
Me ha encantado. Que nivel. Y hablando de válvulas! Me recuerda cuando leí sobre el radar del mig-25 y que tenían que asegurarse de tenerlo apagado al repostar para no provocar incendios  
Título: Compass & Heading
Publicado por: Oak Human Flesh en Octubre 05, 2015, 11:23:16 PM
Imaginar el aparato microondas domiciliario no es muy descabellado a esas frecuencias y potencias,  en los aviones comerciales también es peligroso para la salud del que pase por delante de un avión con un radar irradiando. .. se dice que se empieza por quedar estéril