Accueil Nos publications Blog SDK Sphero – Part 2 – Les capteurs

SDK Sphero – Part 2 – Les capteurs

Logo Sphero

Il est temps d’aborder la deuxième partie de la série d’article initiée ici.

Dans cette partie, nous allons voir, qu’en plus d’envoyer des ordres à Sphero, nous pouvons également lire des informations envoyées par celui-ci.

Ce qui va nous permettre d’illustrer deux scénarios différents. Nous allons d’abord utiliser Sphero comme contrôleur, puis nous verrons comment détecter la collision de la boule avec son environnement.

Utiliser Sphero comme contrôleur

Sphero est équipé d’un accéléromètre et d’un gyroscope, qui pour rappel fournissent à eux deux les déplacements linéaire et angulaire d’un mobile (sphero dans notre cas). Les données brutes de ces capteurs peuvent être lues, mais sphero embarque également une centrale à inertie de type IMU (Inertial Measurement Unit), qui va nous simplifier la tâche pour obtenir la rotation de la boule sur 3 axes.

Comme pour la conduite on va tout d’abord commencer par une phase de calibrage. Pour cette phase nous allons réaliser une page intermédiaire qui demandera au joueur de mettre la lumière face à lui avec la partie lourde vers le bas. Un fois fait il aura juste à appuyer sur un bouton pour poursuivre :


<StackPanel HorizontalAlignment="Center">
   <TextBlock FontSize="26" TextWrapping="Wrap">Turn Sphero to put the blue light facing you with the heavy part below</TextBlock>
   <Button x:Name="btnCalibrationDone" Margin="0,20,0,0" Click="btnCalibrationDone_Click">Calibration done !</Button>
</StackPanel>

Ce qu’il est important de retenir dans le code-behind de cette page, c’est tout d’abord cette partie la dans le constructeur de la page :


// OFF Stabilization and set LEDs
_spheroDevice.StabilizationOFF();
_spheroDevice.SetRGBLED(0.5f, 0, 0);
_spheroDevice.SetBackLED(1.0f);

Le fait de désactiver la stabilisation est obligatoire pour avoir des données fiables des capteurs ( La stabilisation oblige les moteurs à se repositionner automatiquement, ce qui influe forcément sur les capteurs). Ensuite, on affiche la LED arrière et on change la couleur de la LED RGB pour être sur que la LED arrière soit visible.

La deuxième chose importante, sur cette page, est ce qu’il se passe lors de l’appuie sur le bouton :


// Initialize heading and go to the reading page
_spheroDevice.SetHeading(0);
NavigationService.Navigate(new Uri("/IMUReadingPage.xaml", UriKind.RelativeOrAbsolute));

On réinitialise l’origine, pour avoir des données relatives à cette position, et ensuite on navigue vers la page de lecture des données.

Dans la page suivante, nous allons ajouter 3 sliders pour représenter les 3 axes de rotations possibles :


 <StackPanel Orientation="Vertical">
      <TextBlock>Pitch :</TextBlock>
      <Slider x:Name="sldPitch" Foreground="Red" Minimum="-180" Maximum="180"></Slider>
      <TextBlock>Roll :</TextBlock>
      <Slider x:Name="sldRoll" Foreground="Green" Minimum="-180" Maximum="180"></Slider>
      <TextBlock>Yaw :</TextBlock>
      <Slider x:Name="sldYaw" Foreground="Blue" Minimum="-180" Maximum="180"></Slider>
</StackPanel>

Ce qui donnera le rendu suivant :

wp_ss_20140218_0001

Dans le constructeur de cette page, il va nous falloir demander à sphero de nous envoyer les données pour cela nous appelons :


// Initialize SensorData streaming Masks
_spheroDevice.SetDataStreaming(20, 1, Masks.FilteredIMU, 1);

Le premier paramètre N, est un diviseur de fréquence. La fréquence de base est 420Hz, donc avec la valeur de 20 dans l’exemple, nous aurons 420/20 soit environ 21 paquet par secondes. Le seconde paramètre M définit le nombre de trame par paquet (pour l’instant le SDK ne supporte qu’une valeur de 1).

Les deux derniers paramètres correspondent aux données que nous souhaitons recevoir. On peut utiliser les classes Sphero.Locator.Masks et Sphero.Locator.Masks2 pour fournir les masques nécessaires.

Il nous reste maintenant plus qu’à nous abonner à l’évènement qui permettra de lire les données :


// Subscribe to SensorData event
_spheroDevice.SensorDataNotification += _spheroDevice_SensorDataNotification;

Et enfin dans la méthode _spheroDevice_SensorDataNotification nous pouvons maintenant mettre à jour les sliders avec les données lues (en n’oubliant pas de se repositionner dans le thread UI) :


void _spheroDevice_SensorDataNotification(Sphero.Locator.SensorData data)
{
    // If IMU data are present
    if (data.FilteredIMU != null)
    {
        // Update Sliders with data on UI Thread
        Dispatcher.BeginInvoke(() =>
        {
            sldPitch.Value = data.FilteredIMU.Pitch;
            sldRoll.Value = data.FilteredIMU.Roll;
            sldYaw.Value = data.FilteredIMU.Yaw;
        });
       
    }
}

Vous retrouvez le code source de l’exemple ici.

Détection des collisions

Comme je vous l’ai dit en introduction, il est possible de détecter lorsque sphero rentre en collision avec un mur par exemple. Et vous allez voir que ce n’est vraiment pas compliqué. Pour simplifier la démonstration nous allons partir de l’exemple de conduite disponible ici, auquel on va ajouter la détection de collision en affichant dans la console de debug un texte lorsque celle-ci se produit.

Pour configurer la détection et nous y abonner ajoutons ces deux lignes dans le constructeur de la page DrivePage :


// Configure collision detection and subscribe to detection event
_spheroDevice.ConfigureCollisionDetection(CollisionMethod.Enable, 125, 125, 125, 125, 50);
_spheroDevice.CollisionDetected += _spheroDevice_CollisionDetected;

La méthode ConfigureCollisionDetection permet d’activer la détection des collisions, si son premier paramètre est différent de CollisionMethod.Disable. Les deux paramètres suivants permettent de définir le seuil et la vitesse de la détection sur l’axe X, et les deux suivants encore de définir le seuil et la vitesse de la détection sur l’axe Y. Le dernier paramètre définit, en dizaine de millisecondes, le temps minimum entre chaque détection.

Si vous souhaitez en savoir plus sur la détection de collision je vous invite à lire cette documentation.

Il nous reste maintenant plus qu’à définir la méthode qui gère la détection :


void _spheroDevice_CollisionDetected(CollisionData data)
{
    // Collision detected !
    Debug.WriteLine("Collision ! ");
}

Comme d’habitude, les sources de cet exemple sont disponible ici.

A bientôt

Je vous donne rendez vous dans quelques jours pour voir comment définir, stocker, et exécuter des macros au travers de Sphero.