Rebuild : Slides et démos

by Nicolas Calvi 4. octobre 2013 11:29

C'est avec un grand plaisir que j'ai participé hier à la ReBuild de Nantes. J'ai pu présenter deux sessions et c'est donc tout naturellement que je vous proposes les Slides et les démos de ces sessions :

PixelSense, une histoire collaborative

Slides : PixelSense - Une histoire collaborative.pdf (1,77 mb)

Kinect, réflextion et conception

Slides : Kinect - Réflexion et conception.pdf (1,41 mb)

Démos : RebuildDemoKinect.rar (11,05 mb)

N'hésitez pas me contacter si vous avez des questions sur le sujet.

Windows 8.1 : Classes XNA

by Nicolas Calvi 2. octobre 2013 12:02

Il m'est souvent arrivé de porter du code .Net (on va dire Classique, genre WPF, etc.) sur du Windows Store App. Une des problématiques que je rencontrais souvent était les bouts de code qui utilisaient des classes du Framework XNA.

De manière général, ces classes étaient souvent les mêmes : Vector3, Matrix, MathHelper, etc. Mais quand on arrive dans le monde des Windows Store App il est difficile de retrouver ses APIs. 

Afin de vous éviter de devoir décompiler ses classes, je vous propose aujourd'hui de télécharger le code source de celle-ci, compatible avec les Windows Strore App. C'est gratuit, c'est que du bonheur :)

Pour le téléchargement c'est ici : Microsoft.Xna.Framework.rar (33,84 kb)

 

Astuce : Inclinomètre (Windows 8.1)

by Nicolas Calvi 4. septembre 2013 07:30

Dans cette astuce nous allons découvrir l'inclinomètre, qui permet de connaitre comme son nom l'indique, le degré d'inclinaison d'un périphérique sur ses trois axes. 

Contrairement à d'autre senseur, l'inclinomètre n'a pas besoin d'une déclaration spéciale dans le manifeste de l'application.

La classe qui gère ce senseur est la classe statique "Inclinometer", qui regroupe ce qu'il faut pour gérer votre senseur. Contrairement au "Geolocator" ce senseur est toujours actif et travail en tâche de fond. Pour récupérer l'instance de l'inclinomètre, il faut passer par la fonction "GetDefault()" qui vous retourne l'instance courante du senseur. Si vous ne possédez pas de senseur, cette fonction vous retournera NULL, vérifiez donc bien l'instance avant de faire quoi que ce soit. Une fois l'instance retournée, voici les propriétés à connaitre :

  • MinimumReportInterval : Cela retourne l'intervalle minimum supporté par l'inclinomètre pour la mise à jour des positions. C'est une propriété en lecture, elle est a titre informative, elle est exprimée en milliseconde.
  • ReportInterval : C'est ici que l'on spécifie l'intervalle désiré (en milliseconde) entre deux notifications de changement d'inclinaison. Quand une tablette bouge, les notifications sont très rapide, cela permet de temporiser ces notifications si vous exécutez un traitement lourd entre chaque. Par contre, saisir un intervalle inférieur au "MinimumReportInterval" sera ignoré par l'API et se positionnera sur son minimum.

Voici ce que cela donne pour l'initialisation :

// Récupération de l'instance
inclinometer = Inclinometer.GetDefault();

// On test si l'inclinomètre existe
if ( inclinometer == null)
{
  throw(new Exception("Inclinometer not aviable."));
}
else
{
  // Spécification de l'intervalle
  double interval = 50;

  inclinometer.ReportInterval = interval < inclinometer.MinimumReportInterval ? inclinometer.MinimumReportInterval : interval;
}

Pour récupérer les changements d'inclinaisons il y a deux solutions, soit on attend que la classe nous l'indique (ce sera donc avec un abonnement à un événement) ou manuellement quand vous le souhaitez (donc avec une fonction).

Méthode automatique (Event) :

C'est la façon la plus simple d'être informé d'un changement d'inclinaison, en s'abonnant à l'événement "ReadingChanged" vous êtes notifié du changement :

// On se branche sur l'événement
inclinometer.ReadingChanged += OnInclinometerReadingChanged;

// Définition de la fonction pour l'événement
private void OnInclinometerReadingChanged(Inclinometer sender, InclinometerReadingChangedEventArgs args)
{
  // Récupération de la lecture du senseur
  InclinometerReading read = args.Reading;

  // Données les plus courantes
  float pitch = read.PitchDegrees;
  float roll = read.RollDegrees;
  float yaw = read.YawDegrees; 

  // Faire ici le traitement que vous voulez
}

Attention toutefois, cet événement ne s'exécute pas dans le ThreadUI, si vous devez affecter ces valeurs dans l'interface, n'oubliez pas de le faire dans le ThreadUI :

// On se branche sur l'événement
inclinometer.ReadingChanged += OnInclinometerReadingChanged;

// Définition de la fonction pour l'événement
private void OnInclinometerReadingChanged(Inclinometer sender, InclinometerReadingChangedEventArgs args)
{
  // On fait le traitement dans le ThreadUI
  await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    // Faire ici le traitement que vous voulez
  }
}

Voilà pour la méthode automatique.

Méthode manuelle (fonction) :

Dans ce cas précis, c'est nous qui allons demander à un moment que nous déterminons, les dernières valeurs captées par le senseur. Pour se faire on fait appel à la fonction "GetCurrentReading()" :

// Récupération des données
InclinometerReading read = inclinometer.GetCurrentReading();

// Données les plus courantes
float pitch = read.PitchDegrees;
float roll = read.RollDegrees;
float yaw = read.YawDegrees;

C'est une autre façon qui peut avoir beaucoup d'avantage (c'est un peu en fonction de l'utilisation que vous aurez du senseur). 

Voilà donc ce qu'il faut savoir pour bien commencer avec le senseur d'inclinaison.

Rebuild de Nantes

by Nicolas Calvi 2. septembre 2013 10:42

Juste un petit mot pour vous dire que je serais à la Rebuild de Nantes le 3 Octobre prochain. J'animerais deux sessions :

  • PixelSense, une histoire collaborative (Niveau 100)
  • Kinect, réflexion et conception (Niveau 100)

Toutes les informations sont sur le site : http://www.rebuild.fr/Pages/programme.aspx

Astuce : Géolocalisation (Windows 8.1)

by Nicolas Calvi 28. août 2013 07:30

Voici comment initialiser et gérer la géolocalisation sous Windows 8.1, c'est assez simple et vous verrez que ça va assez vite à mettre en place.

La géolocalisation sous Windows 8.1 commence par la déclaration dans le manifeste de l'application de la capacité "Location" en cochant la case adéquat :

Une fois cette modification faite, tout va se passer avec la classe "Geolocator", cette classe magique regroupe toutes les actions pour faire de la géolocalisation. Celle-ci une fois instanciée, possède certaine propriétés à connaitre :

  • DesiredAccuracy : Peux être affecté par deux valeurs (Default ou High), elle détermine avec quelle assiduité le module de géolocalisation va travailler pour vous géolocaliser. Attention, si vous êtes en High cela consommera plus de batterie si vous être en situation de mobilité.
  • DesiredAccuracyInMeters : Détermine le niveau de précision que vous voulez avoir en mètre pour la détection. Sachant que si cette valeur est inférieur ou égale à 100, il faut passer en "DesiredAccuracy = High" pour que cela fonctionne. Par expérience on voudrait mettre 1 mètre, mais sachez que vous ne pourrez pas de façon réaliste allez en dessous de 10 mètres. Les capteurs actuels étant incapable de donner autant de précision, on va dire que la valeur la plus basse est 10 mètres. Au final, si votre périphérique utilise une vraie puce GPS elle aura une précision de 10 mètres, si il utilise les réseaux Wifi la précision sera de 100 à 500 mètres en fonction si la zone en contient beaucoup, enfin si il utilise l'IP ce sera de l'ordre du kilomètre.
  • MovementThreshold : En gros cette propriété permet de définir le déplacement en mètre depuis le dernier point de détection, nécessaire pour vous notifier d'un déplacement. Par défaut c'est 0 mètre, ce qui signifie que chaque changement de position est notifié, c'est la valeur que l'on va utiliser dans la majeur partie des cas. Après, vous pouvez avoir des besoins qui ne nécessite pas un traitement a chaque mètre parcourus, c'est à vous de voir.
  • ReportInterval :  Cette propriété est exprimée en milliseconde et définit l'interval minimum de notification du changement de position. En gros, vous êtes en voiture, ça change tout le temps, cela permet de définir l'intervalle de temps entre deux levé de l'événement de changement de position, ce qui permet un peu de calmer l'API si vous avez des traitements long et ainsi permettre d'avoir un intervalle de traitement raisonnable, ici je vous conseille de la laisser à sa valeur par défaut 0 sauf si vous avez des besoins particulier.

Donc si on devait initialiser cette classe en mode ultra précis cela donnerais ceci :

// Création de l'instance
Geolocator geolocator = new Geolocator();

// Définition des paramètres
geolocator.DesiredAccuracy = PositionAccuracy.High;
geolocator.DesiredAccuracyInMeters = 10;
geolocator.MovementThreshold = 0;
geolocator.ReportInterval = 16;

Nous avons donc créé notre instance, maintenant il faut savoir si le module est activé, pour cela on se branche sur l'événement "StatusChanged", il nous permet de savoir à tout moment si on est bien en détection de notre position, pour cela on écrit :

// On se branche a l'événement
geolocator.StatusChanged += OnGeolocatorStatusChanged;

// Définition de la fonction pour l'événement
private void OnGeolocatorStatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
  switch(args.Status)
  {
    case(PositionStatus.Disabled):
      // Le senseur n'est pas actif
      break;

    case (PositionStatus.Initializing):
      // Le senseur s'initialise
      break;

    case (PositionStatus.NoData):
      // Le senseur ne peut pas encore envoyer de données
      // Cela se produit si vous apellez GetGeopositionAsync()
      // avant qu'il est des données de disponibles
      break;

    case (PositionStatus.NotAvailable):
      // Le senseur n'est pas disponible sur votre hardware
      break;

    case (PositionStatus.NotInitialized):
      // Le senseur n'est pas encore initialisé
      // Cela se produit si vous apellez GetGeopositionAsync()
      // avant que le senseur ne soit initialisé
      break;

    case (PositionStatus.Ready):
      // Senseur prêt, les données sont disponibles
      break;
  }
}

Il ne tient qu'à vous de traiter ces différents états pour que votre application réagisse proprement aux aléas de ce genre de senseur. Si vous n'avez pas de signal ou que le senseur est désactivé, c'est à vous de le faire savoir dans l'interface, c'est un aspect important du Design de votre application, ne pas laisser l'utilisateur dans l'incertitude, un pictogramme "pas de signal" permet souvent d'éviter que l'utilisateur trouve votre application inutilisable.

Maintenant il n'y a plus qu'à récupérer les changements de position. Pour cela deux solutions, soit on attend que la classe nous l'indique (ce sera donc avec un abonnement à un événement) ou manuellement quand vous le souhaitez (donc avec une fonction).

Méthode automatique (Event) :

C'est la façon la plus simple d'être informé d'un changement de position, en s'abonnant à l'événement "PositionChanged" vous êtes notifié du changement de position :

// On s'abonne à l'événement
geolocator.PositionChanged += OnGeolocatorPositionChanged;

// Définition de la fonction pour l'événement
private async void OnGeolocatorPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
  // Faire ici le traitement que vous voulez

  // Voici les informations les plus courantes  
  Geoposition pos = args.Position;

  double localAltitude = pos.Coordinate.Point.Position.Altitude;
  double localLatitude = pos.Coordinate.Point.Position.Latitude;
  double localLongitude = pos.Coordinate.Point.Position.Longitude;
}

Attention toutefois, cet événement ne s'exécute pas dans le ThreadUI, si vous devez affecter ces valeurs dans l'interface, n'oubliez pas de le faire dans le ThreadUI :

// On s'abonne à l'événement
geolocator.PositionChanged += OnGeolocatorPositionChanged;

// Définition de la fonction pour l'événement
private async void OnGeolocatorPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
  // On fait le traitement dans le ThreadUI
  await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  {
    // Faire ici le traitement que vous voulez
  }
}

Voilà pour la méthode automatique.

Méthode manuelle (fonction) :

Dans ce cas précis, c'est nous qui allons demander à un moment que nous déterminons, les dernières coordonnées captées par le senseur. Pour se faire on fait appel à la fonction "GetGeopositionAsync()" :

// Appel à la fonction
Geoposition pos = await geolocator.GetGeopositionAsync();

// Récupération des informations
double localAltitude = pos.Coordinate.Point.Position.Altitude;
double localLatitude = pos.Coordinate.Point.Position.Latitude;
double localLongitude = pos.Coordinate.Point.Position.Longitude;

C'est une autre façon qui peut avoir beaucoup d'avantage (c'est un peu en fonction de l'utilisation que vous aurez du senseur). 

Voilà donc ce qu'il faut savoir pour bien commencer avec le senseur de géolocalisation.