Mittwoch, 4. Dezember 2013

Weiter mit NXT-Python

Ich habe hier einmal ein sehr kleines und einfaches Beispiel für ein Programm geschrieben, dass die drei Motoren einmal um 360° nach vorne dreht. Dabei wird erst der Motor an Port A, dann der Motor an Port B und dann der Motor an Port C gedreht.

Hier einmal der Code mit allen erläuterungen:

#! -*- coding: utf8 -*-

""" (c) Hubble.Pixel """
""" Programm zum Testen des Lego Mindstorm NXT Bricks bei Gebrauch der Motoren an den Ports A/B/C. Debei muss immer sich gegangen werden, dass sich der NXT beim Model B des Raspberry Pis im unteren USB.Slot befindet/ beim Model A des Raspberry Pis am besten an einem angeschlosssenen USB-Hub angeschlossen ist und dass die .nxt-python - Datei richtig konfiguriert ist. """

import nxt # importiere das nxt-python-Modul

b = nxt.locator.find_one_brick() # initalisiere den Brick

portA = nxt.PORT_A # Port A initalisieren
portB = nxt.PORT_B # Port B initalisieren
portC = nxt.PORT_C # Port C initalisieren

vor = 100
zurueck = -100

All = 1 # Alle Motoren

motorA = nxt.motor.Motor(b, portA) # Motor A an Port A initalisieren
motorB = nxt.motor.Motor(b, portB) # Motor B an Port B initalisieren
motorC = nxt.motor.Motor(b, portC) # Motor C an Port C initalisieren

class EingabeFehler(Exception):
   print(Exception)

def drehen(Grad=None, Richtung=None, Motor=None):
   """Funktion zum drehen von den Motoren nacheinander (erst A, dann B und dann C)"""
   if (Richtung != None) and (Richtung == vor):
      richtung = int(Richtung)
   elif (Richtung != None) and (Richtung == zurueck):
      richtung = int(Richtung)
   else:
      raise EingabeFehler("Keine definierte Richtung, versuche entweder vor oder zurueck!")

   if (Grad != None) and (Grad > 0):
      """setzt den Wert, um den der Motor gedreht hat auf die angegebene Zahl"""
      grad = int(Grad)
   elif (Grad != None) and (Grad < 0):
      """falls der Wert, um den der Motor gedreht werden soll kleiner also Null ist, wird ein Fehler
      ausgespuckt"""
      raise EingabeFehler("Keine Gradangabe groesser als 0 angegeben!")
   elif (Grad != None) and (Grad == 0):
      """falls der Wert, um den der Motor gedreht werden soll gleich Null ist, wird ein Fehler ausgespuckt""
      raise EingabeFehler("Keine Gradangabe groesser als 0 angegeben!")
   else:
      raise EingabeFehler("Keine Gradangabe vorhanden, waehle bitte eine Angabe groesser als 0!")
      """wenn gar nichts angegeben wird, soll ebenfalls eine Fehlermeldung ausgegeben werden"""

   if (Motor != None) and (Motor == "motorA"):
      motorA.turn( richtung, grad)
      """vom nxt-Modul mitgeliferte Funktion zum drehen eines Motors (komplett (ohne Zuweisungen wie
      motor = motor.Motor.etc): nxt.motor.Motor( nxt.locator.find_one_brick(), nxt.PORT_A).turn( Richtung,
      Grad) )"""
   elif (Motor != None) and (Motor == "motorB"):
      motorB.turn( richtung, grad)
      """vom nxt-Modul mitgeliferte Funktion zum drehen eines Motors (komplett (ohne Zuweisungen wie
      motor = motor.Motor.etc): nxt.motor.Motor( nxt.locator.find_one_brick(), nxt.PORT_B).turn( Richtung,
      Grad) )"""
   elif (Motor != None) and (Motor == "motorC"):
      motorC.turn( richtung, grad)
      """vom nxt-Modul mitgeliferte Funktion zum drehen eines Motors (komplett (ohne Zuweisungen wie
      motor = motor.Motor.etc): nxt.motor.Motor( nxt.locator.find_one_brick(), nxt.PORT_C).turn( Richtung,
      Grad) )"""
   elif (Motor != None) and (Motor == All):
      """bei Eingabe von "All" werden alle Motoren gedreht, nacheinander"""
      motorA.turn( richtung, grad)
      motorB.turn( richtung, grad)
      motorC.turn( richtung, grad)
   else:
      raise EingabeFehler("Kein Motorport ausgewaehlt, nutze entweder motorA, motorB, motorC oder All!")
      """wenn kein Port oder All ausgewählt wurde, wird eine Fehlermeldung ausgegeben"""

drehen(360, vor, All)
"""startet einmal die Funktion drehen(). Dabei wird jeder Motor ("All") einmal um 360 Grad ("360") nach vorne ("vor" [-> entspricht dem Wert 100]) gedreht."""

Eigentlich sind alle Kommentare mit # eingeleitet, allerdings kann das Blogger nicht ganz so gut anzeigen, wegen den Zeilenumbrüchen, deswegen habe ich mehrzeilige Kommentare verwendet, eingeleitet mit """ und beendet auch wieder mit """.

Ich habe im ganzen Python-Dokument einmal eine Klasse "EingabeFehler" erstellt, die eigentlich den jeweiligen Fehler in der Kommandoleiste ausgeben sollte, allerdings hat das "print(Exception)" nicht immer funktioniert und deswegen müsste man einmal nachgucken, was falsch ist. Ich arbeite eigentlich nicht so oft mit Fehlern/ Fehlermeldungen (außer bei C++ mit cerr) und finde deswegen keine bessere Lösung :/

Bei mir auf meinem Raspberry Pi funktioniert das Programm auch nur, wenn ich es mit
sudo python Test.py
im Terminal aufrufe. Dazu hatte ich ja schon beim letzten Mal etwas gesagt (beim Einrichten von NXT-Python).

Anhand diesem, sehr einfachen, Beispiel kann man auch schon etwas eigenes, kreatives machen. Zum Beispiel kann man den Roboter in einem Viereck rollen lassen (erfordert ein Bisschen Know-How mit dem Drehen).
Wenn man so etwas einfaches bereits gemacht hat, oder dann damit fertig ist, werde ich beim nächsten Mal ein etwas schweres Beispiel mit Sensoren oder ähnlichem machen.

Ein gutes Beispiel ist ein Roboter, der mit einer konstanten Geschwindigkeit fährt und um wenige Millimeter vor einer Wand stehen bleiben soll. Dabei kann man noch Sachen wie Breite von Fußleisten einfließen lassen oder sich es etwas schwieriger machen, indem man Beispielsweise sagt, dass der Roboter gleichmäßig Bremsen soll (eine gleichmäßig beschleunigte Bewegung in negativer Richtung).

So, das wars ersteinmal für heute,
Mit Pixeligen Grüßen,
Hubbel