FLL/test.py
2025-09-13 23:00:44 +02:00

181 lines
5.2 KiB
Python

from pybricks.hubs import PrimeHub
from pybricks.parameters import Color, Port
from pybricks.pupdevices import ColorSensor, Motor, UltrasonicSensor
from pybricks.tools import StopWatch, wait
print("\n" * 5)
print("TEST NORMALE (Pybricks)")
hub = PrimeHub()
PORTS = [Port.A, Port.B, Port.C, Port.D, Port.E, Port.F]
motori: list[Motor] = []
color_sensors: dict[Port, ColorSensor] = {}
distance_sensors: dict[Port, UltrasonicSensor] = {}
# Scoperta dispositivi (una sola istanza per porta)
for porta in PORTS:
try:
m = Motor(porta)
motori.append(m)
print("Motore trovato su porta {}".format(porta))
continue
except Exception:
pass
try:
cs = ColorSensor(porta)
color_sensors[porta] = cs
print("ColorSensor trovato su porta {}".format(porta))
continue
except Exception:
pass
try:
us = UltrasonicSensor(porta)
distance_sensors[porta] = us
print("UltrasonicSensor (distanza) trovato su porta {}".format(porta))
continue
except Exception:
pass
# Test motori
for m in motori:
m.dc(100)
wait(1000)
m.stop()
# Letture sensori esterni
print("Valori dei sensori:")
for porta, cs in color_sensors.items():
c = cs.color()
nome = getattr(c, "name", "NONE") if c is not None else "NONE"
print("ColorSensor su porta {}: colore rilevato {}".format(porta, nome))
for porta, us in distance_sensors.items():
d = us.distance()
if d is None:
print("Ultrasonic su porta {}: distanza fuori portata".format(porta))
else:
print(
"Ultrasonic su porta {}: distanza rilevata {:.1f} cm".format(porta, d / 10)
)
# Sensori integrati (IMU)
print("Valori dei sensori integrati nell'hub:")
tilt = hub.imu.tilt()
print("Tilt (roll, pitch): {}".format(tilt))
gyro = hub.imu.angular_velocity()
print("Velocità angolare (x,y,z): {}".format(gyro))
# ---------- FIX: parsing colori senza isinstance/issubclass --------------
def _color_member_or_none(name):
try:
return getattr(Color, name)
except Exception:
return None
def _parse_color(value):
"""
Accetta Color o stringa e ritorna un membro di pybricks.parameters.Color
senza usare isinstance/issubclass (compatibile con MicroPython).
"""
# Caso: è già un "Color-like" (ha .name che corrisponde a un membro)
try:
nm = getattr(value, "name", None)
if isinstance(nm, str) and _color_member_or_none(nm) is not None:
return value
except Exception:
pass
# Caso: stringa
if isinstance(value, str):
key = value.strip().replace(" ", "_").upper()
# Sinonimi tra VIOLET/PURPLE (dipende dalla versione)
if key in ("VIOLET", "PURPLE"):
return _color_member_or_none("VIOLET") or _color_member_or_none("PURPLE")
return _color_member_or_none(key)
return None
# -------------------------------------------------------------------------
def wait_for_color(color, sensor_port=None, timeout=None, min_time=0):
"""
Attende che un ColorSensor legga 'color'.
- color: Color o str ('violet', 'white', ecc.)
- sensor_port: Port o None per controllare tutti
- timeout: secondi massimi (None = infinito)
- min_time: stabilità minima in secondi
"""
target = _parse_color(color)
if target is None:
print("Colore '{}' non riconosciuto nell'enum Color.".format(color))
return False
if sensor_port is not None:
sensori = (
{sensor_port: color_sensors.get(sensor_port)}
if sensor_port in color_sensors
else {}
)
else:
sensori = color_sensors
if not sensori:
print("Nessun ColorSensor disponibile sulle porte richieste.")
return False
sw = StopWatch()
min_ms = int(min_time * 1000)
timeout_ms = None if timeout is None else int(timeout * 1000)
while True:
if timeout_ms is not None and sw.time() > timeout_ms:
print("Timeout raggiunto senza rilevare il colore.")
return False
for porta, cs in sensori.items():
if cs is None:
continue
current = cs.color()
nome = getattr(current, "name", "NONE") if current is not None else "NONE"
print("Porta {}: Colore rilevato {}".format(porta, nome))
if current == target:
t0 = sw.time()
while True:
cur2 = cs.color()
if cur2 != target:
break
if sw.time() - t0 >= min_ms:
print(
"Colore {} rilevato su porta {} per almeno {} s.".format(
target.name, porta, min_time
)
)
return True
wait(100)
wait(100)
# Sequenza principale
try:
if wait_for_color("violet"):
for m in motori:
m.dc(100)
if wait_for_color("white", min_time=2):
for m in motori:
m.stop()
hub.speaker.beep()
finally:
for m in motori:
try:
m.stop()
except Exception:
pass