Este artículo es una traducción de Día 5: Giroscopio, puedes encontrar aquí la versión original en inglés.

dia5

Hoy vamos a hablar acerca de un nuevo sensor disponible para nosotros, el giroscopio. Este sensor esta solo disponible en teléfonos que fueron lanzados después del lanzamiento de Mango, e incluso ahora, no todos los teléfonos tendrán uno. Sin embargo, es una herramienta poderosa de la cual nosotros podríamos tener ventaja cuando esté disponible y en este artículo te explicaré porque.

Si tu tienes un dispositivo que contenga un sensor de giroscopio, puedes descargar la aplicación de este artículo desde el Windows Phone Marketplace.

¿Qué es un giroscopio?

De acuerdo a Wikipedia, “un giroscopio es un dispositivo utilizado para medir o mantener la orientación”. Muchos de ustedes probablemente han visto un ejemplo de un giroscopio anteriormente, pero aquí está una ilustración de un giroscopio físico (Cortesía de Wikipedia).

220px-Gyroscope_operation

Como puedes ver, tiene la habilidad de girar en tres ejes, el eje X, Y y Z (muy parecido al acelerómetro, el cual cubrí en el Día 11 de 31 días de Windows Phone). Mientras que el acelerómetro mide la aceleración, el giroscopio mide la velocidad rotacional.

Una vez habiendo dicho esto, sin embargo, no hay un dispositivo en tu teléfono que se vea como el que está ilustrado arriba. En su lugar, los teléfonos móviles usan un giroscopio MEMS, el cual comúnmente utiliza vibraciones o resonancia para determinar su información.

 

Usando el giroscopio en tu aplicación.

El sensor del giroscopio es tan sencillo de usar como el acelerómetro, pero no tenemos aún el beneficio adicional de las herramientas en el emulador. La información que tu recibes, mide la velocidad rotacional del dispositivo en radianes por segundo.

Esto significa que tu puedes medir de manera mas acertada y pulida la orientación del dispositivo. Esto se volverá especialmente útil cuando construyas aplicaciones que trabajen con realidad aumentada. En la mayoría de los casos, sin embargo, tu probablemente no vas a estar accesando al giroscopio por sí mismo. Y hay un par de razones para ello.

No todos los Windows Phone tendrán un giroscopio. De hecho, solo los teléfonos que vienen después del lanzamiento de Mango, serán capaces de tener un giroscopio, y este sigue siendo una pieza de hardware opcional.

Microsoft ha creado una clase llamada Motion que combina la información  del acelerómetro, la brújula y el giroscopio en una clase que nosotros podemos usar mas efectivamente (cubriremos este tema en el artículo de mañana).  Si tu estás interesado en la actitud del dispositivo (inclinación, desplazamiento, rotación), debes enfocarte en la clase Motion.

De acuerdo, en caso de que tu necesites usar el giroscopio independientemente de la clase Motion, este debería siempre estar envuelto por un checador para determinar que el el dispositio soporte el sensor. Para esto, necesitamos dos piezas de código específicas. La primera es una sentencia using para el nombre de espacio Microsoft.Phone.Sensors. La segunda es una sentencia IF que checa el valor del Giroscopio.IsSupported. En este estado simple, tu código C# parecería algo así.

 

using System;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;

namespace Dia_5_Giroscopio
{
public partial class MainPage : PhoneApplicationPage
{
Gyroscope giro;

public MainPage()
{
InitializeComponent();

if (Gyroscope.IsSupported)
{
//HACER ALGO
}

}
}
}

Ahora solo necesitamos llenar el espacio de “Hacer algo”. Para hacer esto, vamos a comenzar con una nueva interfaz de usuario que mostrará la información del giroscopio.

image20

 

En la UI de arriba, tenemos tres TextBox para mostrarnos la información, y tres líneas para reflejar el grado de cada valor. Para recrear esta interfaz, utiliza el siguiente XAML como tu página.

<Grid x:Name=”LayoutRoot” Background=”Transparent”>
<Grid.RowDefinitions>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”*”/>
</Grid.RowDefinitions>

<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>
<TextBlock x:Name=”ApplicationTitle” Text=”LA LIGA SILVERLIGHT” Style=”{StaticResource PhoneTextNormalStyle}”/>
<TextBlock x:Name=”PageTitle” Text=”giroscopio” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}”/>
</StackPanel>

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<TextBlock Height=”30″ HorizontalAlignment=”Left”  Margin=”20,100,0,0″ Name=”txtEjeX” Text=”X: 1.0″ VerticalAlignment=”Top” Foreground=”Red” FontSize=”28″ FontWeight=”Bold”/>
<TextBlock Height=”30″ HorizontalAlignment=”Center”  Margin=”0,100,0,0″ Name=”txtEjeY” Text=”Y: 1.0″ VerticalAlignment=”Top” Foreground=”Yellow” FontSize=”28″ FontWeight=”Bold”/>
<TextBlock Height=”30″ HorizontalAlignment=”Right”  Margin=”0,100,20,0″ Name=”txtEjeZ” Text=”Z: 1.0″ VerticalAlignment=”Top”  Foreground=”Blue” FontSize=”28″ FontWeight=”Bold”/>
<Line x:Name=”lineaX” X1=”240″ Y1=”350″ X2=”340″ Y2=”350″ Stroke=”Red” StrokeThickness=”4″></Line>
<Line x:Name=”lineaY” X1=”240″ Y1=”350″ X2=”240″ Y2=”270″ Stroke=”Yellow” StrokeThickness=”4″></Line>
<Line x:Name=”lineaZ” X1=”240″ Y1=”350″ X2=”190″ Y2=”400″ Stroke=”Blue” StrokeThickness=”4″></Line>
<TextBlock Height=”30″ HorizontalAlignment=”Center” Margin=”6,571,6,0″ Name=”txtStatus” Text=”" VerticalAlignment=”Top” Width=”444″ />
</Grid>
</Grid>

En el código de ejemplo de abajo, nosotros creamos un nuevo objeto de tipo Gyroscope, y después de verificar para asegurarnos que el giroscopio es soportado con el valor booleano Gyroscope.IsSupported, nosotros creamos un manejador de eventos para CurrentValueChanged.

using System;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;

namespace Dia_5_Giroscopio
{
public partial class MainPage : PhoneApplicationPage
{
Gyroscope giro;

public MainPage()
{
InitializeComponent();

if (Gyroscope.IsSupported)
{
giro = new Gyroscope();
giro.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
giro.CurrentValueChanged += giro_CurrentValueChanged;
giro.Start();
}
else txtStatus.Text = “No existe soporte para el giroscopio”;
}

void giro_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e)
{
Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
}

private void UpdateUI(GyroscopeReading gyroscopeReading)
{
txtStatus.Text = “Obteniendo información”;
Vector3 rotationReading = gyroscopeReading.RotationRate;

txtEjeX.Text = “X ” + rotationReading.X.ToString(“0.00″);
txtEjeY.Text = “Y ” + rotationReading.Y.ToString(“0.00″);
txtEjeZ.Text = “Z ” + rotationReading.Z.ToString(“0.00″);

lineaX.X2 = lineaX.X1 + rotationReading.X * 200;
lineaY.Y2 = lineaY.Y1 – rotationReading.Y * 200;
lineaZ.X2 = lineaZ.X1 – rotationReading.Z * 100;
lineaZ.Y2 = lineaZ.Y1 + rotationReading.Z * 100;
}
}
}

 

El giroscopio, como la brújula, le permiten a nuestro manejador de eventos el lanzar cada vez que el giroscopio detecte un nuevo valor después de esperar por la duración que la propiedad TimeBetweenUpdates especifica. En nuestro ejemplo, nosotros obtendremos actualizaciones no mayores a 20 milisegundos.

Deberías notar posiblemente raro un fragmento de código en el método giro_CurrentValueChanged

Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));

La razón por la que usamos esto es porque nosotros queremos mover las lecturas de nuestro sensor a un hilo de procesamiento separado. Sin el, nosotros estaríamos tratando de utilizar el hilo de la UI para acceder al giroscopio, lo cual siempre lanzará un error. En Windows Phone, nosotros no somos capaces de obtenerlo desde el hilo de la UI, y para muchos ejemplos como este, vamos  querer tratar nuestro proceso a un hilo separado.

Nosotros aún pasamos el objeto de GyroscopeReading  nuestro nuevo método con un hilo que podamos usar, el método UpdateUI, el cual nos permite obtener cualquiera de los valores X, Y y Z del valor Vector3. Estamos desplegando los valores en TextBlocks, pero la visualización genial esta en los elementos de línea creados en nuestro XAML.

Si tu imaginas cada segmento de línea para representar un punto de información diferente (la roja horizontal es X, la amarilla vertical es Y, y la azul diagonal es el eje Z). Podrías entonces manipular la longitud de esas líneas para representar la velocidad rotacional del dispositivo. Cada uno de esos cálculos extenderá la longitud de sus líneas respectivas, dándote un ejemplo muy ilustrativo de que tipos de rotación esta experimentando tu dispositivo.

Recuerda, el código de ejemplo cubierto en este artículo solo trabajará con dispositivos que tengan un giroscopio disponible. El emulador, también como un Windows Phone 7 original no tiene este sensor. Aquí hay un video breve de como se ve la aplicación corriendo en un dispositivo con un giroscopio.

Puedes ver aquí el video.

En resumen.

El giroscopio es un muy útil y pequeño sensor. Te permite obtener una imagen muy acertada de el movimiento del dispositivo en el espacio, el cual es especialmente útil cuando se trata de aplicaciones de realidad aumentada. Para descargar la aplicación de ejemplo que utilizamos en este artículo, da clic en la línea siguiente.

Descarga aquí el código.

Microsoft también creó una nueva clase en Windows Phone 7.5 llamada Motion, la cual combina la información del giroscopio, acelerómetro y brújula para darnos un sorprendente monto de precisión. Esta clase Motion es el tema del artículo de mañana, y nosotros lo cubriremos en detalle, incluyendo como determinar la “actitud” del dispositivo, la cual incluye inclinación, desplazamiento y rotación. ¡Nos vemos!