{"id":7437,"date":"2022-05-06T10:59:02","date_gmt":"2022-05-06T10:59:02","guid":{"rendered":"https:\/\/pib.rocks\/imitate-me-pib\/"},"modified":"2023-05-19T09:50:15","modified_gmt":"2023-05-19T09:50:15","slug":"imitate-me-pib","status":"publish","type":"post","link":"https:\/\/pib.rocks\/de\/imitate-me-pib\/","title":{"rendered":"Imitate me, pib!"},"content":{"rendered":"<div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-1 fusion-flex-container has-pattern-background has-mask-background nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:1248px;margin-left: calc(-4% \/ 2 );margin-right: calc(-4% \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:1.92%;--awb-margin-bottom-large:20px;--awb-spacing-left-large:1.92%;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:1.92%;--awb-spacing-left-medium:1.92%;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:1.92%;--awb-spacing-left-small:1.92%;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-text fusion-text-1\"><h1>Imitate me, pib!<\/h1>\n<p>Die Idee hinter diesem Projekt ist es, pib zu erm\u00f6glichen, die Bewegung eines Arms zu imitieren. Das gibt uns eine einfache M\u00f6glichkeit, pib zu animieren, ohne dass wir programmatisch steuern m\u00fcssen. Im Moment: noch eine wilde Idee :-) Mal sehen, ob wir das hinbekommen&#8230; Diese Projektseite dokumentiert unseren Fortschritt und soll eine unterhaltsame Anleitung sein, wie man es selbst machen kann, wenn wir es schaffen.<\/p>\n<h2>Was bisher geschah<\/h2>\n<p>Zun\u00e4chst einmal brauchen wir eine M\u00f6glichkeit, die Position des menschlichen Arms zu bestimmen. Es gibt viele Ger\u00e4te auf dem Markt, und wie immer sollte unsere Wahl einfach l\u00f6sbar, gut verf\u00fcgbar und erschwinglich sein. Eine m\u00f6gliche Wahl ist der <a href=\"https:\/\/www.ultraleap.com\/product\/leap-motion-controller\/\" target=\"_blank\" rel=\"noreferrer noopener\">LeapMotion-Controller<\/a>, von dem wir schon vor einiger Zeit zwei St\u00fcck gekauft haben:<\/p>\n<div id=\"attachment_5604\" style=\"width: 810px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-5604\" class=\"lazyload wp-image-5604 size-full\" src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion.jpg\" data-orig-src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion.jpg\" alt=\"LeapMotion\" width=\"800\" height=\"290\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27800%27%20height%3D%27290%27%20viewBox%3D%270%200%20800%20290%27%3E%3Crect%20width%3D%27800%27%20height%3D%27290%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-srcset=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion-200x73.jpg 200w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion-300x109.jpg 300w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion-400x145.jpg 400w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion-600x218.jpg 600w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion-768x278.jpg 768w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/LeapMotion.jpg 800w\" data-sizes=\"auto\" data-orig-sizes=\"(max-width: 800px) 100vw, 800px\" \/><p id=\"caption-attachment-5604\" class=\"wp-caption-text\">Quelle: ultraleap.com<\/p><\/div>\n<p>Als wir diesen bekamen, freuten wir uns sehr \u00fcber die nette Python-API, die es wirklich sehr einfach machte, unsere erste App zum Laufen zu bringen. Das ist zwar schon ein paar Jahre her, aber was kann hier schon schiefgehen&#8230;<\/p>\n<p>\u00c4h&#8230; Eine aktuelle Suche zeigt: Unsere fr\u00fcher so gesch\u00e4tzte Python-API ist jetzt veraltet! Ultraleap sagt, dass das neue Gemini-Framework pr\u00e4ziser ist als die fr\u00fchere API (ja!), aber es gibt nur noch eine C-API. Und komplett auf C umzusteigen ist keine Option :-D Nun, lasst uns weiter suchen und sehen, ob wir einen pyhton-wrapper zum Laufen bringen k\u00f6nnen&#8230;<\/p>\n<p>Bei der Suche auf github haben wir gesehen, dass andere Entwickler unseren Bedarf teilen und bereits an der Sache gearbeitet haben:<\/p>\n<ul>\n<li>https:\/\/github.com\/seanschneeweiss\/RoSeMotion\/tree\/master\/app<\/li>\n<li>https:\/\/github.com\/RomanILL\/Leap-Motion-Python-3.8<\/li>\n<\/ul>\n<p>Nach dem Herunterladen und Installieren: Beide haben keine Daten vom Sensor ausgelesen. Es gibt also keine andere M\u00f6glichkeit, als es selbst zu tun&#8230; Jippee! :-D<\/p>\n<h2>In Python verpackter API-Zugang f\u00fcr LeapMotion<\/h2>\n<p>UltraLeap bietet alle seine Tools in einem einzigen <a href=\"https:\/\/developer.leapmotion.com\/tracking-software-download\" target=\"_blank\" rel=\"noreferrer noopener\">Download-Paket<\/a> an. Nachdem du alles installiert hast, kannst du den UltraLeap-Viewer verwenden, um LeapMotion in Aktion zu sehen:<\/p>\n<p><img decoding=\"async\" class=\"lazyload alignnone wp-image-5605 size-full\" src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer.png\" data-orig-src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer.png\" alt=\"\" width=\"956\" height=\"510\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27956%27%20height%3D%27510%27%20viewBox%3D%270%200%20956%20510%27%3E%3Crect%20width%3D%27956%27%20height%3D%27510%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-srcset=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-200x107.png 200w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-300x160.png 300w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-400x213.png 400w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-600x320.png 600w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-768x410.png 768w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer-800x427.png 800w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/UltraLeapVisualizer.png 956w\" data-sizes=\"auto\" data-orig-sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/p>\n<p>Die erste Frage ist: Werden wir die C-API richtig nutzen k\u00f6nnen? Dann sehen wir uns an, wie man es in Python verwendet. Also, auf geht&#8217;s zur Schatzsuche!<\/p>\n<p>Nach der Installation werden Beispiele f\u00fcr die C-API im samples-Ordner des sdk bereitgestellt. Um das Zeug unter Windows zu bauen, brauchst du au\u00dferdem <a href=\"https:\/\/cmake.org\/download\/\" target=\"_blank\" rel=\"noreferrer noopener\">cmake<\/a>. Nach der Installation von cmake \u00f6ffnest du eine Shell und gehst in den Samples-Ordner (vielleicht kopierst du zuerst das gesamte SDK an einen geeigneten Ort&#8230;) und gibst ein:<\/p>\n<pre class=\"wp-block-code\"><code>cmake .\ncmake --build .<\/code><\/pre>\n<p>Das sollte reichen. Dann noch einen Ordner &#8222;Debug&#8220; erstellen, in dem sich die ausf\u00fchrbaren Dateien befinden. Das Ausf\u00fchren der <em>PollingSample.exe<\/em> in einer Shell zeigt das:<\/p>\n<div id=\"attachment_5606\" style=\"width: 1012px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-5606\" class=\"lazyload wp-image-5606 size-full\" src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample.png\" data-orig-src=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample.png\" alt=\"\" width=\"1002\" height=\"600\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%271002%27%20height%3D%27600%27%20viewBox%3D%270%200%201002%20600%27%3E%3Crect%20width%3D%271002%27%20height%3D%27600%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-srcset=\"https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-200x120.png 200w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-300x180.png 300w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-400x240.png 400w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-600x359.png 600w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-768x460.png 768w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample-800x479.png 800w, https:\/\/pib.rocks\/wp-content\/uploads\/2023\/03\/PollingExample.png 1002w\" data-sizes=\"auto\" data-orig-sizes=\"(max-width: 1002px) 100vw, 1002px\" \/><p id=\"caption-attachment-5606\" class=\"wp-caption-text\">Arm-Koordinaten programmatisch erfasst: funktioniert!<\/p><\/div>\n<h2>Python ctypes Problem: Hilfe ben\u00f6tigt!<\/h2>\n<p>Unsere Hauptsteuerungssprache ist bisher Python, also liegt der Gedanke nahe, ein kleines C-Programm zu verwenden, um Daten von unserem LeapMotion abzurufen und diese Daten mit <a href=\"https:\/\/docs.python.org\/3\/library\/ctypes.html\" target=\"_blank\" rel=\"noreferrer noopener\">ctypes<\/a> in Python zu \u00fcbertragen. Ich habe die Sache unter Windows mit den VS-Tools ausprobiert, hm&#8230; Hat nicht wirklich funktioniert. Ich werde das so schnell wie m\u00f6glich unter Linux ausprobieren, aber bis dahin haben wir uns einen Hack ausgedacht:<\/p>\n<h2>LeapMotion-Daten als json<\/h2>\n<p>Da ich ungeduldig bin, dieses Zeug zu testen, ist die Idee (bis wir etwas haben, das das richtig macht), alle Koordinaten in einem C-Programm zu erhalten und eine Dateischnittstelle zu benutzen, um sie als json zu schreiben. Unser pib-steering-python kann einen <a href=\"https:\/\/pypi.org\/project\/watchdog\/\" target=\"_blank\" rel=\"noreferrer noopener\">Watchdog<\/a> verwenden, um auf Aktualisierungen in dieser Datei zu warten und pibs-Motoren zu aktualisieren, wenn ein Datei-\u00c4nderungsereignis eintritt. Weil es so einfach ist, hat es funktioniert! <a href=\"https:\/\/github.com\/goingTRYBal\/pibPollingJSON\" target=\"_blank\" rel=\"noreferrer noopener\">Hier <\/a>ist der C-Code f\u00fcr den Polling-Ansatz. Du kannst es bauen, wenn du die Datei zum samples-folder und der CMakeLists.txt hinzuf\u00fcgst und dann cmake wie oben gezeigt verwendest. Eine .exe wird in deinem Debug-Ordner erscheinen&#8230;<\/p>\n<p>Willst du sehen, wie die Ergebnisse bis jetzt aussehen? pib zeigt es dir in unserem neuesten Video!<\/p>\n<\/div><div class=\"fusion-video fusion-youtube\" style=\"--awb-max-width:600px;--awb-max-height:360px;\"><div class=\"video-shortcode\"> <div class=\"brlbs-cmpnt-container brlbs-cmpnt-content-blocker brlbs-cmpnt-with-individual-styles\" data-borlabs-cookie-content-blocker-id=\"youtube-content-blocker\" data-borlabs-cookie-content=\"PGxpdGUteW91dHViZSB2aWRlb2lkPSJSVzdfMndfWFFsOCIgY2xhc3M9ImxhbmRzY2FwZSBsdHktbG9hZCIgcGFyYW1zPSJ3bW9kZT10cmFuc3BhcmVudCZhdXRvcGxheT0xJmFtcDtlbmFibGVqc2FwaT0xIiB0aXRsZT0iWW91VHViZSB2aWRlbyBwbGF5ZXIgMSIgZGF0YS1idXR0b24tbGFiZWw9IlBsYXkgVmlkZW8iIHdpZHRoPSI2MDAiIGhlaWdodD0iMzYwIiBkYXRhLXRodW1ibmFpbC1zaXplPSJhdXRvIiBkYXRhLW5vLWNvb2tpZT0ib24iPjwvbGl0ZS15b3V0dWJlPjxzY3JpcHQgZGF0YS1ib3JsYWJzLWNvb2tpZS1zY3JpcHQtYmxvY2tlci1pZ25vcmU+CihmdW5jdGlvbigpIHsKICAgIGNvbnN0IGZ1c2lvblZpZGVvID0gZG9jdW1lbnQuY3VycmVudFNjcmlwdC5jbG9zZXN0KCcuZnVzaW9uLXZpZGVvJyk7CiAgICBpZiAoIWZ1c2lvblZpZGVvIHx8IHR5cGVvZiBqUXVlcnkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgIWpRdWVyeShmdXNpb25WaWRlbykucGFyZW50cygiLmZ1c2lvbi1tb2RhbCIpLmxlbmd0aCAmJiAxID09IGpRdWVyeShmdXNpb25WaWRlbykuZGF0YSgiYXV0b3BsYXkiKSAmJiBqUXVlcnkoZnVzaW9uVmlkZW8pLmlzKCI6dmlzaWJsZSIpICYmIGpRdWVyeShmdXNpb25WaWRlbykuZmluZCgiaWZyYW1lIikuZWFjaCgoZnVuY3Rpb24gKCkgewogICAgICBqUXVlcnkodGhpcykuaGFzQ2xhc3MoImxhenlsb2FkIikgPyBqUXVlcnkodGhpcykub24oImxhenlsb2FkZWQiLCAoZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMuY29udGVudFdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKGpRdWVyeSh0aGlzKS5hdHRyKCJkYXRhLW9yaWctc3JjIikucmVwbGFjZSgiYXV0b3BsYXk9MCIsICJhdXRvcGxheT0xIikpCiAgICAgIH0pKSA6IGpRdWVyeSh0aGlzKS5hdHRyKCJzcmMiLCBqUXVlcnkodGhpcykuYXR0cigic3JjIikucmVwbGFjZSgiYXV0b3BsYXk9MCIsICJhdXRvcGxheT0xIikpCiAgICB9KSkKfSkoKTsKPC9zY3JpcHQ+\"><div class=\"brlbs-cmpnt-cb-preset-c brlbs-cmpnt-cb-youtube\"> <div class=\"brlbs-cmpnt-cb-thumbnail\" style=\"background-image: url('https:\/\/pib.rocks\/wp-content\/uploads\/borlabs-cookie\/1\/brlbs-cb-youtube-main.png')\"><\/div> <div class=\"brlbs-cmpnt-cb-main\"> <div class=\"brlbs-cmpnt-cb-play-button\"><\/div> <div class=\"brlbs-cmpnt-cb-content\"> <p class=\"brlbs-cmpnt-cb-description\">Sie sehen gerade einen Platzhalterinhalt von <strong>YouTube<\/strong>. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfl\u00e4che unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.<\/p> <a class=\"brlbs-cmpnt-cb-provider-toggle\" href=\"#\" data-borlabs-cookie-show-provider-information role=\"button\">Mehr Informationen<\/a> <\/div> <div class=\"brlbs-cmpnt-cb-buttons\"> <a class=\"brlbs-cmpnt-cb-btn\" href=\"#\" data-borlabs-cookie-unblock role=\"button\">Inhalt entsperren<\/a> <a class=\"brlbs-cmpnt-cb-btn\" href=\"#\" data-borlabs-cookie-accept-service role=\"button\" style=\"display: inherit\">Erforderlichen Service akzeptieren und Inhalte entsperren<\/a> <\/div> <\/div> <\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":6785,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[80],"tags":[],"class_list":["post-7437","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pib-insights-de"],"_links":{"self":[{"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/posts\/7437","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/comments?post=7437"}],"version-history":[{"count":2,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/posts\/7437\/revisions"}],"predecessor-version":[{"id":7439,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/posts\/7437\/revisions\/7439"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/media\/6785"}],"wp:attachment":[{"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/media?parent=7437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/categories?post=7437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pib.rocks\/de\/wp-json\/wp\/v2\/tags?post=7437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}