Trebuchet MOC (Pybricks)

Für die Robotmak3rs Powered Up Remix Challenge habe ich aus dem LEGO Technic 42160 Audi RS Q e-tron ein Trebuchet gebaut. Es kann entweder alleine, oder mit einem zusätzlichen Farb- und Abstandssensor, und/oder mit der Powered Up Fernbedienung genutzt werden. Der Quellcode ist für Pybricks geschrieben. Außerdem gibt es eine Bauanleitung für das Modell.

Quellcode ohne Extras

Wird die grüne Taste des Hubs gedrückt, dann wird automatisch der Schussmechanismus ausgelöst und danach kehrt das Trebuchet zurück in die Ausgangsposition. Hier ist zu bedenken, dass der Mechanismus vorher in der "geladenen Ruheposition" und nicht in der "das Trebuchet wurde abgeschossen-Position" sein muss.

from pybricks.hubs import TechnicHub
from pybricks.pupdevices import Motor, Remote, ColorDistanceSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop, Axis
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch

hub = TechnicHub()

motorLeft = Motor(Port.A, Direction.CLOCKWISE)
motorRight = Motor(Port.B, Direction.COUNTERCLOCKWISE)
motorTurn = Motor(Port.D)

motorLeft.reset_angle(0)
motorRight.reset_angle(0)
motorTurn.reset_angle(0)
maxLight = 0
maxLightPosition = 0

#Trebouchet must be in "loaded" state
wait(500)
motorLeft.reset_angle(0)
motorRight.reset_angle(0)
#Throw the wheel (and accelerate doing so)
motorLeft.dc(60)
motorRight.dc(60)
wait(150)
motorLeft.dc(80)
motorRight.dc(80)
wait(150)
motorLeft.dc(100)
motorRight.dc(100)
#stop if the maximum motor position is reached
while (motorLeft.angle() <= 90 and motorRight.angle() <= 90):
    pass
motorLeft.brake()
motorRight.brake()
wait(100)
#return to position to load
motorLeft.run(-100)
motorRight.run(-100)
while (motorLeft.angle() >= 1 and motorRight.angle() >= 1):
    pass
motorLeft.brake()
motorRight.brake()

Quellcode mit Farb- und Abstandssensor

Mit der grünen Taste des Hubs wird der automatische Modus für den Farb- und Abstandssensor aktiviert. Hier sucht das Trebuchet automatisch den hellsten Punkt im Schussbereich. Neben der Ausgangsposition für den automatischen Schussmechanismus muss das Trebuchet außerdem in der Mitte sein, damit es sich frei so weit wie möglich nach links und nach rechts bewegen kann.
from pybricks.hubs import TechnicHub
from pybricks.pupdevices import Motor, Remote, ColorDistanceSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop, Axis
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch

hub = TechnicHub()

motorLeft = Motor(Port.A, Direction.CLOCKWISE)
motorRight = Motor(Port.B, Direction.COUNTERCLOCKWISE)
motorTurn = Motor(Port.D)
brightnessSensor = ColorDistanceSensor(Port.C)

motorLeft.reset_angle(0)
motorRight.reset_angle(0)
motorTurn.reset_angle(0)
maxLight = 0
maxLightPosition = 0

wait(500)
motorTurn.reset_angle(0)
motorTurn.run_target(100, -225, then=Stop.COAST, wait=True)
motorTurn.run(50)
while (motorTurn.angle() <= 225):
    if (maxLight < brightnessSensor.ambient()):
        maxLight = brightnessSensor.ambient()
        maxLightPosition = motorTurn.angle()
motorTurn.run(-50)
while(maxLightPosition < motorTurn.angle()):
    pass
motorTurn.brake()
#######################################
motorLeft.reset_angle(0)
motorRight.reset_angle(0)
#Throw the wheel (and accelerate doing so)
motorLeft.dc(60)
motorRight.dc(60)
wait(150)
motorLeft.dc(80)
motorRight.dc(80)
wait(150)
motorLeft.dc(100)
motorRight.dc(100)
#stop if the maximum motor position is reached
while (motorLeft.angle() <= 90 and motorRight.angle() <= 90):
    pass
motorLeft.brake()
motorRight.brake()
wait(100)
#return to position to load
motorLeft.run(-100)
motorRight.run(-100)
while (motorLeft.angle() >= 1 and motorRight.angle() >= 1):
    pass
motorLeft.brake()
motorRight.brake()

Quellcode mit Powered Up Fernbedienung

Wenn eine Fernbedienung genutzt wird, kann mit der den linken Tasten (Plus und Minus) der Fernbedienung der Abwurfmechanismus bewegt werden und mit den rechten Tasten (Plus und Minus) die Wurfrichtung.
Mit der linken roten Taste wird der Schussmechanismus wie mit dem ersten Quellcode in diesem Post ausgelöst. Die entsprechenden Hinweise sind zu bedenken. Mit der rechten roten Taste wird der automatische Schussmechanismus wie mit dem zweiten Quellcode ausgelöst. Auch dort sind die entsprechenden Hinweise zu beachten.

from pybricks.hubs import TechnicHub
from pybricks.pupdevices import Motor, Remote, ColorDistanceSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop, Axis
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch

hub = TechnicHub()
remote = Remote()

motorLeft = Motor(Port.A, Direction.CLOCKWISE)
motorRight = Motor(Port.B, Direction.COUNTERCLOCKWISE)
motorTurn = Motor(Port.D)
brightnessSensor = ColorDistanceSensor(Port.C)

motorLeft.reset_angle(0)
motorRight.reset_angle(0)
motorTurn.reset_angle(0)
maxLight = 0
maxLightPosition = 0

while True:
    buttons = remote.buttons.pressed()
    #if Button.LEFT_PLUS in buttons:
    #    motorLeft.dc()
    if Button.LEFT_PLUS in buttons:
        motorLeft.dc(60)
        motorRight.dc(60)
    elif Button.LEFT_MINUS in buttons:
        motorLeft.dc(-60)
        motorRight.dc(-60)
    elif Button.LEFT in buttons:
        #Trebouchet must be in "loaded" state
        motorLeft.reset_angle(0)
        motorRight.reset_angle(0)
        #Throw the wheel (and accelerate doing so)
        motorLeft.dc(60)
        motorRight.dc(60)
        wait(150)
        motorLeft.dc(80)
        motorRight.dc(80)
        wait(150)
        motorLeft.dc(100)
        motorRight.dc(100)
        #stop if the maximum motor position is reached
        while (motorLeft.angle() <= 90 and motorRight.angle() <= 90):
            pass
        motorLeft.brake()
        motorRight.brake()
        wait(100)
        #return to position to load
        motorLeft.run(-100)
        motorRight.run(-100)
        while (motorLeft.angle() >= 1 and motorRight.angle() >= 1):
            pass
        motorLeft.brake()
        motorRight.brake()

    else:
        motorLeft.dc(0)
        motorRight.dc(0)
    
    if Button.RIGHT_PLUS in buttons:
        #max Gradzahl: 486
        #Minus: Drehung richtung links
        #Plus: Drehung richtung rechts
        motorTurn.dc(60)
    elif Button.RIGHT_MINUS in buttons:
        motorTurn.dc(-60)
    elif Button.RIGHT in buttons:
        maxLight = 0
        motorTurn.reset_angle(0)
        motorTurn.run_target(100, -225, then=Stop.COAST, wait=True)
        motorTurn.run(50)
        while (motorTurn.angle() <= 225):
            if (maxLight < brightnessSensor.ambient()):
                maxLight = brightnessSensor.ambient()
                maxLightPosition = motorTurn.angle()
        motorTurn.run(-50)
        while(maxLightPosition < motorTurn.angle()):
            pass
        motorTurn.brake()
        #######################################
        #Throw wheel (same code as above)
        #Trebouchet must be in "loaded" state
        motorLeft.reset_angle(0)
        motorRight.reset_angle(0)
        #Throw the wheel (and accelerate doing so)
        motorLeft.dc(60)
        motorRight.dc(60)
        wait(150)
        motorLeft.dc(80)
        motorRight.dc(80)
        wait(150)
        motorLeft.dc(100)
        motorRight.dc(100)
        #stop if the maximum motor position is reached
        while (motorLeft.angle() <= 90 and motorRight.angle() <= 90):
            pass
        motorLeft.brake()
        motorRight.brake()
        wait(100)
        #return to position to load
        motorLeft.run(-100)
        motorRight.run(-100)
        while (motorLeft.angle() >= 1 and motorRight.angle() >= 1):
            pass
        motorLeft.brake()
        motorRight.brake()

    else:
        motorTurn.dc(0)
    #var, roll = hub.imu.tilt()
    #print(motorTurn.angle()) #, roll

Kommentare