.. note:: Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauche gemeinsam mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein. **Warum beitreten?** - **Expertenunterstützung**: Lösen Sie nach dem Kauf auftretende Probleme und technische Herausforderungen mit Hilfe unserer Community und unseres Teams. - **Lernen & Teilen**: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern. - **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugriff auf neue Produktankündigungen und exklusive Einblicke. - **Spezielle Rabatte**: Profitieren Sie von exklusiven Rabatten auf unsere neuesten Produkte. - **Festliche Aktionen und Gewinnspiele**: Nehmen Sie an Verlosungen und Feiertagsaktionen teil. 👉 Bereit, mit uns zu entdecken und zu kreieren? Klicken Sie auf [|link_sf_facebook|] und treten Sie noch heute bei! .. _py_action_gallery: 14. Aktionsgalerie ==================================== Dieses Beispiel bietet ein interaktives Menü, mit dem Sie eine Vielzahl vorprogrammierter Aktionen für PiCrawler auslösen können, darunter Winken, Händeschütteln, Kämpfen, Nicken, Liegestütze und mehr. **Code ausführen** .. raw:: html .. code-block:: cd ~/picrawler/examples sudo python3 14_action_gallery.py Nach dem Start des Programms wird eine nummerierte Liste der verfügbaren Aktionen im Terminal ausgegeben. Geben Sie die Nummer der gewünschten Aktion ein und drücken Sie **Enter**, um sie auszuführen. Drücken Sie erneut **Enter**, um die letzte Aktion zu wiederholen. Wenn **Strg+C** gedrückt wird, beendet sich das Programm sicher und der Roboter kehrt in eine sitzende Position zurück. **Code** .. note:: Sie können den folgenden Code **Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Navigieren Sie dazu zum Quellcode-Pfad wie ``picrawler\examples``. Nach dem Ändern des Codes können Sie ihn direkt ausführen, um das Ergebnis zu sehen. .. raw:: html .. code-block:: python from time import sleep BODY_LENGTH = 77 BODY_WIDTH = 77 BODY_DIAGONAL = 108.9 DELTA = 45 def sit(spider): spider.do_action('sit', speed=40) def stand(spider): spider.do_action('stand', speed=40) def look_up(spider): coords = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -76], [45, 0, -76], [45, 0, -38], [45, 45, -30]], ] for coord in coords: spider.do_step(coord, 60) def look_down(spider): coords = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -28], [45, 0, -40], [45, 0, -68], [45, 45, -76]], ] for coord in coords: spider.do_step(coord, 60) def dance(spider): spider.do_action('dance', speed=60) def wave_hand(spider): coords = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # wave hand [[45, 45, -70], [60, 0, 120], [45, 0, -60], [45, 45, -30]], [[45, 45, -70], [-20, 60, 120], [45, 0, -60], [45, 45, -30]], [[45, 45, -70], [60, 0, 120], [45, 0, -60], [45, 45, -30]], [[45, 45, -70], [-20, 60, 120], [45, 0, -60], [45, 45, -30]], # return to stand [[45, 45, -50], [45, 0, -30], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -40], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in coords: spider.do_step(coord, 58) def shake_hand(spider): coords = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # shake hand [[45, 45, -65], [5, 280, 80], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, 100], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, -10], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, 100], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, -10], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, 100], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 280, -10], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 100, 10], [45, 0, -60], [45, 45, -40]], [[45, 45, -65], [5, 100, 10], [45, 0, -60], [45, 45, -40]], # return to stand [[45, 45, -50], [45, 0, -30], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -40], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in coords: spider.do_step(coord, 52) def fighting(spider): ready = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # fighting ready [[45, 45, -40], [45, 0, -40], [50, 20, -20], [45, 45, -50]], [[45, 45, -40], [45, 0, -40], [40, 20, -45], [45, 45, -50]], [[45, 45, -40], [45, 0, -40], [60, 40, -60], [45, 45, -40]], # [[45, 45, -40], [45, 30, -30], [60, 40, -60], [45, 45, -40]], [[45, 45, -30], [45, 30, -30], [60, 40, -60], [60, 40, -60]], ] twist_butt = [ # twist butt [[55, 7, -30], [19, 48, -30], [77, 12, -60], [36, 63, -60]], [[19, 48, -30], [55, 7, -30], [36, 63, -60], [77, 12, -60]], # [[55, 7, -30], [19, 48, -30], [77, 12, -60], [36, 63, -60]], [[19, 48, -30], [55, 7, -30], [36, 63, -60], [77, 12, -60]], # [[40, 30, -30], [40, 30, -30], [60, 40, -60], [60, 40, -60]], # shrink [[40, 50, -30], [40, 50, -30], [60, 20, -60], [60, 20, -60]], ] pounce_bite = [ [[40, 40, -60], [20, 60, 110], [60, 60, -60], [60, 60, -60]], [[40, 40, -40], [20, 30, -40], [60, 60, -60], [60, 60, -60]], [[20, 60, 110], [20, 30, -60], [60, 60, -60], [60, 60, -60]], [[20, 30, -40], [20, 30, -40], [60, 60, -60], [60, 60, -60]], ] return_stand = [ [[45, 45, -50], [45, 0, -30], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -40], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in ready: spider.do_step(coord, 50) for coord in twist_butt: spider.do_step(coord, 52) sleep(0.2) for coord in pounce_bite: spider.do_step(coord, 40) sleep(0.1) sleep(1) for coord in return_stand: spider.do_step(coord, 52) def excited(spider): coords = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # [[45, 45, -30], [45, 0, -30], [45, 0, -30], [45, 45, -30]], [[45, 45, -80], [45, 0, -80], [45, 0, -80], [45, 45, -80]], [[45, 45, -30], [45, 0, -30], [45, 0, -30], [45, 45, -30]], [[45, 45, -80], [45, 0, -80], [45, 0, -80], [45, 45, -80]], [[45, 45, -30], [45, 0, -30], [45, 0, -30], [45, 45, -30]], [[45, 45, -80], [45, 0, -80], [45, 0, -80], [45, 45, -80]], # [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in coords: spider.do_step(coord, 40) sleep(0.08) def play_dead(spider): sit = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # [[45, 45, -10], [45, 0, -10], [45, 0, -10], [45, 45, -10]], ] play_dead = [ [[45, 45, 100], [45, 45, 100], [45, 45, 100], [45, 45, 100]], # [[45, 35, 60], [35, 45, 80], [35, 45, 80], [45, 35, 60]], [[35, 45, 80], [45, 35, 60], [45, 35, 60], [35, 45, 80]], [[45, 35, 60], [35, 45, 80], [35, 45, 80], [45, 35, 60]], [[35, 45, 80], [45, 35, 60], [45, 35, 60], [35, 45, 80]], [[45, 35, 60], [35, 45, 80], [35, 45, 80], [45, 35, 60]], [[35, 45, 80], [45, 35, 60], [45, 35, 60], [35, 45, 80]], [[45, 35, 60], [35, 45, 80], [35, 45, 80], [45, 35, 60]], [[35, 45, 80], [45, 35, 60], [45, 35, 60], [35, 45, 80]], [[45, 35, 60], [35, 45, 80], [35, 45, 80], [45, 35, 60]], [[35, 45, 80], [45, 35, 60], [45, 35, 60], [35, 45, 80]], # [[45, 45, 100], [45, 45, 100], [45, 45, 100], [45, 45, 100]], ] return_stand = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in sit: spider.do_step(coord, 60) for coord in play_dead: spider.do_step(coord, 55) for coord in return_stand: spider.do_step(coord, 60) def nod(spider): stand = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] nod = [ [[45, 45, -80], [45, 0, -50], [45, 0, -20], [45, 45, -30]], [[45, 45, -20], [45, 0, -36], [45, 20, -52], [40, 20, -80]], [[45, 45, -80], [45, 0, -50], [45, 0, -20], [45, 45, -30]], [[45, 45, -20], [45, 0, -36], [45, 20, -52], [40, 20, -80]], [[45, 45, -80], [45, 0, -50], [45, 0, -20], [45, 45, -30]], ] return_stand = [ [[45, 45, -80], [45, 0, -50], [45, 0, -40], [45, 45, -40]], [[45, 45, -60], [45, 0, -50], [45, 0, -40], [45, 45, -40]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in stand: spider.do_step(coord, 60) for coord in nod: spider.do_step(coord, 45) sleep(.2) for coord in return_stand: spider.do_step(coord, 50) sleep(1) def shake_head(spider): ready = [ # stand [[45, 45, -50], [45, 0, -50], [45, 20, -50], [45, 45, -50]], [[45, 45, -50], [45, 20, -30], [45, 20, -50], [45, 45, -50]], [[45, 45, -50], [45, 45, -50], [45, 20, -50], [45, 45, -50]], ] twist_butt = [ # twist butt [[55, 7, -50], [19, 48, -50], [77, 12, -50], [36, 63, -50]], [[19, 48, -50], [55, 7, -50], [36, 63, -50], [77, 12, -50]], # [[51, 15, -50], [27, 43, -50], [72, 22, -50], [45, 56, -50]], [[27, 43, -50], [51, 15, -50], [45, 56, -50], [72, 22, -50]], # [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], ] return_stand = [ [[45, 45, -50], [45, 20, -30], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in ready: spider.do_step(coord, 50) for coord in twist_butt: spider.do_step(coord, 58) sleep(.5) for coord in return_stand: spider.do_step(coord, 52) def look_left(spider): stand = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] look_left = [ [[45, 0, -50], [45, 45, -50], [45, 45, -50], [45, 0, -50]], [[0, 45, -50], [45, 45, -50], [45, 45, -50], [45, 0, -50]], [[0, 45, -50], [45, 45, -35], [45, 45, -50], [45, 0, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in stand: spider.do_step(coord, 50) for coord in look_left: spider.do_step(coord, 50) def look_right(spider): stand = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] look_right = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [0, 45, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -35], [0, 45, -50], [45, 0, -50], [45, 45, -50]], [[45, 0, -50], [45, 45, -50], [45, 45, -50], [45, 0, -50]], ] for coord in stand: spider.do_step(coord, 50) for coord in look_right: spider.do_step(coord, 50) def warm_up(spider): stand = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], ] left_right = [ [[45, 37, -85], [45, 37, -14], [45, 37, -14], [45, 37, -85]], [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], [[45, 37, -85], [45, 37, -14], [45, 37, -14], [45, 37, -85]], [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], # [[45, 37, -14], [45, 37, -85], [45, 37, -85], [45, 37, -14]], [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], [[45, 37, -14], [45, 37, -85], [45, 37, -85], [45, 37, -14]], [[45, 45, -50], [45, 45, -50], [45, 45, -50], [45, 45, -50]], ] clockwise = [] clockwise.append(spider.move_list.move_body_absolute(0, 25, 10)) clockwise.append(spider.move_list.move_body_absolute(12.5, 21.65, 10)) clockwise.append(spider.move_list.move_body_absolute(21.65, 12.5, 10)) clockwise.append(spider.move_list.move_body_absolute(25, 0, 10)) clockwise.append(spider.move_list.move_body_absolute(21.65, -12.5, 10)) clockwise.append(spider.move_list.move_body_absolute(12.5, -21.65, 10)) clockwise.append(spider.move_list.move_body_absolute(0, -25, 10)) clockwise.append(spider.move_list.move_body_absolute(-12.5, -21.65, 10)) clockwise.append(spider.move_list.move_body_absolute(-21.65, -12.5, 10)) clockwise.append(spider.move_list.move_body_absolute(-25, 0, 10)) clockwise.append(spider.move_list.move_body_absolute(-21.65, 12.5, 10)) clockwise.append(spider.move_list.move_body_absolute(-12.5, 21.65, 10)) clockwise.append(spider.move_list.move_body_absolute(0, 25, 10)) anticlockwise = [] anticlockwise.append(spider.move_list.move_body_absolute(0, 25, 10)) anticlockwise.append(spider.move_list.move_body_absolute(-12.5, 21.65, 10)) anticlockwise.append(spider.move_list.move_body_absolute(-21.65, 12.5, 10)) anticlockwise.append(spider.move_list.move_body_absolute(-25, 0, 10)) anticlockwise.append(spider.move_list.move_body_absolute(-21.65, -12.5, 10)) anticlockwise.append(spider.move_list.move_body_absolute(-12.5, -21.65, 10)) anticlockwise.append(spider.move_list.move_body_absolute(0, -25, 10)) anticlockwise.append(spider.move_list.move_body_absolute(12.5, -21.65, 10)) anticlockwise.append(spider.move_list.move_body_absolute(21.65, -12.5, 10)) anticlockwise.append(spider.move_list.move_body_absolute(25, 0, 10)) anticlockwise.append(spider.move_list.move_body_absolute(21.65, 12.5, 10)) anticlockwise.append(spider.move_list.move_body_absolute(12.5, 21.65, 10)) anticlockwise.append(spider.move_list.move_body_absolute(0, 25, 10)) return_stand = [ [[45, 45, -50], [45, 45, -40], [45, 0, -50], [45, 45, -50]], [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], ] for coord in stand: spider.do_step(coord, 50) sleep(0.5) for coord in left_right: spider.do_step(coord, 48) sleep(.3) for coord in clockwise: spider.do_step(coord, 58) sleep(.3) for coord in anticlockwise: spider.do_step(coord, 58) sleep(.3) for coord in return_stand: spider.do_step(coord, 50) def push_up(spider): ready = [ # stand [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], # [[60, 10, -60], [60, 0, -60], [20, 60, 10], [10, 65, -40]], [[70, 0, -76], [70, 0, -76], [0, 130, -40], [0, 130, -40]], ] push_up = [ [[70, 0, -40], [70, 0, -40], [0, 130, -40], [0, 130, -40]], [[70, 0, -76], [70, 0, -76], [0, 130, -40], [0, 130, -40]], [[70, 0, -40], [70, 0, -40], [0, 130, -40], [0, 130, -40]], [[70, 0, -76], [70, 0, -76], [0, 130, -40], [0, 130, -40]], [[70, 0, -40], [70, 0, -40], [0, 130, -40], [0, 130, -40]], [[70, 0, -76], [70, 0, -76], [0, 130, -40], [0, 130, -40]], ] for coord in ready: spider.do_step(coord,70) for coord in push_up: spider.do_step(coord, 35) sleep(0.1) actions_dict = { "sit": sit, "stand": stand, "wave_hand": wave_hand, "shake_hand": shake_hand, "fighting": fighting, "excited": excited, "play_dead": play_dead, "nod": nod, "shake_head": shake_head, "look_left": look_left, "look_right": look_right, "look_up": look_up, "look_down": look_down, "warm_up": warm_up, "push_up": push_up, } sounds_dict = { } if __name__ == "__main__": from picrawler import Picrawler my_spider = Picrawler() actions = list(actions_dict.keys()) for i, key in enumerate(actions): print(f'{i} {key}') last_key = None try: while True: key = input() if key == '': print(actions[last_key]) actions_dict[actions[last_key]](my_spider) else: key = int(key) if key > (len(actions) - 1): print("Invalid key") else: last_key = key print(actions[key]) actions_dict[actions[key]](my_spider) except KeyboardInterrupt: pass except Exception as e: print(f'Error:\n {e}') finally: my_spider.do_action("sit", speed=40) sleep(.1) **Wie funktioniert es?** #. Beim Programmstart wird ein Dictionary der verfügbaren Aktionen erstellt und ein nummeriertes Menü ausgegeben. .. code-block:: python actions_dict = { "sit": sit, "stand": stand, "wave_hand": wave_hand, "shake_hand": shake_hand, ... } for i, key in enumerate(actions): print(f'{i} {key}') Jeder Schlüssel in ``actions_dict`` ist ein lesbarer Name und jeder Wert ist eine Funktion. Dieses Muster macht es einfach, die richtige Funktion zu finden und aufzurufen, wenn der Benutzer eine Nummer eingibt. #. Interaktive Menüschleife .. code-block:: python while True: key = input() if key == '': actions_dict[actions[last_key]](my_spider) else: key = int(key) last_key = key actions_dict[actions[key]](my_spider) Die Hauptschleife wartet auf Benutzereingaben: - Geben Sie eine Nummer ein, um eine Aktion auszuwählen und sofort auszuführen. - Drücken Sie **Enter** (leere Eingabe), um die letzte Aktion zu wiederholen. - Drücken Sie **Strg+C** zum Beenden. #. Was ist ein Koordinatenschritt? Jede Pose ist als Liste von vier Beinkoordinaten im Format ``[[x, y, z], [x, y, z], [x, y, z], [x, y, z]]`` definiert, entsprechend: - Rechtes Vorderbein (Index 0) - Linkes Vorderbein (Index 1) - Linkes Hinterbein (Index 2) - Rechtes Hinterbein (Index 3) Jede Koordinate hat drei Werte: - **X**: Vorwärts-/Rückwärtsposition der Beinspitze - **Y**: Links-/Rechtsposition der Beinspitze - **Z**: Auf-/Ab-Position (negativer = höher oben) .. code-block:: python # Eine stehende Pose für alle vier Beine [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]] #. Abspielen einer Sequenz von Posen Die meisten Aktionen bestehen aus einer Liste von Koordinaten-Frames. Die Methode ``do_step()`` interpoliert die Servos sanft von der aktuellen Pose zur Zielpose. .. code-block:: python coords = [ [[45, 45, -50], [45, 0, -50], [45, 0, -50], [45, 45, -50]], [[45, 45, -76], [45, 0, -76], [45, 0, -38], [45, 45, -30]], ] for coord in coords: spider.do_step(coord, 60) Das zweite Argument von ``do_step()`` ist die **Geschwindigkeit** (höher = schneller). Typische Werte reichen von 40 (langsam) bis 80 (schnell). #. Eingebaute vs. benutzerdefinierte Aktionen Einige Funktionen verwenden eingebaute Aktionen über ``do_action()``: .. code-block:: python def sit(spider): spider.do_action('sit', speed=40) Andere konstruieren Posen manuell mit ``do_step()`` und geben Ihnen volle Kontrolle über die Haltung des Roboters. .. code-block:: python def wave_hand(spider): coords = [ [[45, 45, -70], [60, 0, 120], [45, 0, -60], [45, 45, -30]], [[45, 45, -70], [-20, 60, 120], [45, 0, -60], [45, 45, -30]], ] for coord in coords: spider.do_step(coord, 58) Die Winkbewegung wechselt das rechte Vorderbein zwischen zwei extremen Positionen und erzeugt so eine Winkgeste. #. Hinzufügen von Pausen zwischen Bewegungen Die Funktion ``sleep()`` fügt Pausen zwischen Bewegungsphasen ein. Dies ist nützlich für mehrphasige Aktionen wie ``fighting()`` oder ``nod()``: .. code-block:: python for coord in twist_butt: spider.do_step(coord, 52) sleep(0.2) for coord in pounce_bite: spider.do_step(coord, 40) sleep(0.1) sleep(1) for coord in return_stand: spider.do_step(coord, 52) Die Pausen lassen jede Phase visuell abschließen, bevor die nächste beginnt. #. Verwendung von ``move_body_absolute()`` für kreisförmige Bewegungen Die Funktion ``warm_up()`` demonstriert ``move_body_absolute()``, das den Körperschwerpunkt relativ zu den Füßen verschiebt: .. code-block:: python clockwise = [] clockwise.append(spider.move_list.move_body_absolute(0, 25, 10)) clockwise.append(spider.move_list.move_body_absolute(12.5, 21.65, 10)) ... Durch das Durchlaufen von Punkten auf einem Kreis (unter Verwendung von Sinus-/Kosinus-Werten) führt der Roboter eine kreisförmige Körperbewegung aus — eine Aufwärmübung, die alle Gelenke lockert. #. Sicherer Exit .. code-block:: python finally: my_spider.do_action("sit", speed=40) sleep(.1) Unabhängig davon, wie das Programm beendet wird (Strg+C oder Fehler), stellt der ``finally``-Block sicher, dass der Roboter in eine sichere sitzende Position zurückkehrt.