Compare commits

..

No commits in common. "main" and "iqrobot" have entirely different histories.

3 changed files with 110 additions and 206 deletions

View file

@ -16,7 +16,7 @@ Importiere den Code entweder über die Shell
oder einen Git Client: oder einen Git Client:
- für Mac oder Windows: https://www.sourcetreeapp.com/ - für Mac oder Windows: https://www.sourcetreeapp.com/
Benutzername und Passwort für Makerlab eingeben Username und PW für Makerlab eingeben
Übersicht über Git Commands: https://ndpsoftware.com/git-cheatsheet.html#loc=workspace; Übersicht über Git Commands: https://ndpsoftware.com/git-cheatsheet.html#loc=workspace;

View file

@ -2,11 +2,13 @@
import math import math
from spike import PrimeHub, Motor, MotorPair, ColorSensor, MotionSensor, DistanceSensor from spike import PrimeHub, Motor, MotorPair, ColorSensor, MotionSensor
from spike.control import wait_for_seconds from spike.control import wait_for_seconds
print("Lade IQ-Bibliothek") HELLO = "HELLO IQ"
BRICKIES_BOT = "brickies"
BRICKIES_BOT_2 = "brickies_2"
BACKSTEIN_BOT = "backstein"
''' '''
Wir nutzen "Duck typing", dh wir schreiben hinter jede Variabel mit ':' die Klasse, zB `leftMotor: Motor` Wir nutzen "Duck typing", dh wir schreiben hinter jede Variabel mit ':' die Klasse, zB `leftMotor: Motor`
@ -14,38 +16,54 @@ damit man dann später auch wieder Code Completion hat bei Nutzung der Variablen
''' '''
class IQRobot: class IQRobot:
def __init__(self, hub: PrimeHub): def __init__(self, hub: PrimeHub, typ: str):
self.hub: PrimeHub = hub self.hub: PrimeHub = hub
self.typ=typ
# Radantrieb if self.typ==BACKSTEIN_BOT:
LEFT_MOTOR_PORT = 'E' # Radantrieb
RIGHT_MOTOR_PORT = 'F' LEFT_MOTOR_PORT = 'F'
RIGHT_MOTOR_PORT = 'B'
# Motoren für Aufsätze
FRONT_MOTOR_RIGHT_PORT = "E"
self.frontMotorRight: Motor = Motor(FRONT_MOTOR_RIGHT_PORT)
# Motoren für Aufsätze elif self.typ==BRICKIES_BOT:
FRONT_MOTOR_RIGHT_PORT = "B" # Radantrieb
FRONT_MOTOR_LEFT_PORT = "A" LEFT_MOTOR_PORT = 'E'
RIGHT_MOTOR_PORT = 'F'
# Motoren für Aufsätze
FRONT_MOTOR_RIGHT_PORT = "B"
FRONT_MOTOR_LEFT_PORT = "A"
self.frontMotorRight: Motor = Motor(FRONT_MOTOR_RIGHT_PORT)
self.frontMotorLeft: Motor = Motor(FRONT_MOTOR_LEFT_PORT)
self.bothFrontMotors: MotorPair = MotorPair(FRONT_MOTOR_LEFT_PORT, FRONT_MOTOR_RIGHT_PORT)
# Radius der Antriebsräder
self.rad_radius = 2.1
# Abstand zwischen Rädern (Mitte) und Vorderseite des Roboters
self.abstand_rad_front = 5.55
self.bothFrontMotors: MotorPair = MotorPair(FRONT_MOTOR_LEFT_PORT, FRONT_MOTOR_RIGHT_PORT) elif self.typ==BRICKIES_BOT_2:
self.linker_motor_vorne: Motor = Motor(FRONT_MOTOR_LEFT_PORT) # Radantrieb
self.linker_motor_vorne.set_stall_detection(stop_when_stalled=True) LEFT_MOTOR_PORT = 'E'
self.rechter_motor_vorne: Motor = Motor(FRONT_MOTOR_RIGHT_PORT) RIGHT_MOTOR_PORT = 'F'
self.rechter_motor_vorne.set_stall_detection(stop_when_stalled=True) # Radius der Antriebsräder
self.rad_radius = 2.9
# Abstand zwischen Rädern (Mitte) und Vorderseite des Roboters
self.abstand_rad_front = 8.5
self.linker_motor: Motor = Motor(LEFT_MOTOR_PORT) ## Allgemein ##
self.movementMotors: MotorPair = MotorPair(LEFT_MOTOR_PORT, RIGHT_MOTOR_PORT)
self.antrieb: MotorPair = MotorPair(LEFT_MOTOR_PORT, RIGHT_MOTOR_PORT)
# Radumfang neu berechnen und Motor konfigurieren # Radumfang neu berechnen und Motor konfigurieren
# Radius der Antriebsräder rad_umfang = 2 * math.pi * self.rad_radius
self.rad_radius = 2.1 self.movementMotors.set_motor_rotation(rad_umfang)
# Abstand zwischen Rädern (Mitte) und Vorderseite des Roboters self.leftMotor: Motor = Motor(LEFT_MOTOR_PORT)
self.abstand_rad_front = 5.55 self.rightMotor: Motor = Motor(RIGHT_MOTOR_PORT)
self.rad_umfang = 2 * math.pi * self.rad_radius #self.colorSensor: ColorSensor = ColorSensor(colorSensorPort)
self.antrieb.set_motor_rotation(self.rad_umfang) #self.frontMotorLeft: Motor = Motor("C")
self.motionSensor: MotionSensor = MotionSensor()
self.bewegungsSensor: MotionSensor = MotionSensor()
self.abstandsSensor: DistanceSensor = DistanceSensor("D")
def show(self, image: str): def show(self, image: str):
''' '''
@ -54,175 +72,93 @@ class IQRobot:
''' '''
self.hub.light_matrix.show_image(image) self.hub.light_matrix.show_image(image)
def strecke_gefahren(self):
''' def driveForward_for_sec(self, seconds: float):
Gibt die gefahrene Strecke basierend auf den Radumdrehungen zurück # Fahre die übergebene Anzahl seconds gerade aus
''' self.movementMotors.start()
return -self.linker_motor.get_degrees_counted()/360 * self.rad_umfang wait_for_seconds(seconds)
self.movementMotors.stop()
def drehe(self, grad=90, with_reset=True, speed=10): def getColorIntensity(self):
""" # Ermittele Farbintensität über den Farbsensor
Funktion um den Roboter auf der Stelle zu drehen (red, green, blue, colorIntensity) = self .colorSensor.get_rgb_intensity()
return colorIntensity
:param int grad: Grad um die der Roboter gedreht werden soll
mittels Vorzeichen +/- kann links oder rechts herum gedreht werden
:param bool with_reset: Parameter, um den Gierwinkel zurückzusetzen, Standard: True
"""
# ist überhaupt etwas zu tun für uns? d.h. grad ist enweder 0 oder 360 def drehe(self, grad=90, with_reset=True):
if grad == 0 or grad == 360 : if grad == 0 or grad == 360 :
print("nichts zu tun") print("nichts zu tun")
return return
# soll der Gierwinkel zurückgesetzt werden?
if with_reset: if with_reset:
self.bewegungsSensor.reset_yaw_angle() # Gierwinkel zurücksetzen self.motionSensor.reset_yaw_angle()
#steering = 100 if grad > 0 else -100 #steering = 100 if grad > 0 else -100
toleranz = 0 # Toleranz soll null sein. Kann erhöht werden, falls der Roboter sich unendlich dreht. toleranz = 0
aktuell = self.bewegungsSensor.get_yaw_angle() # Aktuelle Position aktuell = self.motionSensor.get_yaw_angle()
ziel = grad ziel = grad
steering = 100 if ziel > aktuell else -100 steering = 100 if ziel > aktuell else -100
self.antrieb.start(steering=steering, speed=speed) # Mit bestimmer Geschwindigkeit starten self.movementMotors.start(steering=steering, speed=10)
differenz = ziel - aktuell differenz = ziel - aktuell
print ("Start Ziel: {}, Aktuell: {}".format(ziel, aktuell)) print ("Start Ziel: {}, Aktuell: {}".format(ziel, aktuell))
# wiederhole solange der Grad der Drehung noch nicht erreicht ist
while abs(differenz) > toleranz : while abs(differenz) > toleranz :
aktuell = self.bewegungsSensor.get_yaw_angle() aktuell = self.motionSensor.get_yaw_angle()
differenz = ziel - aktuell differenz = ziel - aktuell
pass pass
self.movementMotors.stop()
# stoppe die Bewegung
self.antrieb.stop()
print ("Final Ziel: {}, Aktuell: {}".format(ziel, aktuell)) print ("Final Ziel: {}, Aktuell: {}".format(ziel, aktuell))
def fahre_gerade_aus(self, cm, speed=20):
"""
Funktion um den Roboter geradeaus fahren zu lassen
:param int cm: Strecke in cm, die der Roboter geradeaus fahren soll def fahre_gerade(self, cm):
:param int speed: Geschwindigkeit zum Fahren der Strecke, Standard: 20 if self.typ == "brickies":
""" cm = -cm
self.motionSensor.reset_yaw_angle()
self.movementMotors.start_tank(10, 10)
self.movementMotors.set_default_speed(10)
self.movementMotors.move(cm)
versatz = self.motionSensor.get_yaw_angle()
self.drehe(grad=-versatz)
# ist überhaupt etwas zu tun für uns? d.h. cm = 0
if cm == 0 :
print("nichts zu tun")
return
# wollen wir vorwärts oder rückwarts fahren? def fahre_gerade_geregelt(self, cm):
richtung = 1 if self.typ == "brickies":
if cm < 0: cm = -cm
richtung = -1 self.motionSensor.reset_yaw_angle()
speed = speed * richtung # Die Geschwindigkeit soll negativ sein, wenn wir rückwärts fahren self.movementMotors.start_tank(10, 10)
self.movementMotors.set_default_speed(10)
# Alles zurücksetzen sum_cm = 0
self.linker_motor.set_degrees_counted(0) while sum_cm < cm:
self.bewegungsSensor.reset_yaw_angle() self.movementMotors.move(1)
versatz = self.motionSensor.get_yaw_angle()
self.drehe(grad=-versatz)
self.motionSensor.reset_yaw_angle()
sum_cm = sum_cm + 1
# Mit irgendeiner Geschwindigkeit g>0 starten. Wert ist irrelevant self.movementMotors.move(cm - sum_cm)
self.antrieb.start_tank(10, 10)
self.antrieb.set_default_speed(10)
linker_speed=speed # Geschwindigkeit linker Motor
rechter_speed=speed # Geschwindigkeit rechter Motor
kp = 1.5 # Verstärkungsfaktor zur Regelung
ki = 1.0 # Integralfaktor zur Regelung
sum_cm = 0 # bereits gefahrene Strecke
versatz = 0 # aktueller Versatz
sum_versatz = 0 # Summe des Versatzes über Zeit
# wiederhole solange die gefahrene Strecke noch nicht erreicht ist
while sum_cm < cm * richtung:
wait_for_seconds(0.05) # Sonst wird das zu oft ausgeführt
sum_cm = self.strecke_gefahren() * richtung # Gefahrene Strecke, ggf. eben negativ machen
versatz = self.bewegungsSensor.get_yaw_angle() # Um wie viel sind wir falsch?
sum_versatz = sum_versatz + versatz
abweichung = (kp * versatz + ki * sum_versatz) / 100 # Abweichung berechnen, um zu korrigieren
linker_speed = speed * (1 - abweichung * richtung)
rechter_speed = speed * (1 + abweichung * richtung)
self.antrieb.start_tank_at_power(int(linker_speed), int(rechter_speed)) # Mit neuer Geschwindigkeit starten
#print("Versatz: " + str(versatz) + " , linker Speed: " + str(linker_speed) + ", rechter Speed: " + str(rechter_speed) + ", strecke: " + str(sum_cm))
self.antrieb.stop() # Stoppen
self.drehe(-versatz) # Da Versatz immer != 0, korrigieren
def fahre_mit_drehung(self, strecke1, grad, strecke2): def fahre_mit_drehung(self, strecke1, grad, strecke2):
"""
Funktion für eine Fahrt mit 1. Strecke, dann Drehung in der Mitte, dann 2. Strecke
Vereinfacht die Logik, da der Roboter durch die Drehung einen Versatz hat gegenüber einer
Strecke die mit dem Lineal ausgemessen wurde
"""
self.fahre_gerade_geregelt(strecke1 + self.abstand_rad_front) self.fahre_gerade_geregelt(strecke1 + self.abstand_rad_front)
self.drehe(grad) self.drehe(grad)
self.fahre_gerade_geregelt(strecke2 - self.abstand_rad_front) self.fahre_gerade_geregelt(strecke2 - self.abstand_rad_front)
def fahre_gerade_aus(self, cm,speed):
#deprecated self.motionSensor.reset_yaw_angle()
def fahre_gerade_aus_alt(self, cm: float, speed: int):
"""
Funktion zum gerade aus fahren mit Korrektur am Ende
Wird nicht mehr aktiv genutzt, da wir jetzt fahre_gerade_aus haben,
welche geregelt ist, und der Roboter daher nicht schief wird.
:param int cm: Zentimeter die gerade aus gefahren werden soll self.movementMotors.move_tank(amount=cm,left_speed=speed, right_speed=speed)
:param speed: Geschwindigkeit mit der gefahren wird drehung = self.motionSensor.get_yaw_angle()
"""
self.bewegungsSensor.reset_yaw_angle()
self.antrieb.move_tank(amount=cm,left_speed=speed, right_speed=speed)
drehung = self.bewegungsSensor.get_yaw_angle()
print(drehung) print(drehung)
if drehung > 0: if drehung > 0:
richtung = -1 richtung = -1
else: else:
richtung = 1 richtung = 1
while abs(drehung) > 2: while abs(drehung) > 2:
self.antrieb.move(amount=richtung * 0.1, steering=100) self.movementMotors.move(amount=richtung * 0.1, steering=100)
drehung = self.bewegungsSensor.get_yaw_angle() drehung = self.motionSensor.get_yaw_angle()
print(drehung) print(drehung)
def heber(self, cm,speed):
"""
Lässt den Heber fahren
:param speed: Geschwindigkeit, mit der der Heber bewegt wird
:param cm: Um wie viel soll der Heber bewegt werden?
"""
self.bothFrontMotors.move_tank(-cm*3.3,"cm", -speed, speed) # Heber bewegen
def schaufel(self,prozent, speed=20):
"""
Lässt die Schaufel fahren
:param prozent: Auf wie viel Prozent soll die Schaufel bewegt werden?
"""
volle_umdrehung=0.29
rotations=volle_umdrehung*prozent/100
#self.bothFrontMotors.move(rotations, unit='rotations',speed=20)
self.bothFrontMotors.move_tank(rotations, 'rotations', speed, -speed)
# TODO: Geregeltes Fahren ist noch nicht eingebaut
def fahre_bis_abstand(self, abstand: int, speed=30, geregelt=True):
"""
Nutzt den Abstandssensor, um zu fahren, bis ein Abstand erreicht ist
:param abstand: Abstand zum Objekt
:param speed: Geschwindigkeit, mit der gefahren wird
:param geregelt: Soll mit Regler gefahren werden?
"""
self.antrieb.start_at_power(speed)
abstand_gerade = self.abstandsSensor.get_distance_cm()
while abstand_gerade > abstand:
abstand_gerade = self.abstandsSensor.get_distance_cm()
print(str(abstand_gerade))
self.antrieb.stop()
print("Fertig geladen.")
print("successfully loaded the IQ Lego teams code :)")

58
main.py
View file

@ -27,11 +27,11 @@ def importFile(slotid=0, precompiled=False, module_name='importFile'):
with open("/projects/.slots","rt") as f: with open("/projects/.slots","rt") as f:
slots = eval(str(f.read())) slots = eval(str(f.read()))
print(slots) print(slots)
#print(os.listdir("/projects/"+str(slots[slotid]["id"]))) print(os.listdir("/projects/"+str(slots[slotid]["id"])))
with open("/projects/"+str(slots[slotid]["id"])+"/__init__"+suffix,"rb") as f: with open("/projects/"+str(slots[slotid]["id"])+"/__init__"+suffix,"rb") as f:
print("trying to read import program") print("trying to read import program")
program = f.read() program = f.read()
#print(program) print(program)
try: try:
os.remove("/"+module_name+suffix) os.remove("/"+module_name+suffix)
except: except:
@ -52,6 +52,14 @@ def importFile(slotid=0, precompiled=False, module_name='importFile'):
# Dateiname und Modulname sollten gleich sein, dann kann man Code Completion nutzen # Dateiname und Modulname sollten gleich sein, dann kann man Code Completion nutzen
importFile(slotid=6, precompiled=True, module_name="iqrobot") importFile(slotid=6, precompiled=True, module_name="iqrobot")
import iqrobot as iq import iqrobot as iq
print(iq.HELLO)
# Importiere Go Robot Code
#importFile(slotid=3, precompiled=True, module_name="gorobot")
#import gorobot as gr
#gr.exampleFour()
#gr.db.gyroRotation(90, 25, 35, 25)
################### Hauptcode #################################### ################### Hauptcode ####################################
''' '''
@ -66,54 +74,14 @@ dh auch an die Funktionen im importierten Code übergeben werde
hub = PrimeHub() hub = PrimeHub()
# Initialisiere Robot Klasse mit unseren Funktionen # Initialisiere Robot Klasse mit unseren Funktionen
iqRobot: iq.IQRobot = iq.IQRobot(hub) iqRobot: iq.IQRobot = iq.IQRobot(hub, typ=iq.BRICKIES_BOT)
# Führe Funktionen aus unser Robot Klasse aus: # Führe Funktionen aus unser Robot Klasse aus:
iqRobot.show('HAPPY') iqRobot.show('HAPPY')
iqRobot.fahre_mit_drehung(strecke1=10, grad=90, strecke2=10)
iqRobot.fahre_mit_drehung(strecke1=0, grad=-90, strecke2=10)
def huenchenaufgabe():
iqRobot.fahre_gerade_aus(40,60)
iqRobot.drehe(-40,True)
iqRobot.fahre_gerade_aus(20,60)
iqRobot.drehe(-20)
iqRobot.fahre_gerade_aus(55,60)
iqRobot.heber(10,30)
def hologram_alt():
iqRobot.fahre_gerade_aus(cm=75,speed=80)
iqRobot.drehe(45, False)
iqRobot.fahre_gerade_aus(cm=14,speed=70)
iqRobot.fahre_gerade_aus(cm=-13,speed=50)
iqRobot.drehe(-45, False)
iqRobot.fahre_gerade_aus(cm=-75,speed=50)
def druckmaschine():
iqRobot.fahre_gerade_aus(19,30)
iqRobot.drehe(-45)
iqRobot.fahre_gerade_aus(20,30)
iqRobot.fahre_gerade_aus(-15,30)
def hologram():
iqRobot.drehe(45)
iqRobot.fahre_gerade_aus(37.5,30)
iqRobot.drehe(45)
iqRobot.fahre_gerade_aus(15,30)
iqRobot.fahre_gerade_aus(-15,30)
def augmented_reality():
iqRobot.drehe(-135)
iqRobot.fahre_gerade_aus(42,30)
iqRobot.drehe(90)
iqRobot.fahre_gerade_aus(12,30)
iqRobot.schaufel(-100)
iqRobot.fahre_gerade_aus(-3,30)
iqRobot.drehe(90)
iqRobot.fahre_gerade_aus(20,30)
iqRobot.drehe(-90)
iqRobot.fahre_gerade_aus(5,20)
#iqRobot.fahre_gerade_aus(16, 20)
#iqRobot.drehe(38)
#iqRobot.fahre_gerade_aus(33,25)
iqRobot.schaufel(1600, speed=100 )
iqRobot.schaufel(-1600, speed=100 )