Bemerkung
Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein.
Warum beitreten?
Expertenunterstützung: Lösen Sie Probleme nach dem Kauf 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 Zugang zu neuen Produktankündigungen und Sneak Peeks.
Sonderrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.
👉 Bereit, mit uns zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!
(Beispiel) Blindfold-Wassermelonen-Zerschlagspiel
Einführung
Dieses Projekt erstellt ein interaktives Blindfold-Wassermelonen-Zerschlagspiel, bei dem sich Spieler mithilfe eines Joysticks auf einem 20×20-Meter-Raster bewegen und dabei auf die Richtungsanweisungen eines AI-Assistenten angewiesen sind. Das System integriert:
Joystick-Steuerung für die Bewegung des Spielers auf der X-/Y-Achse
AI-gestützte Führung mit OpenAI GPT-4
Text-to-Speech-Feedback mit Pico2Wave
Zufällige Zielgenerierung für die Position der Wassermelone
Interaktive Taste für die Schlagaktion
Der Spieler startet in der Mitte bei (0,0) und muss eine zufällig platzierte Wassermelone finden, wobei er sich ausschließlich auf die Audiohinweise des AI-Assistenten verlässt. Dadurch entsteht ein spannendes Spielerlebnis mit sensorischer Einschränkung.
Sie können verschiedene Eingabegeräte mit LLM-Modulen kombinieren, um interaktive AI-Spiele zu entwickeln. Siehe:
Was Sie benötigen
Für dieses Projekt werden die folgenden Komponenten benötigt:
COMPONENT |
PURCHASE LINK |
|---|---|
- |
|
- |
|
Raspberry Pi |
- |
Schaltplan
Verbinden Sie die Komponenten wie folgt mit dem Fusion HAT+:
API-Schlüssel erstellen und speichern
Gehen Sie zu OpenAI Platform und melden Sie sich an. Klicken Sie auf der Seite API keys auf Create new secret key.
Füllen Sie die Angaben aus (Owner, Name, Project und gegebenenfalls Berechtigungen) und klicken Sie dann auf Create secret key.
Sobald der Schlüssel erstellt wurde, kopieren Sie ihn sofort — später wird er nicht noch einmal angezeigt. Falls Sie ihn verlieren, müssen Sie einen neuen erstellen.
Erstellen Sie in Ihrem Projektordner (zum Beispiel:
/) eine Datei mit dem Namensecret.py:cd ~/ai-lab-kit/llm sudo nano secret.py
Fügen Sie Ihren Schlüssel wie folgt in die Datei ein:
# secret.py # Store secrets here. Never commit this file to Git. OPENAI_API_KEY = "sk-xxx"
Abrechnung aktivieren und Modelle prüfen
Bevor Sie den Schlüssel verwenden, öffnen Sie in Ihrem OpenAI-Konto die Seite Billing, hinterlegen Sie Ihre Zahlungsdaten und laden Sie ein kleines Guthaben auf.
Wechseln Sie anschließend zur Seite Limits, um zu prüfen, welche Modelle für Ihr Konto verfügbar sind, und kopieren Sie die genaue Modell-ID für die Verwendung im Code.
Beispiel ausführen
Code ausführen
cd ~/ai-lab-kit/llm sudo python3 llm_openai_blindfolded_game.py
Das Spiel spielen
Nach dem Start des Skripts wird die Wassermelone zufällig auf dem 20×20 Meter großen Spielfeld platziert. Bewegen Sie sich mit dem Joystick Schritt für Schritt und hören Sie auf die Richtungsanweisungen des AI-Assistenten.
Wenn Sie glauben, die Position der Wassermelone erreicht zu haben, drücken Sie die Taste, um zuzuschlagen. Stimmen Ihre Koordinaten exakt mit der Position der Wassermelone überein, gewinnen Sie das Spiel.
Spielmechanik verstehen
Koordinatensystem:
Das Spielfeld ist ein 20×20-Meter-Raster
Die Koordinaten reichen von (-10,-10) bis (10,10)
Positives X = Osten, negatives X = Westen
Positives Y = Süden, negatives Y = Norden (invertierte Y-Achse)
Der Mittelpunkt ist (0,0)
Bewegungsregeln:
Joystick nach rechts → X+1 (Osten)
Joystick nach links → X-1 (Westen)
Joystick nach oben → Y-1 (Norden)
Joystick nach unten → Y+1 (Süden)
Jede Bewegung verändert die Position um 1 Meter
Gewinnbedingung:
Der Spieler muss sich genau auf den Koordinaten der Wassermelone befinden
Drücken Sie die Taste, um an der aktuellen Position zu „zerschlagen“
Bei exakter Übereinstimmung endet das Spiel mit einer Siegmeldung
Rolle des AI-Assistenten:
Erhält sowohl die Koordinaten des Spielers als auch der Wassermelone
Gibt Richtungsanweisungen anhand der Himmelsrichtungen (N, NE, E, SE, S, SW, W, NW)
Gibt eine ungefähre Entfernung in Metern an
Hält die Antworten kurz, damit sie sich gut für die Audiowiedergabe eignen
Code
Hier ist das vollständige Python-Skript für das Blindfold-Wassermelonen-Zerschlagspiel:
from fusion_hat.llm import OpenAI
from secret import OPENAI_API_KEY
from fusion_hat.adc import ADC
from fusion_hat.pin import Pin
from fusion_hat.tts import Pico2Wave
import random, time
# Register OpenAI API
# openai.com
# Export your openai api key with :LLM_API_KEY
# export LLM_API_KEY=sk-xxxxxxxxxxxxxxxxx
# Setup TTS
tts = Pico2Wave()
tts.set_lang('en-US')
# Setup Joystick
btn_pin = Pin(17, mode=Pin.IN, pull=Pin.PULL_UP, bounce_time=0.05)
x_axis = ADC('A1')
y_axis = ADC('A0')
def MAP(x, in_min, in_max, out_min, out_max):
"""
Map a value from one range to another.
"""
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def activate():
global smash_tips
smash_tips = True
btn_pin.when_activated = activate
# Setup LLM
INSTRUCTIONS = "This is a blindfolded watermelon-smashing game. A point representing a watermelon is randomly generated within a 20x20 meter area with coordinates ranging from (-10,-10) to (10,10). The player starts from the origin (0,0) and moves using a joystick. Even if the player can't see anything, they press a button to perform a smash action. After smashing, you will receive the watermelon's and player's coordinates. You need to advise the player on the direction of the watermelon, like 'The watermelon is ten meters to your northeast.' If the smash coordinates match, the game ends. Your responses will be converted into speech via TTS, so please keep them brief, ideally within two sentences."
WELCOME = "Hello, I am Blindfolded Watermelon Smashing Game Assistant. Use the joystick to move and press the button to smash. I will guide you to find the watermelon. Good luck!"
llm = OpenAI(
api_key=OPENAI_API_KEY,
model="gpt-4o",
)
# Set how many messages to keep
llm.set_max_messages(20)
# Set instructions
llm.set_instructions(INSTRUCTIONS)
# Set welcome message
llm.set_welcome(WELCOME)
print(WELCOME)
# Define the map size and the joystick pins
watermelon_x, watermelon_y = random.randint(-10, 10), random.randint(-10, 10)
player_x, player_y = 0, 0
smash_tips = False
while True:
x_val = MAP(x_axis.read(), 0, 4095, -100, 100)
y_val = MAP(y_axis.read(), 0, 4095, -100, 100)
if x_val > 80:
player_x += 1
elif x_val < -80:
player_x -= 1
if y_val > 80:
player_y -= 1
elif y_val < -80:
player_y += 1
# Debug positions (commented out in actual game)
# print('Watermelon position: %d, %d ' % (watermelon_x, watermelon_y))
# print('Player position: %d, %d ' % (player_x, player_y))
time.sleep(0.3)
if smash_tips:
smash_tips = False
print("Smash!")
if (player_x, player_y) == (watermelon_x, watermelon_y):
print("Target hit!")
tts.say("Target hit!")
break
else:
input_text = f"Watermelon position: ({watermelon_x}, {watermelon_y}), Player position: ({player_x}, {player_y})"
# Response with stream
response = llm.prompt(input_text, stream=True)
string = ""
for next_word in response:
if next_word:
# print(next_word, end="", flush=True) # Uncomment for streaming display
string += next_word
# print("") # New line after streaming
print("AI: " + string)
tts.say(string)
print("Game over!")
Code verstehen
Text-to-Speech-Einrichtung
Das Spiel verwendet Pico2Wave für die Audioausgabe:
tts = Pico2Wave() tts.set_lang('en-US')
Dadurch werden die Textantworten der AI in gesprochene englische Anweisungen umgewandelt.
Verarbeitung der Joystick-Eingaben
Der Joystick verwendet zwei ADC-Kanäle zum Auslesen der X- und Y-Achse:
x_axis = ADC('A1') # Horizontale Bewegung y_axis = ADC('A0') # Vertikale Bewegung def MAP(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min # ADC-Wert von 0–4095 auf Bereich -100 bis 100 umrechnen x_val = MAP(x_axis.read(), 0, 4095, -100, 100) y_val = MAP(y_axis.read(), 0, 4095, -100, 100)
Taster mit Interrupt einrichten
Der Taster verwendet einen Interrupt-Callback für eine sofortige Reaktion:
btn_pin = Pin(17, mode=Pin.IN, pull=Pin.PULL_UP, bounce_time=0.05) def activate(): global smash_tips smash_tips = True btn_pin.when_activated = activate
Wenn der Taster gedrückt wird, setzt er
smash_tipsaufTrueund löst dadurch im Hauptprogramm die Schlagaktion aus.OpenAI-LLM-Konfiguration
Der AI-Assistent wird mit spezifischen Spielanweisungen konfiguriert:
INSTRUCTIONS = "This is a blindfolded watermelon-smashing game..." WELCOME = "Hello, I am Blindfolded Watermelon Smashing Game Assistant..." llm = OpenAI( api_key=OPENAI_API_KEY, model="gpt-4o", ) llm.set_max_messages(20) # Gesprächsverlauf speichern llm.set_instructions(INSTRUCTIONS) # Spielregeln festlegen llm.set_welcome(WELCOME) # Begrüßung festlegen
Verwaltung des Spielzustands
Das Spiel speichert die Positionen des Spielers und des Ziels:
# Zufällige Platzierung der Wassermelone watermelon_x, watermelon_y = random.randint(-10, 10), random.randint(-10, 10) # Spieler startet in der Mitte player_x, player_y = 0, 0 # Bewegungsschwellenwert (80 % Joystick-Auslenkung) if x_val > 80: player_x += 1 # Nach rechts bewegen elif x_val < -80: player_x -= 1 # Nach links bewegen if y_val > 80: player_y -= 1 # Nach oben bewegen (negatives Y) elif y_val < -80: player_y += 1 # Nach unten bewegen (positives Y)
Schlagaktion und AI-Antwort
Wenn der Taster gedrückt wird, überprüft das Spiel, ob ein Treffer vorliegt oder ob eine AI-Anweisung benötigt wird:
if smash_tips: smash_tips = False print("Smash!") if (player_x, player_y) == (watermelon_x, watermelon_y): print("Target hit!") tts.say("Target hit!") break # Spiel endet else: # Positionen an die AI senden input_text = f"Watermelon position: ({watermelon_x}, {watermelon_y}), Player position: ({player_x}, {player_y})" # Streaming-Antwort von der AI abrufen response = llm.prompt(input_text, stream=True) string = "" for next_word in response: if next_word: string += next_word print("AI: " + string) tts.say(string) # Anleitung aussprechen
Verarbeitung der Streaming-Antwort
Die AI-Antwort wird Wort für Wort verarbeitet, um eine mögliche Echtzeitanzeige zu ermöglichen:
response = llm.prompt(input_text, stream=True) string = "" for next_word in response: if next_word: # Zum Anzeigen während des Empfangs auskommentieren entfernen # print(next_word, end="", flush=True) string += next_word
Bewegungslogik mit Dead-Zone
Der Joystick hat eine Dead-Zone von 80 Einheiten, um unbeabsichtigte Bewegungen zu vermeiden:
# Bewegung nur, wenn der Joystick >80 % in eine Richtung gedrückt wird # Dies verhindert Drift aus der Mittelposition if x_val > 80: # Rechts elif x_val < -80: # Links if y_val > 80: # Oben elif y_val < -80: # Unten
Struktur der Spielschleife
Die Hauptschleife des Spiels führt kontinuierlich folgende Schritte aus:
Joystick-Position lesen
Spielerkoordinaten aktualisieren, wenn der Joystick bewegt wird
Prüfen, ob der Schlag-Taster gedrückt wurde
AI-Antworten verarbeiten, falls erforderlich
Audiofeedback über TTS ausgeben
Fehlerbehebung
Keine Reaktion vom Joystick
ADC-Verbindungen prüfen: A0 für Y-Achse, A1 für X-Achse
Stromversorgung prüfen: VCC an 3.3V, GND an Masse
ADC-Werte testen:
print(x_axis.read())sollte Werte von 0–4095 anzeigenSicherstellen, dass der Joystick zentriert ist (sollte etwa ~2048 anzeigen)
Kein Ton bei TTS
Audioausgabe prüfen:
sudo raspi-config→ System Options → AudioLautsprecher testen:
speaker-test -t sine -f 440Sicherstellen, dass Pico2Wave installiert ist:
pico2wave --helpLautstärke prüfen:
alsamixerAudio-Setup-Skript erneut ausführen:
sudo /opt/setup_fusion_hat_audio.sh
OpenAI-API-Fehler
API-Schlüssel in
secret.pyprüfenInternetverbindung testen:
ping 8.8.8.8Sicherstellen, dass die Abrechnung im OpenAI-Konto aktiviert ist
Prüfen, ob das Modell „gpt-4o“ für Ihr Konto verfügbar ist
Spieler bewegt sich zu schnell/langsam
Bewegungsschwelle anpassen (derzeit 80): höher = größere Joystick-Auslenkung erforderlich
Bewegungsschritt ändern (derzeit 1): z. B. 0.5 für feinere Steuerung
Wartezeit anpassen (derzeit 0.3 s): längere Zeit = langsamere Bewegung
AI-Antworten sind zu lang
Kürzere Antworten in den
INSTRUCTIONSfestlegenBeispiel hinzufügen: „Respond in 10 words or less.“
Begrenzung der Antwortlänge im Code implementieren
Dieses Blindfold-Wassermelonenspiel zeigt, wie physische Steuerungen, AI-gestützte Führung und Audiofeedback kombiniert werden können, um ein spannendes sensorisches Spielerlebnis zu schaffen, das räumliches Denken und Zuhörfähigkeiten herausfordert.