No description
  • JavaScript 94%
  • CSS 4.1%
  • Nix 1.1%
  • HTML 0.8%
Find a file
2026-11-06 10:22:18 +00:00
preset_blocks (c) server starter: emergency brake left as TODO for students 2026-11-05 02:15:31 +00:00
src (+) car protocol: zmq heartbeat, newest reply wins, ultrasonic in background thread, timing fields 2026-11-06 10:22:18 +00:00
.env.example (+) .env.example 2026-11-03 07:15:51 +01:00
.gitignore (+) flake/mise setup 2026-11-03 07:08:42 +01:00
flake.lock (c) GPL v3 license like intsys_car_v1, nix-dev-sandbox from public GitHub URL 2026-11-05 02:31:12 +00:00
flake.nix (c) GPL v3 license like intsys_car_v1, nix-dev-sandbox from public GitHub URL 2026-11-05 02:31:12 +00:00
LICENSE (c) GPL v3 license like intsys_car_v1, nix-dev-sandbox from public GitHub URL 2026-11-05 02:31:12 +00:00
mise.toml (+) Server exmples 2026-11-04 15:52:48 +01:00
package-lock.json (c) GPL v3 license like intsys_car_v1, nix-dev-sandbox from public GitHub URL 2026-11-05 02:31:12 +00:00
package.json (c) GPL v3 license like intsys_car_v1, nix-dev-sandbox from public GitHub URL 2026-11-05 02:31:12 +00:00
README.md (c) server starter: emergency brake left as TODO for students 2026-11-05 02:15:31 +00:00
webpack.config.js (+) Initial commit 2025-12-22 17:05:43 +01:00

intsys Blockly Code Generator

Blockly-Oberfläche, die Python-Code für das intsys car v1 und den zugehörigen Schüler-Server erzeugt. Grundlage ist die Bibliothek intsys_car_v1 (ab 0.0.8) und der intsys-car-v1-Standard aus SPARK-E (docs/intsys-car-v1-standard.md).

Modi

Den Modus an die URL anhängen (ohne Parameter erscheint eine Auswahl):

  • ?mode=car: Programm, das auf dem Fahrzeug läuft
  • ?mode=server: Schüler-Server auf dem eigenen Rechner

Beide Modi werden gleich bedient: „setze Geschwindigkeit auf 40“, Sensorwerte wie „Ultraschall-Abstand“ und eine „Fahrschleife“. Socket, Port (5555), Takt und Protokoll stecken in den Klassen Car und CarServer der Bibliothek, der erzeugte Code bleibt kurz:

from intsys_car_v1 import CarServer          # bzw. Car auf dem Fahrzeug

car = CarServer()
while car.next_frame():
    car.drive_manually()
    if car.distance < 20 and car.speed > 0:
        car.speed = 0

Gesetzte Werte bleiben stehen, bis sie geändert werden (wie ein Motor auf dem Fahrzeug).

Kategorie „Kamerabild“ (beide Modi): „Helligkeit links/Mitte/rechts“ (0 … 255), „Anteil Rot/ Orange/Gelb/Grün/Blau“ (% der Pixel, ganzes Bild oder ein Drittel) und „speichere Kamerabild“ (bild_<Nummer>.jpg, z. B. als Trainingsdaten). Auf dem Fahrzeug startet der erste Zugriff die Kamera (rund 2 s).

Seitenleiste

Beide Modi sind gleich aufgebaut:

  • Kontrollstrukturen: Logik, Mathe, Schleifen, Text (mit Debug-Ausgabe).
  • Fahrzeug: alles über Car bzw. CarServer. „Fahren“ (Geschwindigkeit beider Motoren, Lenkung, Motor links/rechts einzeln, halte an), „Kamera“ (Schwenken, Neigen, Bildauswertung), „Sensoren“, Fahrschleife, Kalibrierung; auf dem Server zusätzlich „Manuell fahren“.
  • Steuerung: Variablen, Funktionen.
  • Erweitert: alles unterhalb der Abstraktion. Fahrzeug: Motoren und Servos einzeln (LGPIO-Factory, Pins aus car.toml), Sensoren und Kamera einzeln, eigene Fahrlogik, Server-Protokoll von Hand, Dictionaries. Server: Socket und Server-Schleife von Hand, Controller-Rohdaten, Dictionaries. Nicht mit „Fahrzeug“ mischen: beide belegen dieselben Pins bzw. denselben Port.

Fahrzeug

  • Kategorie „Fahrzeug“: Car mit Pins und Kalibrierung aus /etc/intsys/car.toml (per Ansible aus dem Fleet-Manager gepflegt). „setze … auf …“ stellt Motoren und Servos sofort, „Fahrschleife“ läuft bis zu 20-mal pro Sekunde.
  • „verbinde mit Server“: Danach sendet die Fahrschleife Bild und Sensordaten und fährt nach der Antwort (gleiche Regeln wie SPARK-E, ohne Antwort nach 2 s Stopp). Blöcke in der Schleife gelten zusätzlich, z. B. als Notbremse.
  • Einzelne Motoren, Servos und Sensoren stehen unter „Erweitert“, ebenfalls mit den Werten aus car.toml.

Server

  • „Fahrschleife: für jedes Kamerabild“ wartet auf das Fahrzeug, zeigt das Kamerabild und schickt nach deinen Blöcken die gesetzten Werte zurück. Beenden: q oder Fenster schließen.
  • „fahre mit Tastatur (WASD) oder Xbox-Controller“: W/S vor/zurück, A/D lenken, loslassen = anhalten (wie im Dashboard von intsys-car-v1-server). „Taste … gedrückt“ für eigene Tasten.
  • „Kalibrierung: setze …“: Live-Kalibrierung für die laufende Ausleihe.
  • Auf dem Rechner: pip install "intsys_car_v1[server]" (bringt pygame für Fenster, Tastatur und Controller mit).

Die Blöcke mit Pin-Eingaben sind nur noch registriert, damit gespeicherte Workspaces laden.

Beispiele

Über „Beispiel laden …“ (ersetzt nach Rückfrage die aktuellen Blöcke). Das erste Beispiel eines Modus erscheint beim ersten Öffnen.

Modus Beispiel Datei
Server Manuell fahren: WASD oder Xbox-Controller; Notbremse ist als TODO für die Schüler offen preset_blocks/server_controller.json
Server Im Kreis fahren preset_blocks/server_kreis.json
Server Eine Acht fahren (Richtungswechsel nach Anzahl Bilder) preset_blocks/server_acht.json
Server Linienverfolgung mit den Liniensensor-Werten des Fahrzeugs preset_blocks/server_linienverfolgung.json
Fahrzeug Im Kreis fahren preset_blocks/car_kreis.json
Fahrzeug Eine Acht fahren preset_blocks/car_acht.json
Fahrzeug Linienverfolgung mit dem Liniensensor preset_blocks/car_linienverfolgung.json
Fahrzeug Mit Server fahren: Gegenstück zu allen Server-Beispielen preset_blocks/car_controller.json

Beim Start lädt die App den zuletzt bearbeiteten Workspace aus dem localStorage des Browsers (storageKey in src/config/app_config.js); nur ein leerer Workspace bekommt das erste Beispiel. Nach Änderungen, die alte Workspaces unbrauchbar machen, die Version im Schlüssel erhöhen (aktuell _v2); der alte Stand bleibt unter dem alten Schlüssel erhalten. Kommentare in den Beispielen öffnen sich mit Klick auf das „?“ am Block (nicht angepinnt); Blockly übernimmt sie auch in den erzeugten Code.

Ein Beispiel ändern: laden, bearbeiten, mit „Blöcke speichern“ sichern und die Datei in preset_blocks/ ersetzen. Neue Beispiele in src/examples/index.js eintragen.

Entwicklung

Voraussetzung ist nur mise. mise installiert Node, und jeder Task gleicht vorher node_modules mit package-lock.json ab (npm ci, danach ein No-op).

mise trust        # einmalig
mise tasks        # alle Befehle anzeigen
mise run start    # Entwicklungsserver auf 0.0.0.0:8080
mise run start --host 127.0.0.1 --port 3000   # andere Adresse/anderer Port
mise run build    # Produktions-Build nach dist/

Alternativ in der MicroVM: mise run vm (auf dem Host), dann ssh intsys-car-blockly-vm (~/.ssh/config: HostName 127.0.10.20, Port 2200). Der Entwicklungsserver ist dann unter http://127.0.10.20:8080 erreichbar (die VM leitet nur Port 8080 weiter). nix develop liefert nur mise, der Rest läuft gleich. Unter NixOS braucht das Node von mise nix-ld (in der VM aktiv).

Aufbau

  • src/blocks/: Blockdefinitionen (vehicle: einfache Blöcke für Car/CarServer, common für beide Modi, car_v1: einzelne Hardware, server: alte Server-Blöcke)
  • src/generators/python/: Python-Generatoren je Blockdatei
  • src/config/car_protocol.js: Abschnitte von car.toml und Felder des Schülerprotokolls
  • src/toolbox.js, src/toolbox_server.js: Toolboxen je Modus
  • src/generators/python/car_protocol.js: alte Protokoll-Blöcke auf dem Fahrzeug (nur noch für gespeicherte Workspaces)
  • src/examples/index.js: Beispiele je Modus (Dateien in preset_blocks/)