Dev Life

Mission sur Mars – PyCon 2014

Nous nous sommes beaucoup amusés à la PyCon 2013 avec notre pistolet Nerf géant commandé par email. Ce fut un grand succès auprès du public et pour la PyCon 2014, nous voulions faire quelque chose d'encore plus incroyable. Il était donc évident que nous devions commencer par… un aspirateur. Ce blog vous montre comment nous sommes passés d'un aspirateur à un rover martien et comment nous avons passé un excellent moment cette année encore à la PyCon.
Image pour Mission sur Mars – PyCon 2014

Nous nous sommes beaucoup amusés à la PyCon 2013 avec notre pistolet Nerf géant commandé par email. Ce fut un grand succès auprès du public et pour la PyCon 2014, nous voulions faire quelque chose d’encore plus incroyable. Il était donc évident que nous devions commencer par… un aspirateur. Ce blog vous montre comment nous sommes passés d’un aspirateur à un rover martien et comment nous avons passé un excellent moment cette année encore à la PyCon.

De modestes débuts… une mission sur Mars

Anton, notre ingénieur électricien devenu développeur de logiciels, s’était acheté un aspirateur robot Neato après des recherches approfondies, comparant Neato au très populaire iRobot Roomba. Le facteur décisif ? Les aspirateurs Neato disposent d’une API qui vous permet de les contrôler via du code. Exactement ce dont nous avions besoin pour notre mission sur Mars.

L’une des nombreuses choses que nous apprécions en travaillant chez Rackspace, l’entreprise qui a racheté Mailgun en 2012, est le hackday mensuel où tous les ingénieurs du bureau se réunissent pour travailler sur tout ce qu’ils trouvent intéressant, que cela soit lié ou non à un projet officiel de Rackspace. Nous avons fait appel à quelques collègues de Rackspace et avons passé la journée à travailler sur le code que nous allions utiliser pour contrôler le robot.

Nous savions que nous voulions donner au public la possibilité d’envoyer des commandes par email au robot comme mécanisme de contrôle, et que le robot devait pouvoir avancer, reculer et tourner à 360 degrés. Nous voulions également pouvoir « prélever des échantillons » de la surface martienne, c’est-à-dire allumer l’aspirateur, et prendre une photo à l’aide de la caméra montée sur ce qui allait devenir la tour d’instruments principale du rover.

Comment ça marche ?

La plupart des détails de notre jeu pour la PyCon de cette année étaient différents, mais nous avions retenu une leçon de l’année précédente :
L’accès au réseau peut s’avérer compliqué sur le lieu de la conférence. L’adresse IP du Raspberry Pi ne serait peut-être pas accessible publiquement, rendant impossible l’envoi d’une requête HTTP POST.
– Mailgun à la PyCon 2013
Pour résoudre ce problème, nous avons utilisé Redis afin de nous assurer que le rover pouvait récupérer les commandes depuis le serveur tant que le Raspberry Pi disposait d’une connexion Internet. Voici à quoi cela ressemble sur le plan conceptuel :
+ - - - - - + +-----------+ +------------+ +--------------+ | | | | | | | | SMTP | | HTTP | | | Email client +-----> | Mailgun +-----> | Web server | | | | | route | | | +--------------+ | | | | | | | | +-----+------+ +-----------+ | | | Redis lpush | (local) | | | v | +--------------+ +------------+ | | Redis brpop | | | | | Raspberry Pi | | Raspery Pi Camera | | GPIO +-------------------+ +-------------------> | Brick Pi | | serial port +-------------------+ +-------------------> | Neato Vac | +-------------------+
Une fois ce problème résolu, nous avons travaillé sur les commandes principales.
Voici des exemples du code que nous avons utilisé pour contrôler le robot :
Contrôler la tour de la caméra avec BrickPi :

                                

                                    def init(host, password): """Init the required components.""" print "Init BrickPi" BrickPiSetup() BrickPi.MotorEnable[PORT_D] = 1 def camera_control(command, mission_control_address): print "Camera control module received:", command if command in ("up", "down"): if command "up": BrickPi.MotorSpeed[PORT_D] = -100 elif command "down": # despite the fact that the surface gravity of Mars is only # about 38% of Earth's there is still less force required to # bring the camera down BrickPi.MotorSpeed[PORT_D] = 50 BrickPiUpdateValues() sleep(0.5) # stop the motor BrickPi.MotorSpeed[PORT_D] = 0 BrickPiUpdateValues() elif command == "take_picture": camera.capture(file_name) send_picture(file_name, mission_control_address) def send_picture(file_name, mission_control_address) """Send picture back to the Mission Control Center.""" r = requests.post( "https://api.mailgun.net/v2/mailgun.net/messages", auth=("api", "***"), files=[("attachment", open(file_name))], data={"from": "Mars Rover ", "to": mission_control_address, "cc": "nsa@mailgun.net", # oops "subject": "A message from Mars", "text": "The picture of the surface is attached!"})
                                
                            

Contrôler l’aspirateur :

                                

                                    def init(host, password): print "Init Vacuum Base!!!" vac_port = serial.Serial("/dev/ttyACM1") def vac_run_command(command, read_response=True): print "Vacuum base control module received:", command try: vac_port.write(command) if not read_response: # provided command doesn't have a response return return read_response() except: # fault tolerance for the WIN! reconnect()
                                
                            

Accepter les requêtes POST depuis Mailgun :

                                

                                    @app.route('/mission_control', methods=['POST']) def mission_control(): """Commands from Mailgun arrive here.""" command_message = request.form['stripped-text'] from_ = request.form['From'] for command in parse(command_message): robot.run(command, from_) return "10-4"
                                
                            

Nous allons avoir besoin de plus de Lego

Une fois la partie logicielle terminée, nous avons commencé à transformer notre aspirateur en rover martien.

Nous avons commencé par chercher le meilleur endroit pour acheter des Lego de couleur unie en vrac. Nous avions besoin de beaucoup de Lego noirs, gris et blancs pour créer un rover authentique. Il s’avère qu’ eBay est le meilleur endroit pour se procurer des Lego, souvent au kilo. 118 $ plus tard, nous étions prêts à commencer.

Deux hommes et un enfant travaillent ensemble à une longue table couverte de piles de blocs de construction triés

Nous avons réuni une équipe d’ingénieurs hors pair pour cette mission, dont le fils de quatre ans de l’un des membres de l’équipe Mailgun, et avons disposé tous les Lego qui formeraient la carrosserie du rover. Voici Anton, Ralph et Luca en pleine préparation. Après avoir prototypé quelques-uns des principaux composants, nous avons finalisé notre conception. Le rover serait équipé d’une caméra oscillante (alimentée par un moteur Lego Mindstorms) montée au sommet d’une tour de contrôle intégrant un  Raspberry PiBrickPi et une batterie de secours. Une grande partie de la carrosserie du rover serait également recouverte d’un panneau solaire USB fonctionnel.

Diagramme sur tableau blanc montrant des vues aériennes et arrière d'un robot avec des libellés pour le panneau solaire, la caméra et le Raspberry Pi

Quelques erreurs, quelques rires et quelques heures plus tard, nous étions en bonne voie pour présenter un robot assemblé lors de la présentation du hackday qui, par coïncidence, était programmée plus tard dans la journée au bureau de Rackspace.

Un homme travaille sur une construction LEGO complexe construite au-dessus d'une base d'aspirateur robot

Et voici un gros plan de la tour de contrôle principale. L’élément avec l’autocollant Mailgun est la batterie de secours. Le Raspberry Pi et le BrickPi sont montés par-dessus, et vous pouvez voir le moteur Lego en haut de la photo. La caméra du Raspberry Pi est juste hors du champ.

Un robot construit à partir de briques LEGO et de composants électroniques, arborant un logo Mailgun sur sa base

Voici une vue arrière du rover. Une grande partie des éléments décoratifs chromés a été ajoutée par le plus jeune membre de la mission, y compris les deux personnages Lego. L’un d’eux est un marin, et l’autre est un pirate. Il s’est avéré que ce n’était qu’une partie de la mission qui allait nécessiter beaucoup de créativité, comme vous le verrez plus tard.

Deux minifigurines LEGO se tiennent sur le pont d'un modèle de bateau LEGO construit sur mesure

Nous avons terminé une longue journée par une démonstration du rover à notre bureau. Voici Anton en train d’examiner le rover terminé.

Un homme s'accroupit et pointe du doigt un petit robot pendant qu'un groupe de personnes regarde

Chère TSA,

Nous savions que nous ne pouvions pas prendre le rover avec nous dans l’avion pour Montréal. Il ressemble à une bombe, nous l’admettons, et nous ne voulions pas avoir une longue et agréable conversation avec une équipe d’agents de la TSA. Nous avons donc soigneusement emballé le rover dans une grande valise, en le protégeant avec une trentaine de t-shirts American Apparel 50-50 bien doux, que nous allions distribuer aux participants de la conférence qui essaieraient le rover. Nous avons également joint un mot à l’attention de la TSA pour l’informer qu’il s’agissait d’un robot fabriqué avec un Raspberry Pi. Nous étions sûrs qu’ils ouvriraient le sac et jetteraient un coup d’œil, mais nous n’avions pas prévu à quel point ils l’inspecteraient de près.

Nouveau et amélioré… mais pas par choix

Lorsque nous sommes arrivés à notre hôtel à Montréal et que nous avons ouvert la valise, notre première pensée a été : mince, ils ont vraiment dû jeter le sac dans tous les sens, car de nombreuses pièces se sont complètement détachées. Cependant, en y regardant de plus près, il est devenu évident que la TSA avait démonté le rover, presque Lego par Lego. Certains composants étaient encore intacts, mais les structures les plus complexes, comme le châssis et la tour de contrôle, avaient été méticuleusement démontées.

Un café à la main et deux heures avant l’ouverture de la conférence, nous avons à nouveau étalé les Lego sur une table et commencé le réassemblage. Le problème auquel nous étions confrontés était que nous n’avions pas apporté de Lego supplémentaires. Comme nous avions improvisé la conception initiale, nous n’avions aucun plan à suivre, et chaque Lego devait donc être replacé exactement comme il l’était auparavant si nous voulions conserver le design d’origine.

Inutile de dire que nous avons opté pour une conception légèrement différente, qui a fini par nécessiter environ 30 % de Lego en moins pour créer un design tout aussi fonctionnel.

Un ordinateur portable, un smartphone, un panneau solaire et divers composants électroniques et plastiques sur une table blanche

Bien que frustrante au début, la reconstruction du rover s’est avérée très amusante. Nous avons fini par discuter avec de nombreux passionnés de Lego au cours de la matinée, et certains sont même venus nous donner un coup de main. À la mi-journée, notre rover martien était pleinement opérationnel et s’est révélé être un excellent moyen de rencontrer la communauté Python. Parmi nos hackers préférés que nous avons rencontrés figuraient les plus jeunes qui venaient à la PyCon pour la première fois. Voici une photo prise par la caméra du rover après que notre jeune ami a contrôlé le robot en envoyant des commandes par email depuis le téléphone de son père. On peut dire que la mission a été un succès !

Un homme et un jeune garçon portant des tours de cou sourient pour une photo dans une grande salle intérieure

Voilà donc l’histoire de notre rover martien. Quoi qu’il arrive, nous nous amusons toujours beaucoup à la PyCon. Nous avons hâte d’être à l’année prochaine pour recommencer.

À très vite ! Bons envois.

L’équipe Mailgun.