Simuler l'accéléromètre sur le simulateur iPhone !

AliGatorAliGator Membre, Modérateur
novembre 2008 modifié dans Vos applications #1
Bonjour à  tous,

Un peu déçu de voir que le simulateur iPhone ne gérait pas l'accéléromètre (un peu embêtant alors que je base quelques unes de mes applis dessus !), j'ai trouvé ça d'autant plus dommage que j'ai un MacBookPro donc avec un accéléromètre intégré... et qu'Apple n'a donc pas daigné relier cet accéléromètre à  celui de l'iPhoneSimulator.

Du coup, je me suis lancé... Et aujourd'hui je vous propose une solution permettant de relier l'accéléromètre de votre MacBook[Pro] à  celui du Simulateur iPhone avec un minimum de modification sur votre appli iPhone !
Bon au début j'utilisais un programme en ligne de commande pour récupérer les données de l'accéléromètre de mon mac... et les NSTask sur l'iPhone, c'est pas possible. Alors après quelques tests, j'ai réalisé que le NSDistributedNotificationCenter est partagé entre celui d'OSX et celui intégré au simulateur iPhone... cool, on va pouvoir communier d'une appli Mac à  une appli iPhone :)


Cela donne ce que vous trouvez dans l'archive ZIP jointe ci-dessous :
  • une appli mac "AccelerationSensor4iPhoneSimulator" qui affiche une fenêtre dans OSX avec les données de l'accéléromètre de votre mac, et publie une notification distribuée avec ces valeurs.
  • Et du côté iPhone, l'appli "iPhoneNotificationReceiver" qui sert ici d'exemple se contente d'utiliser la classe "UIAccelerometer" presque comme habituellement sur l'iPhone, sauf qu'elle appelle [tt]sharedAccelerometerSimulator[/tt] au lieu de [tt]sharedAccelerometer[/tt] tout court, cette méthode se chargeant sous le capot de façon transparente d'écouter la notification du logiciel OSX, et de la traduire par un envoi de message [tt]accelerometer:didAccelerate:[/tt] au delegate de l'accéléromètre (comme le ferait le vrai accéléromètre).



--> Du coup, un simple petit #define vous permettra de facilement switcher de l'utilisation du simulateur d'accéléromètre à  l'accéléromètre réel lors du déployement sur iPhone réel :
#define USE_SIMULATOR 1 /* y&#39;a p&#39;tet une macro déjà  définie pour savoir si on est sur le simulateur d&#39;ailleurs ??<br />#if USE_SIMULATOR<br />  #import &quot;UIAccelerometerSimulator.h&quot;<br />  #define sharedAccelerometer sharedAccelerometerSimulator<br />#endif
En rajoutant ce petit bout de code au début de votre classe qui appelle sharedAccelerometer, et en incluant UIAccelerometerSimulator.h et .m dans votre projet bien sûr, ça suffit pour utiliser l'accéléromètre de votre MacBook/MacBookPro sur le simulateur iPhone :) (Bon il faut lancer l'appli "AccelerationSensor4iPhoneSimulator" sur votre OSX pour qu'il envoie les données pendant que vous testez, quand même)


Donc, si vous avez tout suivi, il suffit de lancer "AccelerationSensor4iPhoneSimulator" sur votre mac, puis le projet d'exemple "iPhoneNotificationReceiver" dans le Simulateur iPhone, et de bouger votre MacBook[Pro] dans tous les sens ;D
Voilà , ça reste sans doute à  faire évoluer, donc je suis à  l'écoute de vos remarques :)






Notes en vrac :
  • Mon projet "AccelerationSensor4iPhoneSimulator" ne compile pas (ou plus exactement ne linke pas) en Release, pourtant il marche très bien Debug (grace au fait que c'est en zerolink j'imagine)... Je ne me suis pas étendu sur la question car il est tard, mais si vous avez des idées sur la raison...
  • L'appli OSX "AccelerationSensor4iPhoneSimulator" utilise la librairie "unimotion" pour récupérer les données de l'accéléromètre du Mac. Merci à  son auteur.
  • Je suis passé par les notifications distribuées car au début j'utilisais AMSTracker (programme en ligne de commande) et on ne peux pas créer de NSTask sur l'iPhone à  ma connaissance (puisqu'Apple n'accepte qu'une tâche à  être lancée à  la fois) -- et puis j'étais pas sûr que ce programme récupère les bonnes valeurs sur l'iPhone -- d'où l'idée de faire une appli OSX externe pour lire l'accéléromètre et envoyer les données. Maintenant qu'au final j'utilise une lib, y'a peut-être moyen de l'intégrer à  votre appli iPhone pour se passer de l'appli OSX envoyant les notifications, à  creuser.
    Bon je suis pas persuadé que ce soit possible et surtout que ça ait un impact aussi faible sur le projet iPhone que la solution actuelle, mais ça reste à  creuser.


Du coup j'ai testé avec CrashLanding (sample code fourni par Apple), j'ai téléchargé le sample puis juste rajouté ma catégorie (le fameux .h et .m) et mon "bootstrap" (truc avec le #define indiqué au dessus), et ça a marché de suite :)


Bons tests !

Réponses

  • Philippe49Philippe49 Membre
    11:05 modifié #2
    Un premier essai à  plat sur la table :

    1 g en z vers le haut ... bon Ok mon Mac Book Pro ne bouge pas sur la table, il subit donc une force de réaction à  la pesanteur.
    Mais en x et en y , je ne vois pas la raison  : précision de l'accéléromètre  ou accélération de Coriolis ? Cela me semble beaucoup pour cette dernière ...

  • AliGatorAliGator Membre, Modérateur
    11:05 modifié #3
    Salut Philippe et merci de ton test
    .
    • Alors pour l'accéléromètre, j'utilise comme je l'ai dit la librairie de UniMotion. Ce n'est donc pas moi qui gère les données. Cependant dans le package de unimotion, ils proposent un programme (ligne de commande) pour calibrer on accéléromètre (rajouter un offset et éventuellement un scale pour chaque axe) donc ça veut bien dire que c'est sans doute utile. Je tâcherai donc d'intégrer cette possibilité de calibrage dans la prochaine version.
    • Par contre bizarre que ton Z soit positif, le mien est négatif (j'ai un MacBook Pro pour ma part, et toi ?)... J'ajouterai d'ailleurs une information sur le type de sensor détecté aussi tiens, ça permettra d'ajuster automatiquement si on voit que sur certaines machines les axes ne sont pas bons... bien que normalement unimotion est fait pour ça, être indépendant du type de sensor...
    • Je compte rajouter à  terme (j'aurais pas le temps ce WE, mais un de ces 4) une case à  cocher pour mettre en marche ou arrêter l'envoi des notifications, et un slider pour permettre de régler la fréquence de mise à  jour.
      De plus, dans ma catégorie UIAccelerometer(Simulator) je vais tâcher de faire remonter une notification lorsque l'utilisateur modifie le updateInterval, pour que l'appli OSX prenne cette valeur en conséquence (y'a moyen de surcharger une méthode d'une classe via une catégorie de cette classe ?) car pour l'instant c'est un updateInterval (fréquence d'envoi de la notif) fixe et non modifiable.



    Sinon, à  part le fait que les valeurs de l'accéléromètre ne sont pas idéales, le "jumelage" avec le simulateur iPhone marche bien pour tes applis iPhone ? Tu as essayé ?


    Tiens sinon j'ai été surpris moi-même de trouver un NSDistributedNotificationCenter dans l'iPhone : quand j'ai pensé à  l'idée d'utiliser ça pour faire communiquer mon appli OSX et iPhone, je me suis dit "ah ben non les DistributedNotifications ça doit pas exister sous iPhone puisqu'il ne peut y avoir qu'une seule application d'ouverte à  la fois donc ça rend cette classe obsolète"... du coup ça m'arrange qu'elle existe, mais je ne vois pas trop comment elle pourrait s'avérer utile sur un iPhone réel ?
  • Philippe49Philippe49 Membre
    11:05 modifié #4
    dans 1225541734:

    Par contre bizarre que ton Z soit positif, le mien est négatif (j'ai un MacBook Pro pour ma part, et toi ?)...

    J'ai un Mac Book Pro qui commence à  dater (au moins 2 ans), je pensais changer cette année mais l'écran brillant cela ne me dit rien du tout ...
    Physiquement c'est plutôt normal que ce soit +1g (cela mesure la réaction à  la force de gravité, donc une force dirigée vers le haut). Ce qui m'inquiète plutôt c'est qu'il y a quand même 1g +10%, à  Angers on est pas si haut par rapport à  la mer ... et surtout ce sont les valeurs en x et y. Je questionne un collègue Physicien, je vais voir ce qu'il me répond ...

    Mais ce n'est peut-être qu'un problème de calibrage de "l'instrument de mesure" UniMotion comme tu le dis.

    dans 1225541734:

    Sinon, à  part le fait que les valeurs de l'accéléromètre ne sont pas idéales, le "jumelage" avec le simulateur iPhone marche bien pour tes applis iPhone ? Tu as essayé ?
    pas encore

  • orfaitorfait Membre
    novembre 2008 modifié #5
    Je vais donner une réponse à  propos des valeurs...

    Déjà , il ne faut pas s'attendre à  avoir la valeur exacte (9,81 environ, ou bien 1 si on met une échelle en G). Ces capteurs utilisent une sonde capacitive et ne sont en général pas calibrés. Dans les situations nécessitant une valeur plus "réelle", on utilise soit un DSP (Digital Signal Processor), soit un circuit analogique pour corriger les valeurs (et c'est souvent non-linéaire). Il existe des capteurs avec un DSP intégré pour corriger et linéariser les valeurs, mais c'est bien plus coûteux.
    Ensuite, pour les axes, c'est compliqué. En gros, il faut fixer un repère au circuit intégré et projeter l'accélération sur ce repère. Alors tout simplement, je pense que Apple a du changer la position du circuit intégré entre ses versions de macbook, d'où des valeurs différentes. Il est aussi possible que la référence du composant ai changé.

    Voilà , j'espère vous avoir éclairé.
  • AliGatorAliGator Membre, Modérateur
    novembre 2008 modifié #6
    Bonsoir tout le monde,

    Me revoilà  avec une nouvelle version un peu plus élaborée et plus simple encore à  intégrer ! ;)

    Côté appli Mac (qui a été renommée en AccelerometerPilot.app), j'y ai intégré :
    • L'affichage (et la possibilité de choix bien qu'à  priori cette possibilité est inutile) du type de sensor détecté (en fonction de la machine)
    • La possibilité de "calibrer" le sensor : mettre une "tare" sur les valeurs X et Y, échanger les différents axes X,Y,Z et inverser leur sens (spéciale dédicace pour Philippe49 qui a la tête à  l'envers, pourtant j'ai testé ce WE à  Angers en rentrant chez mes parents, j'avais toujours un Z négatif :))
    • La possibilité de modifier le [tt]updateInterval[/tt], soit par l'interface, soit par une notification (utile pour récupérer cette valeur quand modifiée depuis l'iPhone Simulator)
    • Un drawer affichant les axes de l'iPhone, et un panel pour avoir une vision graphique des valeurs X et Y rendues par le sensor
    • Le projet est réglé pour être compatible 10.4 (enfin normalement, si j'ai bien fait les choses), quoique je suis pas sûr que ce soit utile puisqu'il faut 10.5 pour programmer pour iPhone... mais bon ça permet à  ceux qui n'ont que 10.4 de quand même faire mumuse avec leur accéléromètre, hors du contexte des applis iPhone ;D


    Du coup je pense qu'il commence à  être bien complet. Il me reste plus que les préférences / NSUserDefaults que je n'ai pas encore géré (mai est-ce utile ? pour les échanges et inversions d'axe et la position des fenêtres peut-être ?)


    Du côté de votre appli iPhone :
    • maintenant vous n'avez plus qu'à  ajouter UIAccelerometerSimulator.h/.m pour que ça marche sans rien modifier dans votre code, magique !
    • Pour activer ou désactiver le comportement simulé (basculer entre la vraie classe UIAccelerometer et la catégorie de remplacement UIAccelerometer(Simulator) qui communique par notifications envoyées par AccelerometerPilot.app), il suffit de basculer le [tt]#define USE_ACCELEROMETER_SIMULATOR[/tt] de 0 à  1 dans UIAccelerometerSimulator.h
    • Dorénavant, cette catégorie UIAccelerometer(Simulator) gère aussi le updateInterval (elle envoie une notification lorsque votre code modifie le updateInterval et AccelerometerPilot.app en tient compte)





    Voilà  !
    Au final, pour intégrer cette simulation d'accéléromètre dans votre appli sur le Simulateur iPhone :
    - Inclure UIAccelerometerSimulator.h/.m dans votre projet iPhone (vous les trouverez dans le projet iPhone d'exemple malnommé "iPhoneNotificationReceiver" et fourni dans le ZIP, je l'ai pas peaufiné, lui)
    - #importer le .h dans les .m où vous utilisez l'accéléromètre pour que la catégorie soit prise en compte
    - Lancer AcceleratorPilot.app sur votre Mac, et l'étalonner si besoin
    - Compiler et exécuter votre appli iPhone sur le simulateur.
    Et ça devrait marcher tout seul !

    N'hésitez pas à  me faire des retours ;)
Connectez-vous ou Inscrivez-vous pour répondre.