No description
  • GDScript 58%
  • Python 41.3%
  • Nix 0.7%
Find a file
Dennis Burgermeister 036bdf667a
Some checks failed
Tests and release contents / verify (push) Has been cancelled
(c) less logging
2026-11-05 14:26:01 +01:00
.github/workflows Prepare simulator source and Linux releases for publication 2026-10-30 08:57:17 +00:00
.vscode (c) mise/devcontainer to just/nix 2026-10-22 12:19:27 +02:00
artwork/d404_posters Prepare simulator source and Linux releases for publication 2026-10-30 08:57:17 +00:00
Assets (+) bumper kart 2026-11-04 11:42:34 +01:00
docs (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
examples (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
external (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
fleet_simulator (c) less logging 2026-11-05 14:26:01 +01:00
licenses Prepare simulator source and Linux releases for publication 2026-10-30 08:57:17 +00:00
scenes (f) bumper car: lock roll / pitch 2026-11-04 17:13:46 +00:00
spark-e@8006aa0c0a (c) less logging 2026-11-05 14:26:01 +01:00
tests (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
third_party/intsys_car_v1 (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
tools (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
.editorconfig (+) Initial Commit 2025-12-23 16:36:52 +01:00
.env.example (c) less logging 2026-11-05 14:26:01 +01:00
.gitattributes (+) Initial Commit 2025-12-23 16:36:52 +01:00
.gitignore (c) updates 2026-10-22 15:50:33 +02:00
.gitmodules (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
bumper_car_unity3d.zip (+) bumper kart 2026-11-04 11:42:34 +01:00
COPYRIGHT.md (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
export_presets.cfg (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
flake.lock (f) setup fixes 2026-10-30 02:23:02 +01:00
flake.nix (c) .env example 2026-10-30 20:25:54 +01:00
icon.svg (+) Initial Commit 2025-12-23 16:36:52 +01:00
icon.svg.import (+) Initial Commit 2025-12-23 16:36:52 +01:00
LICENSE Prepare simulator source and Linux releases for publication 2026-10-30 08:57:17 +00:00
main.gd (+) bumper kart 2026-11-04 11:42:34 +01:00
main.gd.uid (+) PiCar X / WASD Control, Sample course 2026-10-09 04:31:11 +00:00
mise.toml (f) spark-e changes 2026-10-30 15:33:46 +01:00
project.godot (c) fixed car positions / styles 2026-10-31 16:27:09 +01:00
pytest.ini (c) fleet_manager -> spark-e 2026-10-30 02:06:15 +01:00
README.md (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
RELEASE.md (c) cleanup 2026-11-04 08:48:52 +01:00
requirements-release.txt Prepare simulator source and Linux releases for publication 2026-10-30 08:57:17 +00:00
requirements.txt (c) fleet_manager -> spark-e 2026-10-30 02:06:15 +01:00
run_fleet_server.py (c) less logging 2026-11-05 14:26:01 +01:00
SECURITY.md (f) spark-e changes 2026-10-30 15:33:46 +01:00
sim_car_client.py (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00
THIRD_PARTY_NOTICES.md (+) intsys_car_v1 0.0.8 als Submodul: Car, CarServer im Simulator 2026-11-04 17:40:26 +00:00

IntSys Kart & PiCar-X Simulator

Physikbasierter 3D-Simulator in Godot 4 mit virtuellen Sensoren und Aktoren für autonome Fahrroboter. Schülerprotokoll und virtuelle Python-API orientieren sich an intsys-car-v1 (SunFounder PiCar-X). Unterstützte Schnittstellen und Hardware-Unterschiede: Kompatibilität.

Schnellstart

Entwicklungsumgebung (MicroVM über flake.nix)

Die Umgebung ist eine MicroVM aus dem gemeinsamen nix-dev-sandbox-Flake (Profile desktop + godot): Godot 4.7.2 als offizielles Release, Mesa in Software-Rendering, die Python-Pakete aus requirements.txt aus Nix. Alle Ports liegen auf dem Host nur an 127.0.10.14.

  1. .env.example nach .env kopieren und DEV_SSH_PUBKEY, GIT_USER_NAME, GIT_USER_EMAIL eintragen.
  2. In ~/.ssh/config auf dem Host:
    Host intsys-kart-simulator-vm
      HostName 127.0.10.14
      Port 2200
      User dev
      ForwardX11 yes
    
  3. VM starten (auf dem Host) und verbinden:
    mise run vm
    ssh intsys-kart-simulator-vm
    
  4. Einmalig in der VM (Export-Templates, .godot-Cache):
    mise run setup
    

mise tasks listet alle Befehle (auf dem Host einmalig mise trust). Von außen erreichbar:

Dienst Adresse
Fleet Manager http://127.0.10.14:18080
Simulator-API 127.0.10.14:65433 (VM setzt SIM_BIND_ADDRESS=0.0.0.0)
Steuerungs-Server auf dem Host (Port 5555) aus der VM unter 10.0.2.2:5555

Das Flake setzt WEB_PORT=18080, SIM_PORT=65433, GODOT_PORT=65433, SIMULATOR_PORT=65433 und SPARK_FLEET_URL=ws://127.0.0.1:18080, damit auch separat gestartete Agenten und Python-Clients die Entwicklungsports verwenden. Werte aus .env bzw. CLI-Parameter überschreiben diese; die Portweiterleitungen müssen dann ebenfalls angepasst werden. Nach Änderungen am Flake die VM neu starten.

Ohne ssh -X öffnen sich Fenster im virtuellen Display :99 der VM. Ist Vulkan in Software zu langsam, in .env GODOT_ARGS="--rendering-method gl_compatibility" setzen.

Direkt auf dem Host (ohne VM) bereitet mise run setup auch die Python-Abhängigkeiten in einer lokalen .venv vor; mise run sim prüft sie vor dem Start, mise run venv aktualisiert sie. mise install installiert keine Pakete aus requirements.txt.

Starten

Das Projekt muss einmal in Godot geöffnet worden sein, damit die Szenen importiert sind.

mise run sim            # Fleet Server im Hintergrund + Godot im Vordergrund (Alias: mise run multiplayer)
mise run sim:headless   # dasselbe ohne Fenster (Server / CI)

mise run run            # nur Godot (Standard: Rennstrecke)
mise run run --scene res://scenes/environments/classroom/classroom.tscn
mise run run:headless
mise run fleet          # nur Fleet Server + Simulator-Agent
mise run editor         # Godot-Editor

mise run sim beendet den Fleet Server beim Schließen von Godot oder bei Ctrl+C mit. Für den Unterricht bietet sich an, mise run run (Beamer) und mise run fleet (Server-Log) in getrennten Terminals zu starten.

Fleet Server: Port 8080, in der Entwicklungs-VM 18080.

  • Schüler-Portal: http://<SERVER-IP>:8080
  • Lehrer-Dashboard: http://<SERVER-IP>:8080/admin

Hosts und Ports

mise run sim --host 127.0.0.1 --port 18080 --sim-host 127.0.0.1 --sim-port 65433
# Auch für sim:headless, fleet sowie run / run:headless (nur --sim-*).
# Zusätzliche Godot-Argumente anhängen, bei Bedarf nach --:
mise run sim --port 18080 --sim-port 65433 -- --rendering-method gl_compatibility

Ohne VM-Vorgaben gelten WEB_HOST=0.0.0.0, WEB_PORT=8080, SIM_BIND_ADDRESS=127.0.0.1 und SIM_PORT=65432; die Variablen können auch in .env gesetzt werden, Parameter haben Vorrang. Der lokale Fleet-Agent wird automatisch mit der gewählten Webadresse und Godot-API verbunden (bei --sim-host 0.0.0.0 bzw. :: über Loopback). Separat gestartete Python-Clients brauchen passende GODOT_HOST / GODOT_PORT.

Bei belegten Ports bricht der Start ab. Die Start-Tasks beenden keine fremden Prozesse; beim Beenden werden nur die selbst gestarteten Kindprozesse aufgeräumt. VM-Portweiterleitungen müssen bei abweichenden Ports separat angepasst werden.

Fahrzeuge

PiCar-X Go-Kart Boxauto (bumpercar)
Lenkung (Servo P2) −30° bis +30° ca. 35°–45° Radeinschlag (Standard 40°) −60° bis +60° am Vorderrad
Antrieb Hinterräder einzeln: P13 / Pin 23 links, P12 / Pin 24 rechts Hinterräder einzeln: P13 links, P12 rechts ein E-Bike-Nabenmotor im gelenkten Vorderrad; erhält den Mittelwert von P13 und P12
Kamera-Pan (P0) −90° bis +90° −90° bis +90° −90° bis +90°
Kamera-Tilt (P1) −65° bis +40° −45° bis +45° −45° bis +45°
Ultraschall (HC-SR04) vorne am Stoßfänger, bis 4,0 m vorne am Frontflügel vorne in der Fronthaube über dem Prallring
Liniensensor (AnalogGrayscale) 3 Kanäle (L/M/R), ADC 0–4095, Schwellenwert 300 keiner keiner

Die Kamera liefert 320×240 @ 30 FPS und wird im HUD als Bild-in-Bild angezeigt. Das PiCar-X-Modell bildet den SunFounder PiCar-X nach.

Boxauto

Das Boxauto bildet einen umgebauten Autoscooter nach: Akkubetrieb ohne Stromabnehmer, ein E-Bike-Nabenmotor im Vorderrad, das über die Lenksäule mitlenkt, und zwei mitlaufende Hinterräder (Dreirad-Prinzip). Da es nur einen Fahrmotor gibt, wirken P13 und P12 gemeinsam: Motor("P13") allein fährt mit halber Kraft, beide Kanäle zusammen mit voller. Höchstgeschwindigkeit ca. 20 km/h. Kamera-Mast mit Pan/Tilt sitzt auf der Fronthaube. Der Gummi-Prallring federt bei Kollisionen zurück.

Abmessungen (1,90 × 1,04 × 0,89 m), Masse (130 kg), Antriebskraft und Federung sind Schätzwerte und nicht am realen Fahrzeug vermessen. Das Modell entsteht reproduzierbar mit python3 tools/make_bumper_car_model.py aus dem unveränderten Sketchfab-Download in Assets/bumper_car/.

PiCar-X-Fahrphysik

Der PiCar-X nutzt eine geschwindigkeitsabhängige DC-Motor-Kennlinie, getrennte Hinterradantriebe und eine Ackermann-Näherung für die Lenkung. Tastatur und API verwenden dieselbe Antriebsphysik. Der Motorwert ist ein Stellwert in Prozent, keine garantierte Geschwindigkeit. Die Lenkung hält ihren Zielwinkel auch im Stand.

Rad-/Achsmaße und Aufbauhöhen entsprechen Messungen am realen Fahrzeug. Masse, Anfahr- und Bremsparameter sind noch nicht vermessen: Das Modell eignet sich für Funktions- und Protokolltests, nicht als Vorhersage von Fahrzeiten oder Bremswegen. Details und Messplan: PiCar-X-Physik.

Steuerung im Simulator

Taste Funktion
W / ↑ Gas
S / ↓ Bremsen / Rückwärts
A / D / ← / → Lenken
Leertaste Handbremse / Drift (Kart)
V / Tab Ansicht durchschalten: Go-Kart → Boxauto → PiCar-X → Observer
O / F3 Observer-Modus an/aus
F1 / 1 Rennstrecke
F2 / 2 Klassenzimmer
F4 / 4 Labor D404 + E405
L / N Tag/Nacht (Räume)
R Fahrzeug aufrichten / Reset

Angemeldete Schüler-Fahrzeuge und der Observer-Modus bleiben bei Szenenwechseln erhalten. Alle Tasten sind Input-Actions (Projekt → Projekteinstellungen → Eingabezuordnung).

Observer (freie Kamera)

Taste Funktion
W / A / S / D Fliegen
Leertaste / E Steigen
Q / C Sinken
Shift 2,8× Geschwindigkeit
Rechte Maustaste + Maus, Pfeiltasten Kamera drehen
Mausrad Fluggeschwindigkeit (0,5–25 m/s)

Teamnamen über Flottenfahrzeugen lassen sich im Observer einblenden (standardmäßig aus, max. 24 Zeichen). Fahrzeugkameras und übertragene Kamerastreams enthalten diese Einblendungen nie.

Umgebungen

Wechsel per Taste, UI-Button oder Python-API (select_scene: track, classroom, classroom_d404). Jede Umgebung ist eine SimEnvironment: Spawn-Plätze als Marker3D unter SpawnPoints, Tag/Nacht über LightingProfile-Ressourcen, Reset aller RigidBody3D-Props. Die Räume sind statische, im Editor bearbeitbare Szenen (*_room.tscn); nur die Rennstrecke wird aus track.gd erzeugt.

  • Rennstrecke (track.tscn): Asphalt-Rundkurs mit Curbs und Begrenzungen.
  • Klassenzimmer (classroom.tscn): Computerpool mit Labortischen, Slalom-Stoppschildern und schwarzem Linienkurs für den Liniensensor. Die Stoppschilder (StopSign_0–StopSign_5 unter SlalomObstacles in classroom_room.tscn) sind RigidBody3D-Props; das Modell selbst liegt in scenes/props/stop_sign.tscn.
  • Labor D404 + Raum E405 (classroom_d404.tscn): Nachbildung von D404 und dem über die Brandschutztür erreichbaren Eckraum E405, Klebeband-Rundkurs im Gang. Außenbereich: Nürtingen rund um die PMHS aus OpenStreetMap und EU-DEM (d404_city.tscn, gebaut von tools/build_d404_city.gd), dahinter ein Fotopanorama (d404_surroundings.tscn). Auf einer echten GPU zusätzlich vorgebackene globale Beleuchtung (VoxelGI) und 4×-MSAA; im Software-Rendering bleiben beide aus. SIM_GI=on / SIM_GI=off erzwingt die Wahl.

Python-API (intsys-car-v1)

Der Simulator stellt einen TCP-Server bereit (Standard 127.0.0.1:65432). Die lokale Implementierung von intsys-car-v1 leitet Sensor- und Aktoraufrufe dorthin weiter.

git submodule update --init --recursive
pip install -r requirements.txt
from intsys_car_v1 import Motor, Servo, HC_SR04, AnalogGrayscale, select_vehicle

select_vehicle("picarx")  # oder "kart", "bumpercar"

motor_left = Motor("P13", 23)
motor_right = Motor("P12", 24)
steering = Servo("P2", min_angle=-30, max_angle=30)
cam_pan = Servo("P0")
cam_tilt = Servo("P1")

steering.setAngle(20)       # 20° nach rechts
motor_left.setSpeed(50)     # 50 % vorwärts
motor_right.setSpeed(50)
cam_pan.setAngle(-30)       # 30° nach links
cam_tilt.setAngle(-15)      # 15° nach oben

us = HC_SR04()
print("Distanz:", us.get_distance_cm(), "cm")

grayscale = AnalogGrayscale()
print(grayscale.get_line_detection_data())
# {'leftValue': 890, 'leftDetected': False, 'centerValue': 120, 'centerDetected': True, 'rightValue': 900, 'rightDetected': False}

Fahrzeug und Schüler-Server: Car und CarServer

Car und CarServer kommen unverändert aus der Hardware-Bibliothek intsys_car_v1 (Git-Submodul external/intsys_car_v1). Steuerwerte sind Eigenschaften, die Fahrschleife ist while car.next_frame():. Im Simulator fährt Car das aktive Godot-Fahrzeug über die virtuellen Aktoren; das Kamerabild kommt aus Godot statt von Picamera2, eine GPIO-Factory entfällt.

from intsys_car_v1 import Car

car = Car()                    # Konfiguration über load_car_config(), siehe unten
while car.next_frame():        # höchstens 20/s, misst Ultraschall und Liniensensor
    car.steering = -20 if car.line_left else 20 if car.line_right else 0
    car.speed = 0 if car.distance < 15 else 35

CarServer läuft auf dem Schülerrechner und ist von einem realen Fahrzeug, von sim_car_client.py oder von SPARK-E aus nicht zu unterscheiden:

from intsys_car_v1 import CarServer

car = CarServer()              # Port 5555, Kamerafenster (pygame, optional)
while car.next_frame():
    car.drive_manually()       # WASD oder Xbox-Controller
    if car.distance < 20 and car.speed > 0:
        car.speed = 0

Eigenschaften, Live-Kalibrierung und Bildauswertung (car.brightness("left"), car.color_share("red"), car.save_image()) beschreibt das README der Hardware-Bibliothek. Abweichung im Simulator: Der Motor-Watchdog (siehe unten) stoppt auch Car-Motoren nach 2 s ohne neuen Befehl; in der Fahrschleife oder mit Server werden sie laufend neu gesetzt. Kamerafenster, Tastatur und Controller von CarServer brauchen pip install pygame.

Beispiele:

  • python3 examples/test_all_sensors.py: Funktionstest aller Sensoren und Aktoren auf beiden Fahrzeugen.
  • python3 examples/line_follower_demo.py: Linienfolger mit Ultraschall-Kollisionsschutz.

Konventionen

  • Lenkung P2 und Pan P0: positiver Winkel = rechts. Tilt P1: negativ = oben.
  • Servos fahren mit endlicher Geschwindigkeit auf ihren Zielwinkel; get_servo liefert den aktuellen Winkel.
  • Servo-Zielwinkel bleiben bis zum nächsten Servo-/Resetbefehl oder zur manuellen Übernahme bestehen; ein Motor-Stopp zentriert die Lenkung nicht.
  • Motor-Watchdog: Ohne neuen Motorbefehl stoppt ein Motor nach 2 s. Servo- und Sensoraufrufe verlängern die Frist nicht.
  • Ein erkannter Verbindungsabbruch stoppt die Motoren, die zuletzt von dieser Verbindung gesteuert wurden.
  • Im Observer-Modus gibt es kein aktives Fahrzeug: Fahrzeugbefehle ohne id antworten mit einem Fehler.

Fahrzeug-Konfiguration

load_car_config() und CAR_CONFIG_STANDARD sind wie in der Hardware-Bibliothek verfügbar. Die Rückgabe enthält neutrale Simulator-Montagewerte und lässt sich direkt an die virtuellen Aktoren übergeben:

from intsys_car_v1 import load_car_config, Motor, Servo

car = load_car_config()  # optional: load_car_config("car.toml")
motor_left = Motor(factory=None, **car["motor_left"])
motor_right = Motor(factory=None, **car["motor_right"])
steering = Servo("Lenkung", **car["servo_steering"])

Dateipfad alternativ über INTSYS_CAR_CONFIG. Ohne Angabe wird $XDG_CONFIG_HOME/intsys/simulator-car.toml bzw. ~/.config/intsys/simulator-car.toml verwendet; fehlt die Datei, gelten die Simulator-Standardwerte. Eine ausdrücklich gewählte Hardware-Datei wird auf virtuelle Pin-Zuordnungen und neutrale Invertierungen/Offsets abgebildet. Beispiel: simulator-car.toml, Details: Konfigurationsadapter.

Protokoll

Eine JSON-Zeile pro Anfrage und Antwort. Sendet ein Client "binary": true, kommen Kamerabilder als rohe JPEG-Bytes direkt nach der JSON-Zeile ("image_size"), sonst als image_base64. Der Server blockiert nie: Clients, die Antworten nicht abholen oder überlange Zeilen schicken, werden getrennt. Er ist ein Autoload und bleibt bei Szenenwechseln verbunden.

Netzwerk und Sicherheit

Umgebungsvariablen beim Start von Godot:

Variable Standard Bedeutung
SIM_BIND_ADDRESS 127.0.0.1 z. B. 0.0.0.0 für Zugriff aus dem LAN
SIM_PORT 65432 TCP-Port
SIM_API_TOKEN leer Wenn gesetzt, muss jeder Client einmal pro Verbindung "token" mitsenden (SimClient liest dieselbe Variable)
SIM_DIRECT_TIMEOUT_SEC 2 Motorfrist für direkte set_motor-/Python-Aufrufe; 0 hält bis Stop oder Verbindungsabbruch. Fleet-Batches behalten ihre 2-s-Frist.

Der Fleet Manager schützt Lehrer-Aktionen (Kicken, Reset) mit FLEET_ADMIN_TOKEN. Ist die Variable nicht gesetzt, erzeugt der Server beim Start ein Token und schreibt es ins Log.

Der Fleet-Server ist für ein vertrauenswürdiges Labornetz ausgelegt: Fahrzeugliste und Belegung (inkl. Teamnamen und Netzadressen) sind ohne Anmeldung erreichbar. FLEET_CLASS_TOKEN schützt die Belegung mit einem gemeinsamen Kurscode. Für öffentlichen Betrieb reichen TLS und Admin-Token nicht aus; Zugriffe und erlaubte Zielnetze müssen begrenzt werden. Siehe SECURITY.md.

Fleet-Betrieb mit SPARK-E

SPARK-E ist der eigenständige Fleet Server (Git-Submodul). Er verwaltet reale und simulierte Fahrzeuge, Online-Status und Team-Belegungen; der Godot-Adapter liegt unter fleet_simulator/. Reale Fahrzeuge melden sich mit demselben Agent-Protokoll an.

mise run fleet / mise run sim starten SPARK-E zusammen mit dem Simulator-Agenten. Dieser meldet 16 virtuelle Plätze (sim-01 bis sim-16), die nur bei erreichbarem Godot verfügbar sind. Die Fahrzeuge stehen schon vor der Belegung auf festen Parkplätzen (in D404 nebeneinander im Raum E405, Knoten RoomE405) und kehren bei Rückgabe, Verbindungsabbruch oder inaktiver Schülerverbindung dorthin zurück. SIM_FLEET_SIZE, SIM_PROVIDER_ID und SIM_VEHICLE_PREFIX passen den Bestand an.

Jedes Fahrzeug hat eine feste Lackfarbe und seine Nummer auf beiden Seiten und oben; beides bleibt bei Teamwechsel erhalten und ist auch in Fahrzeugkameras sichtbar.

SPARK-E separat betreiben (eigene VM unter 127.0.10.19, siehe README): SPARK_FLEET_URL (oder FLEET_URL, hat Vorrang) auf die aus dem Simulator erreichbare WebSocket-Adresse setzen, FLEET_PROVIDER_TOKEN mit dem Server abgleichen und mise run fleet:agent starten. Zwischen zwei SLiRP-VMs führt die Verbindung über den Host, z. B. per SSH-Tunnel; 127.0.10.19 bezeichnet innerhalb einer VM deren eigene Loopback-Schnittstelle.

Schüler-Workflow

  1. Portal unter http://<SERVER-IP>:8080 öffnen.
  2. Reales oder simuliertes Fahrzeug wählen, Teamname, Rechner-IP und Steuerungs-Port angeben und verbinden.
  3. Python-Steuerungsprogramm starten. Kamera, Sensoren und Steuerung laufen über das ZeroMQ-Protokoll (Standardport 5555).
  4. Die Lehrkraft kann Belegungen im Dashboard freigeben; Positionsreset gibt es nur für unterstützte Fahrzeuge.

Der Beispielclient (sim_car_client.py, ein Car mit connect()) verbindet sich standardmäßig mit 127.0.0.1; anderer Steuerungsserver über CONTROL_SERVER_HOST / CONTROL_SERVER_PORT, Simulator-Verbindung über GODOT_HOST / GODOT_PORT. Wie das reale Fahrzeug wartet er nach jedem Bild auf eine Antwort (höchstens 20 Hz), hält nach 2 s ohne Antwort an und sendet dann das nächste Bild.

Projektstruktur

├── main.gd                     # GameManager: Ansicht (Kart / Boxauto / PiCar-X / Observer), Szenenwechsel, Flotte
├── scenes/
│   ├── environments/
│   │   ├── sim_environment.gd  # Basis aller Umgebungen (Spawn-Plätze, Liniensensor, Reset, Tag/Nacht)
│   │   ├── lighting_profile.gd # Tag-/Nacht-Werte als Ressource (*.tres je Raum)
│   │   ├── classroom/          # classroom.tscn + classroom_room.tscn + textures/
│   │   ├── classroom_d404/     # classroom_d404.tscn + d404_room.tscn + d404_surroundings.tscn
│   │   └── track/              # track.tscn + track.gd (prozedurale Rennstrecke)
│   ├── vehicles/
│   │   ├── sim_vehicle.gd      # Basis Kart/Boxauto/PiCar-X: Motoren, Radlayout, Servos, Watchdog, API, Kameras
│   │   ├── components/         # UltrasonicSensor, LineSensor, VehicleCamera (async JPEG)
│   │   ├── kart/kart.tscn      # Go-Kart (nur Parameter, Skript = sim_vehicle.gd)
│   │   ├── bumper_car/         # bumper_car.tscn: Boxauto mit Nabenmotor-Vorderrad (Skript = sim_vehicle.gd)
│   │   ├── picarx/             # picarx.tscn, picarx_model.tscn, picarx.gd (Flotten-Identität)
│   │   └── vehicle_server.gd   # Autoload "VehicleServer": TCP-API für intsys-car-v1
│   ├── ui/                     # Menü, HUD, Theme, Icons, Schriften
│   ├── camera/                 # observer_camera.tscn
│   ├── props/                  # Möbel und Hindernisse als eigene Szenen, meshes/
│   ├── materials/              # PBR-Materialien (D404 / E405)
│   └── physics_layers.gd       # Namen der Physik-Layer
├── Assets/                     # Rohdaten (Meshes, Texturen, HDRI)
├── tools/                      # Editor-Skripte: Szene dumpen, Ansichten rendern, D404-Meshes/-Texturen bauen, GI backen
├── spark-e/                    # Fleet Server + Webportal (Git-Submodul, GPL v3)
├── fleet_simulator/            # Godot-Adapter und Simulator-Agent für SPARK-E
├── third_party/intsys_car_v1/  # Python-Clientbibliothek für den Simulator (inkl. protocol.py)
├── external/intsys_car_v1/     # Hardware-Bibliothek (Git-Submodul): Car, CarServer, Schülerprotokoll
├── examples/                   # Python-Steuerungsskripte
└── tests/                      # Pytest-Suite und GDScript-Tests

picarx_model.tscn ist das rein optische Modell ohne Physik und Serveranbindung. picarx.tscn ist das fahrbare Fahrzeug (VehicleBody3D mit picarx.gd → SimVehicle); es instanziiert das Modell als Kindknoten Model und enthält UltrasonicSensor, LineSensor und OnboardCamera.

Lizenzen

Eigener Simulator-Code und die lokale Simulator-Clientbibliothek: GPL-3.0-only, siehe LICENSE und Lizenzumfang. Das vollständige Inventar mit Quellen, Änderungen und Ausnahmen steht in THIRD_PARTY_NOTICES.md und ist im Simulator über Lizenzen & Quellen erreichbar. Linux-Releases enthalten die Lizenzdateien neben dem Programm.

  • "Modular Go-kart" (https://skfb.ly/pBzPo) by Jungle Jim is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
  • This work is based on "Bumper Car (Unity3D)" (https://sketchfab.com/3d-models/bumper-car-unity3d-830cbf0f466049fbac076b9eaf4af3fc) by jsa201077 (https://sketchfab.com/unityjsa7) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/). Geändert: Stromabnehmer entfernt, Lenkrad abgetrennt, Maßstab/Ausrichtung angepasst (tools/make_bumper_car_model.py).
  • UI-Icons: Lucide (ISC, siehe scenes/ui/icons/LICENSE), als SVG aus spark-e/fleet_manager/web/static/lucide.min.js übernommen.
  • UI-Schrift: Fixel (Assets/fonts/FixelVariable.woff2).
  • Umgebung von D404: Kartendaten © OpenStreetMap-Mitwirkende (ODbL 1.0), Gelände aus EU-DEM (Copernicus), siehe Assets/osm/README.md.
  • D404: eigene generische Poster-/Demowandgrafiken, originale eigene Tafel-/Flipchartanschriebe und eigene Fototexturen unter den Projektbedingungen; das intsys-Logo ist CC0-1.0. Quellen: Assets/textures/d404/README.md.
  • PBR-Texturen: ambientCG, CC0 1.0, Details je Textur in Assets/textures/ambientcg/README.md.
  • Chassis-/Rad-CAD: PiCar_Hardware von Mickael Gaillard / Theosakamg, Apache-2.0, unveränderte Dateien; Herkunft und Dateihashes in Assets/picarx/README.md. Sensor-/Kameraaufbauten des PiCar-X sind eigene Ergänzungen.
  • DINish 4.007: OFL-1.1, siehe licenses/DINish-OFL.txt. HDRI: Poly Haven, CC0-1.0, siehe Assets/README.md.

Release-Build, Python-Paketsatz mit Hashes, Prüfung des Exportinhalts und Quellpaket ohne private Git-Historie: RELEASE.md.