intsys car v1
This repository contains code run on our intsys cars (v1). It's primarily code to control the motors, servos and sensors.
Fahrzeug-Konfiguration
Pins und Kalibrierung eines Autos stehen in /etc/intsys/car.toml (zentral per Ansible
gepflegt, anderer Pfad über INTSYS_CAR_CONFIG). Die Abschnitte passen direkt zu den
Konstruktoren:
from gpiozero.pins.lgpio import LGPIOFactory
from intsys_car_v1 import load_car_config, Motor, Servo, HC_SR04, AnalogGrayscale
car = load_car_config()
factory = LGPIOFactory()
motor_links = Motor(factory=factory, **car["motor_left"])
lenkung = Servo("Lenkung", **car["servo_steering"])
ultraschall = HC_SR04(factory=factory, **car["ultrasonic"])
linie = AnalogGrayscale(**car["line_sensor"])
Fehlt die Datei, gilt der Standard (CAR_CONFIG_STANDARD). Unbekannte Schlüssel oder
falsche Typen lösen ValueError aus.
Fahrzeug und Schüler-Server: Car und CarServer
Beide Seiten werden gleich bedient: Steuerwerte sind Eigenschaften, die Fahrschleife ist
while car.next_frame():. Port (5555), Takt, Sicherheitsstopp und Protokoll stecken in
den Klassen.
| Eigenschaft | Bedeutung |
|---|---|
speed, left, right |
Motoren −100 … 100 (speed setzt beide) |
steering, pan, tilt |
Lenkung −30 … 30°, Kamera schwenken −90 … 90°, neigen −65 … 40° |
distance |
Ultraschall in cm, 999 ohne Echo |
line_left, line_center, line_right |
Linie erkannt (*_value: Rohwert) |
frame_count, image |
Durchläufe/Bilder, Kamerabild (numpy, BGR) |
Werte außerhalb des Bereichs werden begrenzt, Nicht-Zahlen lösen ValueError aus.
car.stop() setzt alles auf 0, car.calibrate("servo_steering", "compensate_angle", -8)
kalibriert live (Fahrzeug: sofort bis Programmende; Server: mit der nächsten Antwort).
Fahrzeug (Hardware aus car.toml; car.motor_left, car.servo_steering usw. bleiben
erreichbar, aber nicht zusätzlich eigene Motor-Objekte für dieselben Pins anlegen):
from intsys_car_v1 import Car
car = Car()
car.connect("192.168.0.10") # optional: Schüler-Server
while car.next_frame(): # max. 30/s; mit Server: Bild + Sensordaten senden, Antwort fahren
if car.distance < 15:
car.speed = 0 # eigene Regeln nach der Server-Antwort
Ohne Antwort hält das Fahrzeug nach 2 s an. Programmende (auch Strg+C) stoppt die Motoren und stellt die Servos auf 0°.
Schüler-Server (pip install "intsys_car_v1[server]" für pygame):
from intsys_car_v1 import CarServer
car = CarServer() # Port 5555, Kamerafenster
while car.next_frame(): # wartet auf das nächste Bild; q oder Fenster schließen beendet
car.drive_manually() # WASD im Fenster oder Xbox-Controller
if car.distance < 20 and car.speed > 0:
car.speed = 0
- Gesetzte Werte bleiben stehen und gehen mit jeder Antwort mit; nie gesetzte Werte werden nicht gesendet (das Fahrzeug nimmt 0).
drive_manually(): W/S vor/zurück mit 100, A/D lenken 30°, loslassen = 0, wie im Dashboard von intsys-car-v1-server. Gedrückte Tasten haben Vorrang vor dem Controller.key_pressed("space"),controller(Rohdaten),message(Sensordaten des Fahrzeugs).calibrate("servo_steering", "compensate_angle", -8): Live-Kalibrierung, einmal gesendet.- Neben dem Kamerabild zeigt eine Spalte die aktuellen Werte (nur Anzeige): Verbindung (fps,
Bildalter, Rechenzeit bis zur Antwort), Ultraschall, Liniensensor (erkannt + Rohwert),
Aktoren gesendet vs. vom Fahrzeug gemeldet (Abweichung gelb), Kalibrierung und
sensor_errors. Abschalten mitCarServer(show_info=False). Schriften: Inter und JetBrains Mono (SIL OFL 1.1, liegen mit Lizenz infonts/). - Das Kamerafenster ist in der Größe veränderbar: Die Spalte bleibt rechts mit fester Breite,
das Bild füllt den Rest seitenrichtig (schwarze Balken).
Strg +/Strg −ändern die Schriftgröße der Spalte (80 … 200 %),Strg 0setzt sie zurück. Ist das Bild größer als der Bildschirm, öffnet sich das Fenster passend verkleinert.
Auf beiden Seiten wertet car.brightness("left") (0 … 255; "center", "right", "all")
und car.color_share("red") (% der Pixel; "orange", "yellow", "green", "blue") das
Kamerabild aus; car.save_image("bilder") speichert es als bild_<Nummer>.jpg.
intsys_car_v1.protocol enthält die Regeln ohne Hardware (parse_reply,
check_calibration, Grenzen); Car und SPARK-E werten Antworten gleich aus.
Änderungen in 0.0.8
- Neu:
Car,CarServer,intsys_car_v1.protocolundintsys_car_v1.vision(siehe oben). Extra[server]installiert pygame für Fenster, Tastatur und Controller.
Änderungen in 0.0.7
Motor.min_speed_to_moveist eine öffentliche Eigenschaft (0 … < 100) und wirkt bei laufendem Motor sofort. Damit lässt sich live kalibrieren, wie mitServo.compensate_angle.
Änderungen in 0.0.6
Motor: Rückwärts wird mitmin_speed_to_movegleich skaliert wie vorwärts (vorher maximal 50 % und Stillstand zwischen 0 und −33). Richtung wird vor der Leistung gesetzt. Neu:close().Servo:min_angle/max_anglebegrenzen den gewünschten Winkel vorcompensate_angle, also symmetrisch um die kalibrierte Mitte; danach Begrenzung auf ±90°. Keinprintmehr, numpy-Zahlen erlaubt.- I2C: Bus-Sperre für alle Zugriffe; nach fünf Fehlversuchen
OSErrorstatt stillFalse. Adresssuche ohnei2cdetect, einmal pro Prozess. Ein Logger pro Klasse. AnalogGrayscale: findet die Controller-Adresse wie die PWM, misst als eine gesperrte Transaktion mit Wiederholung, akzeptiert"A0"…"A7", warnt bei Kanälen, die kein ADC-Eingang sind. Neu:close().HC_SR04: Zeitlimit 40 ms beim Warten auf Beginn und Ende des Echos (vorher ohne Limit bzw. abhängig von der CPU),perf_counterstatttime.time.factoryist optional und wird erst im Konstruktor erzeugt;import intsys_car_v1öffnet keinen GPIO-Chip mehr. Neu:temperature_c,close().load_car_config()/CAR_CONFIG_STANDARDfür/etc/intsys/car.toml.- Paket: Python ≥ 3.11,
opencv-python-headlessstattopencv-python,gpiozeroals Abhängigkeit.lgpioundpicamera2kommen aus Raspberry Pi OS.
Entwicklungsumgebung
mise trust # einmalig: mise.toml freigeben
mise install # installiert uv
mise run dev # Paket editierbar + Test-Extras in .venv installieren
mise legt beim Betreten des Ordners .venv (Python 3.11 wie auf den Autos, von uv
bereitgestellt) an und aktiviert sie automatisch – python und pytest kommen dann
aus .venv. Voraussetzung: mise ist in der Shell aktiviert (mise activate).
Tests
mise run test
# ohne mise:
pip install -e '.[test]' && python -m pytest
Laufen ohne Raspberry Pi (I2C-Attrappe, gpiozero MockFactory).
Build & Upload (PyPI)
Voraussetzung: Entwicklungsumgebung wie oben eingerichtet (uv kommt über mise).
API-Tokens
Die Tokens gehören ausschließlich in die Datei .env im Wurzelverzeichnis dieses
Repos. Sie ist git-ignoriert; eingecheckt wird nur die Vorlage .env.template.
cp .env.template .env
Dann in .env eintragen:
| Variable | Für | Token erstellen |
|---|---|---|
PYPI_TOKEN |
mise run publish |
https://pypi.org/manage/account/token/ |
TESTPYPI_TOKEN |
mise run publish:test |
https://test.pypi.org/manage/account/token/ |
Tokens beginnen mit pypi-…. TestPyPI ist ein eigener Dienst mit eigenem Account und
eigenem Token. Am besten das Token auf das Projekt intsys_car_v1 beschränken.
mise lädt .env automatisch und blendet die Werte in seinen Ausgaben aus.
Ablauf
versioninpyproject.tomlerhöhen (eine Version lässt sich nur einmal hochladen).- Bauen und prüfen:
mise run build # dist/*.whl + dist/*.tar.gz, danach twine check
- Erst auf TestPyPI, dann ausprobieren:
mise run publish:test pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ intsys_car_v1
- Auf PyPI:
mise run publish
publish und publish:test bauen vorher immer frisch (clean → build). Alle Tasks:
mise tasks.
Die Fahrschleife hat einen Zieltakt von 30 Hz; die Kamera wird mit 640 × 480
und 30 FPS konfiguriert (OV5647 unterstützt diesen Modus). Bei Serverbetrieb
begrenzen auch Bildverarbeitung und Antwortzeit den tatsächlich erreichten Takt.
Der Liniensensor wird pro Durchlauf gelesen. Ultraschall misst unabhängig
in einem Hintergrundthread mit mindestens 70 ms zwischen Messstarts; verwendet
wird der letzte abgeschlossene Messwert. Car() wartet beim Start kurz auf die
erste Messung. Ist ein Messwert älter als 0,5 s (oder fehlt er), gilt der Abstand
als unbekannt: None im Protokoll, 999 über car.distance, Grund in
car.sensor_errors["ultrasonic"].
Jedes Bild trägt ab 0.0.10 timing für Latenzanzeigen (wie der SPARK-E-Agent):
sent (Sendezeit, Unix-Sekunden), image_age (Belichtungsbeginn bis Senden) und
ultrasonic_age (Ende der Messung bis Senden), beide in Sekunden auf dem Fahrzeug
gemessen; unbekannt ist None.
Verbindung (ab 0.0.10): Car und CarServer setzen einen ZeroMQ-Heartbeat (1 s,
Zeitlimit 3 s). Ein ohne Abmeldung verschwundenes Fahrzeug blockiert den
zmq.PAIR-Port des Servers dann nur einige Sekunden statt bis zum Neustart.
Liegen beim Fahrzeug mehrere Antworten bereit, nimmt Car die neueste.
Car(jpeg_quality=90) legt die JPEG-Qualität der gesendeten Bilder fest
(kleiner = weniger WLAN-Last).
Kamera ohne IR-Filter (NoIR-Modul, wirksam ab 0.0.12; 0.0.11 kennt den Schlüssel, aber
libcamera ignorierte das Tuning): in car.toml [camera] noir = true.
Car lädt dann die Tuning-Datei <sensor>_noir.json (z. B. ov5647_noir.json), sonst
hat das Bild einen grün/magenta Farbstich. Der Sensor kann den fehlenden Filter nicht
selbst melden. Für eigene Picamera2-Skripte: Picamera2(tuning=camera_tuning(Picamera2, config["camera"]["noir"])) mit from intsys_car_v1.car import camera_tuning.
Sensor-Modus (ab 0.0.11): Car nimmt den größten Modus mit vollem Bildwinkel, der
30 FPS schafft (OV5647: 1296 × 972), und lässt den ISP auf 640 × 480 verkleinern.
Das ist deutlich schärfer und rauscht weniger als der kleinste Modus, den libcamera
sonst wählt. Für eigene Skripte: sensor_mode(camera.sensor_modes, fps) aus
intsys_car_v1.car, Ergebnis als raw={"size": mode["size"]}.
Metadata
Release files for intsys_car_v1 0.0.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| intsys_car_v1-0.0.14.tar.gz | 393.2 kB | Without provenance | Details for intsys_car_v1-0.0.14.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| intsys_car_v1-0.0.14-py3-none-any.whl | Python 3 | none | any | Details for intsys_car_v1-0.0.14-py3-none-any.whl |
Total release size: 783.8 kB
Release files / intsys_car_v1-0.0.14.tar.gz
| Download URL | intsys_car_v1-0.0.14.tar.gz |
|---|---|
| Size | 393.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
508d9c1ffc755ae8d445575e627d72b28880950331eac32f044c1f5e83b902ae
|
|
BLAKE2b-256 checksum How to use checksums |
230a2f83d0fb44aff902097bb637e8950061d29e6f65280282b06adfaedfc0b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / intsys_car_v1-0.0.14-py3-none-any.whl
| Download URL | intsys_car_v1-0.0.14-py3-none-any.whl |
|---|---|
| Size | 390.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0c3152509baa7512d9362b4295f57ef608005644ceae2cb4770804ce0a05976
|
|
BLAKE2b-256 checksum How to use checksums |
39d0ba91c6dc0a04c0854d9792846ae8a5b56e3c0c016067676d9a39b9238402
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for intsys_car_v1 0.0.14
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.