.. include:: /index.rst :start-after: start_hello_message :end-before: end_hello_message .. _py_homework_grading_demo: (Beispiel) Demo zur Hausaufgabenkorrektur mit Pan-Tilt-Kamera ============================================================================== **Einführung** Dieses Projekt erstellt einen interaktiven **AI-Hausaufgabenkorrektur-Assistenten**, der Computer Vision, künstliche Intelligenz und Robotik kombiniert. Das System: 1. **Erfasst Fotos** von handschriftlichen oder gedruckten Hausaufgaben mit einer Raspberry-Pi-Kamera 2. **Analysiert den Inhalt** mit dem Vision-Modell GPT-4 von OpenAI, um zu bestimmen, ob die Antworten korrekt sind 3. **Gibt physisches Feedback** über servogesteuerte Pan-Tilt-Kopfbewegungen: - *Nickt* bei richtigen Antworten - *Schüttelt den Kopf* bei falschen Antworten 4. **Verwendet eine einfache Interaktion**, die durch einen einzigen Tastendruck ausgelöst wird .. raw:: html Diese Demo zeigt, wie AI mit der physischen Welt interagieren kann, und schafft so ein anschauliches Lernwerkzeug, das sofortiges visuelles Feedback zur Richtigkeit von Hausaufgaben gibt. Sie können auch andere LLM-Module und Hardwarekomponenten verwenden, um eigene AI-gestützte Lernsysteme zu entwickeln. Siehe: * :ref:`py_online_llm` * :ref:`cpn_servo` * :ref:`cpn_camera_module` ---------------------------------------------- **Was Sie benötigen** Für dieses Projekt werden die folgenden Komponenten benötigt: .. list-table:: :widths: 30 20 :header-rows: 1 * - COMPONENT - PURCHASE LINK * - :ref:`cpn_servo` - |link_servo_buy| * - Pan-Tilt - * - :ref:`cpn_camera_module` - |link_camera_buy| * - :ref:`cpn_fusion_hat` - \- * - Raspberry Pi - \- * - Hausaufgabenbeispiel (gedruckt oder handschriftlich) - \- ---------------------------------------------- **Hardware-Einrichtung** Für eine komfortable Nutzung des Kameramoduls wird :ref:`assemble_fusion_hat_pan_tilt` empfohlen. .. note:: Durch die Montage des Pan-Tilt-Moduls können einige Pins verdeckt werden. Daher wird empfohlen, es nur bei Verwendung der Kamera zu montieren oder es nach der Montage außen anzubringen. .. image:: ../quick_start/img/gimbal_assemble.png ---------------------------------------------- .. include:: python_online_llms.rst :start-after: start_setup_openai :end-before: end_setup_openai ---------------------------------------------- **Code ausführen** #. Hausaufgabenbeispiel erstellen: - Schreiben oder drucken Sie eine einfache Mathematikaufgabe mit Antwort - Beispiel: "5 + 3 = 8" (richtig) oder "5 + 3 = 7" (falsch) - Achten Sie auf gut lesbare Handschrift oder einen klaren Druck #. Programm starten: .. code-block:: bash cd ~/ai-lab-kit/llm python3 llm_openai_homework.py #. Anweisungen auf dem Bildschirm folgen: - Positionieren Sie die Hausaufgabe unter der Kamera - Drücken Sie die User-Taste (USR) auf dem Fusion HAT+ - Beobachten Sie die Reaktion des Servos #. Erwartete Ausgabe: .. code-block:: text HOMEWORK GRADING DEMO ================================================== Instructions: 1. Place a homework question under the camera 2. Make sure the question AND answer are visible 3. Press the User Button (USR) on Fusion HAT to grade 4. The camera will take a photo 5. AI will grade the answer 6. Servo will nod (correct) or shake (incorrect) ================================================== Waiting for button press... ================================================== Button pressed - Starting grading process Taking photo... Photo captured Sending to AI for grading... AI response: CORRECT Answer is correct - nodding head ================================================== ---------------------------------------------- **Code** Hier ist das vollständige Python-Skript für die Demo zur Hausaufgabenkorrektur: .. raw:: html .. code-block:: python #!/usr/bin/env python3 """ Homework Grading Demo with Pan-Tilt Camera Press User Button to take photo, LLM grades, servo nods or shakes """ import time from fusion_hat.llm import OpenAI from fusion_hat.servo import Servo from fusion_hat.user_button import UserButton from picamera2 import Picamera2, Preview # ========== LLM SETTINGS ========== # Create a secret.py file with: OPENAI_API_KEY = "your-api-key-here" try: from secret import OPENAI_API_KEY except ImportError: print("ERROR: Please create a secret.py file with your OpenAI API key") print("Example content: OPENAI_API_KEY = 'sk-...'") exit() # LLM instructions for grading INSTRUCTIONS = """You are a homework grading assistant. When you see a photo of a homework question with an answer, determine if the answer is correct or incorrect. Respond with ONLY ONE WORD: - If the answer is CORRECT, respond: "CORRECT" - If the answer is INCORRECT, respond: "INCORRECT" Do not provide any other text, explanations, or justifications. Only respond with "CORRECT" or "INCORRECT".""" # Initialize LLM llm = OpenAI( api_key=OPENAI_API_KEY, model="gpt-4o" ) # Set LLM settings llm.set_max_messages(5) llm.set_instructions(INSTRUCTIONS) # ========== HARDWARE SETTINGS ========== PAN_CHANNEL = 2 # Horizontal servo for shaking head TILT_CHANNEL = 3 # Vertical servo for nodding head # Servo center positions TILT_CENTER = 0 # Looking straight ahead PAN_CENTER = 0 # Center position # ========== INITIALIZE HARDWARE ========== print("Initializing Homework Grading Demo...") print("-" * 50) # Initialize servos pan_servo = Servo(PAN_CHANNEL) tilt_servo = Servo(TILT_CHANNEL) # Center servos tilt_servo.angle(TILT_CENTER) pan_servo.angle(PAN_CENTER) time.sleep(1) print("Servos ready") # Initialize camera camera = Picamera2() camera_config = camera.create_preview_configuration(main={"size": (1280, 720)}) camera.configure(camera_config) camera.start_preview(Preview.QT) camera.start() time.sleep(2) print("Camera ready") # Initialize user button user_button = UserButton() print("User button ready") print("-" * 50) # ========== SERVO MOVEMENT FUNCTIONS ========== def nod_head(): """ Nodding head movement for "correct" """ # Look down tilt_servo.angle(15) time.sleep(0.2) # Look up tilt_servo.angle(-10) time.sleep(0.2) # Return to center tilt_servo.angle(TILT_CENTER) def shake_head(): """ Shaking head movement for "incorrect" """ # Look left pan_servo.angle(-20) time.sleep(0.15) # Look right pan_servo.angle(20) time.sleep(0.15) # Look left again pan_servo.angle(-15) time.sleep(0.15) # Return to center pan_servo.angle(PAN_CENTER) # ========== GRADING FUNCTION ========== def grade_homework(): """ Main grading function: take photo, send to LLM, move servo """ print("\nTaking photo...") # Capture image img_path = './homework.jpg' camera.capture_file(img_path) print("Photo captured") # Send to LLM for grading print("Sending to AI for grading...") prompt = "Look at this homework question and answer. Is the answer correct? Respond with only one word: 'CORRECT' or 'INCORRECT'." response = llm.prompt(prompt, image_path=img_path) response_text = response.strip().upper() print(f"AI response: {response_text}") # Move servo based on response if "INCORRECT" in response_text: print("Answer is incorrect - shaking head") shake_head() elif "CORRECT" in response_text: print("Answer is correct - nodding head") nod_head() else: print(f"Unexpected response: {response_text}") # ========== BUTTON CALLBACK ========== def on_button_click(): """ Called when user button is pressed """ print("\n" + "=" * 50) print("Button pressed - Starting grading process") grade_homework() print("=" * 50) # ========== MAIN DEMO ========== def main(): """ Main demo function """ print("\nHOMEWORK GRADING DEMO") print("=" * 50) print("Instructions:") print("1. Place a homework question under the camera") print("2. Make sure the question AND answer are visible") print("3. Press the User Button (USR) on Fusion HAT to grade") print("4. The camera will take a photo") print("5. AI will grade the answer") print("6. Servo will nod (correct) or shake (incorrect)") print("=" * 50) print("\nWaiting for button press...") # Set button callback user_button.set_on_click(on_button_click) # Keep program running try: while True: time.sleep(0.1) except KeyboardInterrupt: print("\nDemo stopped by user") # ========== CLEANUP ========== def cleanup(): """ Clean up resources """ print("\nCleaning up...") # Return servos to center tilt_servo.angle(TILT_CENTER) pan_servo.angle(PAN_CENTER) # Stop camera camera.stop() print("Demo ended") # ========== RUN DEMO ========== if __name__ == "__main__": try: main() finally: cleanup() ---------------------------------------------- **Code verstehen** 1. LLM-Konfiguration und Einrichtung Das System verwendet OpenAIs GPT-4o mit Vision-Funktionen zur Bildanalyse: .. code-block:: python # LLM importieren und initialisieren from fusion_hat.llm import OpenAI llm = OpenAI(api_key=OPENAI_API_KEY, model="gpt-4o") # Spezifische Anweisungen für konsistente Antworten festlegen INSTRUCTIONS = """You are a homework grading assistant...""" llm.set_instructions(INSTRUCTIONS) # Gesprächsverlauf begrenzen, um Tokens zu sparen llm.set_max_messages(5) 2. Hardware-Initialisierung Drei Hardwarekomponenten werden initialisiert: Servos, Kamera und Taste: .. code-block:: python # Servosteuerung für das Pan-Tilt-System pan_servo = Servo(PAN_CHANNEL) # Kanal 2 für horizontale Bewegung tilt_servo = Servo(TILT_CHANNEL) # Kanal 3 für vertikale Bewegung # Kameraeinrichtung mit Vorschau camera = Picamera2() camera_config = camera.create_preview_configuration(main={"size": (1280, 720)}) camera.configure(camera_config) camera.start_preview(Preview.QT) camera.start() # User-Taste für Interaktion user_button = UserButton() 3. Servo-Animationsfunktionen Natürlich wirkende Bewegungen zum Nicken und Kopfschütteln: .. code-block:: python def nod_head(): """Kopf-Nicken für 'richtige' Antworten""" tilt_servo.angle(15) # Nach unten schauen time.sleep(0.2) tilt_servo.angle(-10) # Nach oben schauen time.sleep(0.2) tilt_servo.angle(TILT_CENTER) # Zurück zur Mitte def shake_head(): """Kopf-Schütteln für 'falsche' Antworten""" pan_servo.angle(-20) # Nach links schauen time.sleep(0.15) pan_servo.angle(20) # Nach rechts schauen time.sleep(0.15) pan_servo.angle(-15) # Noch einmal nach links time.sleep(0.15) pan_servo.angle(PAN_CENTER) # Zurück zur Mitte 4. Bildaufnahme und AI-Analyse Der Hauptablauf für die Bewertung: .. code-block:: python def grade_homework(): # Bild von der Kamera aufnehmen img_path = './homework.jpg' camera.capture_file(img_path) # Bild mit spezifischem Prompt an das LLM senden prompt = "Look at this homework question and answer..." response = llm.prompt(prompt, image_path=img_path) response_text = response.strip().upper() # Antwort interpretieren und entsprechende Servo-Bewegung auslösen if "INCORRECT" in response_text: shake_head() elif "CORRECT" in response_text: nod_head() 5. Ereignisbehandlung der Taste Einfaches Callback-System für die Benutzerinteraktion: .. code-block:: python def on_button_click(): print("Button pressed - Starting grading process") grade_homework() # Callback der Taste zuweisen user_button.set_on_click(on_button_click) 6. Hauptanwendungsschleife Minimale Hauptschleife, die auf Tastendruck wartet: .. code-block:: python def main(): print("Waiting for button press...") user_button.set_on_click(on_button_click) # Programm läuft weiter, bis es unterbrochen wird try: while True: time.sleep(0.1) # Warten mit geringer CPU-Auslastung except KeyboardInterrupt: print("\nDemo stopped by user") 7. Ressourcenbereinigung Ordnungsgemäßes Herunterfahren: .. code-block:: python def cleanup(): # Servos in Neutralposition zurücksetzen tilt_servo.angle(TILT_CENTER) pan_servo.angle(PAN_CENTER) # Kamera stoppen camera.stop() ---------------------------------------------- **Fehlerbehebung** - Kein Modul namens ``picamera2`` Installieren Sie die benötigte Bibliothek: .. code-block:: bash sudo apt update sudo apt install python3-picamera2 - Kamera wird nicht erkannt 1. Kameraverbindung prüfen: sicherstellen, dass das Flachbandkabel korrekt eingesetzt ist 2. Kamera aktivieren: ``sudo raspi-config`` → Interface Options → Camera 3. Kamera separat testen: ``libcamera-hello`` - Servos bewegen sich nicht 1. Stromversorgung prüfen: Servos benötigen 5V 2. Überprüfen, ob die Servo-Kanäle mit dem Code übereinstimmen (Kanäle 2 und 3) 3. Servos separat mit einfachen Winkelbefehlen testen - AI reagiert nicht oder gibt Fehler aus 1. Prüfen, ob der API-Schlüssel in ``secret.py`` korrekt ist 2. Internetverbindung testen: ``ping 8.8.8.8`` 3. Sicherstellen, dass Ihr OpenAI-Konto über Guthaben verfügt 4. Prüfen, ob das Modell „gpt-4o“ in Ihrem Konto verfügbar ist - Falsche Servo-Bewegungen 1. Prüfen, ob Pan- und Tilt-Servo vertauscht sind 2. Winkelwerte in ``nod_head()`` und ``shake_head()`` anpassen 3. Servo-Mittelposition überprüfen (möglicherweise Kalibrierung erforderlich) - Bild zu unscharf oder zu dunkel 1. Für ausreichende Beleuchtung der Hausaufgabe sorgen 2. Kamerafokus einstellen (falls möglich) 3. Kamera etwa 15–30 cm über dem Papier positionieren 4. Für Handschrift einen gut sichtbaren Stift oder Marker verwenden - Taste reagiert nicht 1. Prüfen, ob die LED der User-Taste beim Drücken aufleuchtet 2. Sicherstellen, dass das Callback korrekt registriert ist 3. Taste mit einem einfachen ``print``-Testskript prüfen - AI liefert unerwartete Antworten 1. Prompt-Formatierung im Code überprüfen 2. Sicherstellen, dass im Bild sowohl Aufgabe als auch Antwort klar sichtbar sind 3. Zunächst sehr einfache Rechenaufgaben testen ---------------------------------------------- Diese Demo zur Hausaufgabenkorrektur zeigt, wie AI-Vision-Modelle mit physischer Hardware interagieren können, um spannende Lernerfahrungen zu schaffen, bei denen digitale Intelligenz mit greifbarem Feedback kombiniert wird.