{"id":143,"date":"2017-12-04T19:21:30","date_gmt":"2017-12-04T19:21:30","guid":{"rendered":"http:\/\/www.plontke-online.de\/blog\/?p=143"},"modified":"2018-09-13T19:11:50","modified_gmt":"2018-09-13T19:11:50","slug":"cozmo-entdeckt-seine-welt","status":"publish","type":"post","link":"https:\/\/www.plontke-online.de\/blog\/index.php\/2017\/12\/04\/cozmo-entdeckt-seine-welt\/","title":{"rendered":"Cozmo entdeckt seine Welt"},"content":{"rendered":"<p>Im <a href=\"https:\/\/www.plontke-online.de\/blog\/index.php\/2017\/11\/19\/cozmo-ein-genialer-spielzeug-roboter\/\">letzten Beitrag<\/a> habe ich den Roboter Cozmo vorgestellt und seine grundlegenden Funktionen erkl\u00e4rt. Heute m\u00f6chte ich ein erstes kleines Programmierbeispiel mit dem mitgelieferten Python-SDK zeigen.<\/p>\n<p>In diesem Programm-Prototyp findet der Roboter selbstst\u00e4ndig seinen Weg \u00fcber den Schreibtisch. Er agiert dabei als einfaches <em>autonomes Fahrzeug<\/em>. Die eingebaute Bilderkennungs-Engine des Roboters wird verwendet, um sich zu orientieren und sich zu positionieren. Die Erkundung der umgebenden Welt erfolgt dabei in Echtzeit. Die Objekterkennung wird anhand vordefinierter Marker unterst\u00fctzt. Zur Demonstration der Funktionsweise habe ich f\u00fcr Cozmo eine kleine Welt aus Bausteinen ausgelegt.<!--more--><\/p>\n<h3>Definition von Objekten<\/h3>\n<p>Ein wichtiger Bestandteil von Cozmos Wahrnehmung ist seine Frontkamera. Der Videostream wird fortlaufend ausgewertet und auf bekannte Objekte untersucht. So werden unter anderem die Powercubes, Gesichter, Haustiere und die Ladestation automatisch erkannt. Dar\u00fcber hinaus k\u00f6nnen Cozmo auch eigene, benutzerdefinierte Objekte bekannt gemacht werden. Im vorliegenden Beispiel sollen dies einfache Holzbausteine sein. Diese sind zur Unterscheidung f\u00fcr den Roboter mit speziellen Markern beklebt, welche im weiteren Programmablauf ausgewertet werden k\u00f6nnen.<\/p>\n<p>Benutzerdefinierte Objekte k\u00f6nnen im CozmoSDK mit eindeutigen Abmessungen definiert werden. Das kann zum Beispiel so aussehen:<\/p>\n<pre>async def defineObjects(robot: cozmo.robot.Robot):\n        wall_obj0 = await robot.world.define_custom_wall(CustomObjectTypes.CustomType01, CustomObjectMarkers.Circles2, 73, 22, 30, 20, False)\n<\/pre>\n<p>Damit kann Cozmo nun alle Objekte Typs <em>&#8222;Baustein mit Kreissymbol&#8220;<\/em> erkennen, und diese im Raum anhand der bekannten Ma\u00dfe einordnen. Das hei\u00dft, wenn Cozmo ein solches Objekt sieht, kann er berechnen, welche Lage der Baustein im Raum relativ zu ihm selbst hat. Die Entfernungs- und Lageberechnungen sind erstaunlich genau. <em>Hinweis: Beim Aufkleben der Marker muss man sehr pr\u00e4zise vorgehen, da schr\u00e4g angebrachte Marker dazu f\u00fchren, dass das Objekt unter Umst\u00e4nden mit falschen Z-Koordinaten oder verdreht im 3D-Modell platziert wird.<\/em><\/p>\n<h3>Objekte ansteuern<\/h3>\n<p>Der Roboter erforscht seine Umgebung und kann die erkannten Objekte anhand der dreidimensionalen Repr\u00e4sentation punktgenau ansteuern. Bekannte Hindernisse k\u00f6nnen umfahren werden.<\/p>\n<p>Im Beispielprogramm werden die benutzerdefinierten Objekte genutzt, um einen Weg durch das Bausteinlabyrinth zu finden. Ein Kreisymbol zeigt den Weg nach rechts und ein Diamantsymbol den Weg nach links. Die anderen Symbole sind ohne Funktion und markieren lediglich unpassierbare W\u00e4nde.<\/p>\n<p>Zum Ansteuern einer Position in Cozmos 3D-Welt muss nicht unbedingt bis auf die Ebene der Motorsteuerung, respektive die Ansteuerung der beiden Ketten hinabgestiegen werden. Es gibt bereits eine vorgefertigte Funktion, welche ihn an eine spezielle Position im Raum fahren l\u00e4sst. Die einzige Schwierigkeit besteht noch darin, mittels Vektorrechnung die Zielposition zwischen dem angepeilten Marker und der aktuellen Position zu berechnen. Ohne diese Einschr\u00e4nkung w\u00fcrde Cozmo sonst stets bis zur Mitte des erkannten Markerbausteins fahren und diesen dabei verschieben.<\/p>\n<p>Asynchroner Aufruf der Funktion <em>go_to_pose<\/em> zum Ansteuern einer Position im dreidimensionalen Raum:<\/p>\n<pre>try:\n    print(\"object %s\" % str(CustomObject.object_type))\n    await robot.go_to_pose(pose=position).wait_for_completed()\n    print(\"Done.\")\nexcept:\n    print(\"Didn't go to the object.\")<\/pre>\n<h3>Video autonomes Fahren<\/h3>\n<p>Das Video zeigt den Ablauf des Programms im Detail. Im Fenster links oben wird die dreidimensionale Repr\u00e4sentation von Cozmos Welt mit dem im SDK enthaltenen OpenGL-Viewer dargestellt. Im Fenster daneben sieht man den Livestream der Frontkamera. Die erkannten Objekte werden fortlaufend als Annotation eingeblendet. Unten rechts sieht man wie Cozmo seinen Weg durch den Parcours findet.<\/p>\n<div style=\"width: 525px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-143-1\" width=\"525\" height=\"295\" poster=\"https:\/\/www.plontke-online.de\/blog\/wp-content\/uploads\/2017\/12\/customobj_pre.png\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/www.plontke-online.de\/blog\/wp-content\/uploads\/2017\/12\/WPII2543_x264.mp4?_=1\" \/><a href=\"https:\/\/www.plontke-online.de\/blog\/wp-content\/uploads\/2017\/12\/WPII2543_x264.mp4\">https:\/\/www.plontke-online.de\/blog\/wp-content\/uploads\/2017\/12\/WPII2543_x264.mp4<\/a><\/video><\/div>\n<p>Wie flie\u00dfend Bilderkennung und Auswertung erfolgen, kann man im Video gut verfolgen. Beachtenswert ist, mit welcher Pr\u00e4zision die einzelnen Abbiegemarker angesteuert werden. Interessant ist es au\u00dferdem, zu sehen, dass selbst im Hintergrund befindliche Objekte visualisiert werden. So werden im Verlauf der Fahrt zum Beispiel auch die Ladestation und Powercubes erkannt.<\/p>\n<p>Die Herausforderung bei der Programmierung des Roboters liegt im Besonderen in der Nebenl\u00e4ufigkeit der einzelnen Prozesse. Die Bilderkennung und das Man\u00f6vrieren des Roboters laufen parallel und asynchron ab. Asynchrone Programmierung folgt einem von der sequentiellen bzw. ereignisorientierten Programmiermethode abweichenden Ansatz, bei dem die einzelnen Befehle nicht nacheinander, sondern nebeneinander abgearbeitet werden. Die R\u00fcckgabewerte von Funktionen oder angeforderten Aktionen stehen nicht unmittelbar nach der Ausf\u00fchrung zur Verf\u00fcgung, sondern erst nach unbestimmter Zeitspanne. Das asynchrone Programmierparadigma wird von Python mit der Bibliothek <em>asyncio<\/em> unterst\u00fctzt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im letzten Beitrag habe ich den Roboter Cozmo vorgestellt und seine grundlegenden Funktionen erkl\u00e4rt. Heute m\u00f6chte ich ein erstes kleines Programmierbeispiel mit dem mitgelieferten Python-SDK zeigen. In diesem Programm-Prototyp findet der Roboter selbstst\u00e4ndig seinen Weg \u00fcber den Schreibtisch. Er agiert dabei als einfaches autonomes Fahrzeug. Die eingebaute Bilderkennungs-Engine des Roboters wird verwendet, um sich zu &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.plontke-online.de\/blog\/index.php\/2017\/12\/04\/cozmo-entdeckt-seine-welt\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eCozmo entdeckt seine Welt\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":142,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[1],"tags":[5,6],"class_list":["post-143","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-cozmo","tag-robotik"],"_links":{"self":[{"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/posts\/143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=143"}],"version-history":[{"count":43,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/posts\/143\/revisions"}],"predecessor-version":[{"id":598,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/posts\/143\/revisions\/598"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/media\/142"}],"wp:attachment":[{"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.plontke-online.de\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}