Dev Life
Mission zum Mars – PyCon 2014
Wir hatten großen Spaß auf der PyCon 2013 mit unserer gigantischen E-Mail-gesteuerten Nerf-Gun. Sie war ein absoluter Publikumsmagnet, und für die PyCon 2014 wollten wir etwas noch Beeindruckenderes machen. Daher lag es natürlich auf der Hand, dass wir mit … einem Staubsauger beginnen sollten. Dieser Blog zeigt Ihnen, wie wir aus einem Staubsauger einen Mars Rover gemacht haben und dieses Jahr wieder eine großartige Zeit auf der PyCon hatten.
Von bescheidenen Anfängen … eine Mission zum Mars
Anton, unser hauseigener Elektrotechniker und heutiger Softwareentwickler, hatte sich einen Neato Saugroboter gekauft, nachdem er ausführlich recherchiert und den Neato mit dem beliebteren iRobot Roomba verglichen hatte. Der entscheidende Faktor? Neato-Staubsauger verfügen über eine API, über die sich das Gerät per Coding steuern lässt. Genau das, was wir für unsere Mission zum Mars brauchten.
Eines der vielen Dinge, die wir an der Arbeit bei Rackspace – dem Unternehmen, das Mailgun 2012 übernommen hat – schätzen, ist der monatliche Hackday. An diesem Tag kommt das gesamte Technikteam im Büro zusammen, um an Themen zu arbeiten, die es interessant findet, unabhängig davon, ob es sich um ein offizielles Rackspace-Projekt handelt oder nicht. Wir zogen ein paar Kollegen von Rackspace hinzu und verbrachten den Tag damit, am Code zu arbeiten, mit dem wir den Roboter steuern würden.
Wir wussten, dass wir den Leuten die Möglichkeit geben wollten, Befehle per E-Mail als Steuerungsmechanismus an den Roboter zu senden, und dass der Roboter in der Lage sein sollte, sich vorwärts und rückwärts zu bewegen sowie sich um 360 Grad zu drehen. Außerdem wollten wir in der Lage sein, „Proben“ von der Marsoberfläche zu nehmen – also den Staubsauger einzuschalten – und mit der Kamera, die am zukünftigen Hauptinstrumententurm des Rovers angebracht war, ein Bild aufzunehmen.
Wie es funktioniert
Viele Details unseres diesjährigen PyCon-Spiels waren anders, aber eine Sache hatten wir aus dem letzten Jahr gelernt:
Der Netzwerkzugang am Veranstaltungsort der Konferenz könnte schwierig werden. Die IP-Adresse des Raspberry Pi ist möglicherweise nicht öffentlich zugänglich, sodass ein HTTP-POST-Request dorthin eventuell nicht funktioniert.
– Mailgun auf der PyCon 2013
Um dies zu lösen, verwendeten wir Redis. So stellten wir sicher, dass der Rover Befehle vom Server abrufen konnte, solange der Raspberry Pi über eine Internetverbindung verfügte. Hier ist das entsprechende Konzept:+ - - - - - + +-----------+ +------------+ +--------------+ | | | | | | | | 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 | +-------------------+
Nachdem dies gelöst war, arbeiteten wir an den Kernsteuerungen.
Unten finden Sie Beispiele des Codes, den wir zur tatsächlichen Steuerung des Roboters verwendet haben:
Kameraturm mit BrickPi steuern:
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!"})
Staubsauger steuern:
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()
POST-Anfragen von Mailgun akzeptieren:
@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"
Wir werden mehr Legosteine brauchen
Nachdem die Software fertig war, machten wir uns daran, unseren Staubsauger in einen Mars Rover zu verwandeln.
Wir begannen damit, nach dem besten Ort zu suchen, um einfarbige Legosteine in großen Mengen zu kaufen. Wir brauchten eine Menge schwarze, graue und weiße Legosteine, um einen authentischen Rover zu bauen. Es stellte sich heraus, dass Ebay der beste Ort ist, um Legosteine zu kaufen, oft kiloweise. 118 $ später waren wir bereit loszulegen.

Wir stellten ein erstklassiges Technikteam für die Mission zusammen, darunter der vierjährige Sohn eines Mailgunners, und legten alle Legosteine bereit, die den Rover-Körper bilden sollten. Hier sehen Sie Anton, Ralph und Luca beim Aufbau. Nachdem wir Prototypen einiger Hauptkomponenten erstellt hatten, legten wir unser endgültiges Design fest. Der Rover sollte eine schwenkbare Kamera (angetrieben von einem Lego-Mindstorms-Motor) haben, montiert auf einem Kontrollturm mit integriertem Raspberry Pi, BrickPi und Batterie-Backup. Ein großer Teil des Rover-Gehäuses sollte zudem mit einem funktionierenden USB-Solarpanel abgedeckt werden.

Ein paar Fehltritte, einige Lacher und wenige Stunden später waren wir auf dem besten Weg, einen zusammengebauten Roboter für die Hackday-Präsentation zu haben, die zufällig für denselben Tag im Rackspace-Büro angesetzt war.

Und hier ist eine Nahaufnahme des Hauptkontrollturms. Das Ding mit dem Mailgun-Aufkleber ist das Batterie-Backup. Der Raspberry Pi und der BrickPi sind darauf montiert, und oben auf dem Foto ist der Lego-Motor zu erkennen. Die Raspberry-Pi-Kamera befindet sich knapp außerhalb des Bildausschnitts.

Hier ist eine Rückansicht des Rovers. Ein Großteil des dekorativen Chroms wurde von unserem jüngsten Missionsmitglied hinzugefügt, einschließlich der zwei Lego-Männchen. Eines davon ist ein Seemann und das andere ein Pirat. Dies sollte sich als nur ein Teil der Mission herausstellen, der große Kreativität erforderte, wie Sie später sehen werden.

Wir beendeten einen langen Tag, indem wir den Rover in unserem Büro vorführten. Hier überprüft Anton den fertigen Rover.

Liebe TSA,
Wir wussten, dass wir den Rover nicht mit ins Flugzeug nach Montreal nehmen konnten. Zugegeben, er sieht aus wie eine Bombe, und wir wollten keine ausgedehnte Konversation mit einem Team von TSA-Agenten führen. Also packten wir den Rover vorsichtig in einen großen Koffer und schützten ihn mit etwa 30 schönen, weichen 50/50-T-Shirts von American Apparel, die wir auf der Konferenz an Leute verteilen würden, die den Rover eine Runde steuerten. Außerdem legten wir einen Zettel für die TSA bei, um sie wissen zu lassen, dass es sich um einen Roboter handelte, der mit einem Raspberry Pi gebaut wurde. Wir waren uns sicher, dass sie die Tasche öffnen und nachsehen würden, aber wir hatten nicht damit gerechnet, wie genau sie hinsehen würden.
Neu und verbessert … aber nicht ganz freiwillig
Als wir in unserem Hotel in Montreal ankamen und den Koffer öffneten, dachten wir zuerst: Verdammt, sie müssen den Koffer wirklich herumgeworfen haben, denn viele Teile waren komplett auseinandergefallen. Bei näherer Betrachtung wurde jedoch klar, dass die TSA den Rover buchstäblich Stein für Stein auseinandergenommen hatte. Einige Komponenten waren noch intakt, aber die komplexesten Strukturen, wie der Rahmen und der Kontrollturm, waren akribisch zerlegt worden.
Mit Kaffee in der Hand und zwei Stunden vor Konferenzeröffnung breiteten wir die Legosteine erneut auf einem Tisch aus und begannen mit dem erneuten Zusammenbau. Das Problem dabei war, dass wir keine zusätzlichen Legosteine mitgebracht hatten. Da wir das ursprüngliche Design improvisiert hatten, gab es keinen Bauplan, dem wir folgen konnten. Daher musste jeder Legostein exakt wieder so platziert werden wie zuvor, wenn wir das Originaldesign beibehalten wollten.
Es versteht sich von selbst, dass wir uns letztendlich für ein leicht abweichendes Design entschieden haben – eines, das am Ende rund 30 % weniger Legosteine benötigte, um dasselbe funktionale Design zu erzielen.

Obwohl es zunächst frustrierend war, erwies sich der Wiederaufbau des Rovers als riesiger Spaß. Wir unterhielten uns im Laufe des Morgens mit unzähligen Lego-Enthusiasten, und einige sprangen sogar ein und halfen ein wenig. Gegen Mittag war unser Mars Rover wieder voll einsatzfähig und bot eine großartige Gelegenheit, die Python-Community kennenzulernen. Zu unseren Lieblings-Hackern, die wir trafen, gehörten die ganz Jungen, die zum ersten Mal auf der PyCon waren. Hier ist eine Aufnahme, die mit der eigenen Kamera des Rovers gemacht wurde, nachdem unser junger Freund den Bot gesteuert hatte, indem er Befehle per E-Mail vom Handy seines Vaters gesendet hatte. Wir würden sagen, die Mission war ein Erfolg.

Das ist also die Geschichte unseres Mars Rovers. Was auch passiert, auf der PyCon haben wir immer großen Spaß. Wir können es kaum erwarten, das Ganze nächstes Jahr noch einmal zu machen.
Bis dann. Viel Spaß beim Versenden.
Ihr Mailgun-Team.