LEGO Control+ Lenkrad mit Pybricks Hub2Hub und SPIKE Prime

Kürzlich hat Pybricks eine Hub2Hub-Funktion hinzugefügt. Damit ist es möglich, in Python-Programmen für die LEGO Powered Up Hubs Nachrichten über Bluetooth (BLE) von einem Hub zum nächsten zu schicken. Ein Kommentar in einem LEGO-Fanblog hat mich zu der Idee gebracht, ein Lenkrad für Control+-Fahrzeuge zu bauen. Für dieses Projekt nutze ich neben einem mit dem SPIKE Prime Set selbstgebauten Lenkrad mit Gaspedal den LEGO Technic Control+ 42124 Off-Road Buggy als Objekt, das ferngesteuert werden soll. Falls du selbst nicht die Programmiersprache Python beherrschst, gibt es weiter unten in diesem Text zusätzlich ein vergleichbares Programm in der Powered Up App geschrieben.

Technische Grenzen

Pybricks nutzt für die Hub2Hub Funktion sogenannte Broadcast-Nachrichten. Dabei wird ein Befehl "in die Welt hinaus gerufen". Alle Hubs in der Nähe empfangen die Nachrichten. Ohne weitere Tricks (z.B. indem eine Adresse als ein Teil der Nachricht mitgeschickt wird) ist es für die empfangenden Hubs nicht möglich, zu entscheiden, für welchen Hub die Nachricht geschickt wurde.
Außerdem gibt es aufgrund des BLE-Standards starke Einschränkungen für die Länge der BLE Nachricht bzw. die Anzahl der sendbaren Daten. In dem Fall der Pybricks Hub2Hub Befehle stehen 26 Byte zur Verfügung. Das sind Zeichenketten, also Sätze, mit 25 Buchstaben, oder 5 Zahlen.

Das Modell

Da es mir bei diesem Projekt hauptsächlich darum ging, die Hub2Hub Möglichkeiten von Pybricks auszuprobieren, ist das Modell relativ einfach geworden. So schön wie auf dem Vorschaubild für den Post sieht das finale Produkt leider nicht aus.
Die Drehung des Lenkrads kann über den Winkelpositionssensor des Motors die Position messen (-180° bis 179°). Das Gaspdeal ist über einen Kraftsensor umgesetzt, der bis zu 10 Newton messen kann. Um die Richtung des ferngesteuerten Fahrzeugs umdrehen zu können, damit der Buggy auch rückwärts fahren kann, werden die beiden Tasten des SPIKE Prime Hubs genutzt - eine Art Gangschaltung. Der SPIKE Prime Hub liest außerdem die beiden Sensoren in Motor und Kraftsensor aus und schickt die gemessenen Werte an den Buggy.
Damit der Motor nicht zu weit gedreht wird, sodass der Wert von 179° auf -180° springen würde, ist der Bewegungsbereich des Motors zwischen -100 und 100 Grad begrenzt. Wird der Wert überschritten, dreht sich der Motor von selbst wieder in den Bereich.

Quellcode (geschrieben mit Pybricks)

Bisher unterstützt nur die aktuelle BETA-Version von Pybricks die Hub2Hub-Funktion. Es wird mindestens die Version 3.3 vorausgesetzt.

Quellcode für die Steuerung/ das Lenkrad mit dem SPIKE Prime Hub:
from pybricks.hubs import PrimeHub
from pybricks.pupdevices import *
from pybricks.parameters import *
from pybricks.tools import wait

#broadcast to ble channel 1
hub = PrimeHub(broadcast_channel=1)
steering_motor = Motor(Port.A)
acceleration_sensor = ForceSensor(Port.E)

direction = 1

while True:
    pressed = hub.buttons.pressed()
    #change direction depending on buttons (force sensor can't have negative values)
    #aka "switch gears" between reverse and forwards
    if Button.LEFT in pressed:
        direction = -1
    elif Button.RIGHT in pressed:
        direction = 1
   
    #read and calculate values for acceleration and steering data
    steering = steering_motor.angle()
    #force sensor max value is 10 Newton, not 100 percent
    acceleration = acceleration_sensor.force() * 10 * direction

    #move motor to right angles if it steered too far
    if (steering > 100):
        steering_motor.track_target(95)
    elif (steering < -100):
        steering_motor.track_target(-95)
    #make sure that the motor is easy to move otherwise
    else:
        steering_motor.brake()
   
    #send BLE data to other hub
    hub.ble.broadcast(-acceleration, -steering)
    #broadcasts are only sent every 100ms. No reason to send more data
    wait(100)



Quellcode für das Fahrzeug mit dem Control+ Hub:
from pybricks.hubs import TechnicHub
from pybricks.pupdevices import *
from pybricks.parameters import *
from pybricks.tools import wait

#observe BLE channel 1
hub = TechnicHub(observe_channels=[1])
steering = Motor(Port.B)
driving = Motor(Port.A)

#steering calibration sequence
steering.run_until_stalled(500)
steering.reset_angle(0)
steering.run_until_stalled(-500)
maxAngle = steering.angle()
steering.run_target(500, (maxAngle/2)+10)
steering.reset_angle(0)

#main loop
while True:
    #receive ble data from remote
    data = hub.ble.observe(1)

    if data is None:
        pass
    else:
        #commands to drive forwards or backwards
        driving.dc(data[0])

        #commands to steer
        steering.track_target(((maxAngle/2)-5)*data[1]/100)

    wait(100)

Das Programm für den Buggy basiert auf meinem und sollte mit Anpassen der Ports/Motoren relativ einfach für andere Control+ Fahrzeuge übernommen werden können.

Quellcode (geschrieben mit der Powered Up App)

Mit der Powered Up App muss der SPIKE Prime Hub durch einen anderen Hub ersetzt werden, da die App den Hub zum Zeitpunkt dieses Posts nicht unterstützt. Der Hub für die Fernbedienung muss als erster Hub verbunden sein und der Hub des Control+ Fahrzeugs als 2. Hub.



Weitere Ideen

Natürlich kann man das Konzept noch weiter verfeinern. Entweder kann man Fernsteuerungen für andere Sets bauen und programmieren (z.B. Control+ Kettenfahrzeuge oder die City-Züge), oder man baut eigene MOCs und kann für diese eine eigene, individuelle und optimal passende Fernsteuerung bauen.


Kommentare