Compare commits

52 Commits

Author SHA1 Message Date
8d9b2ca679 Add templates/logger.py 2026-03-26 18:19:58 +00:00
06bce553aa Update diagnostics/hub_diagnostics.py 2026-03-24 18:35:46 +00:00
a60c92997a Update README.md 2026-03-24 17:59:59 +00:00
7a4c06d789 Update diagnostics/hub_diagnostics.py 2026-03-24 17:55:28 +00:00
ddb5d4cc1b Update diagnostics/os_diagnostics.py 2026-03-24 17:52:28 +00:00
beeb707843 Update diagnostics/os_diagnostics.py 2026-03-24 17:50:10 +00:00
0fcc65deee Update diagnostics/micropython_diagnostics.py 2026-03-24 17:49:28 +00:00
6258ad2003 Add experiments/game.py 2026-03-23 18:24:06 +00:00
aa9fa76d46 Update templates/xbox_controller.py 2026-03-23 18:23:43 +00:00
436569ffd0 Removed unnecessary comments 2026-03-23 18:05:31 +00:00
57836a8da7 Update diagnostics/micropython_diagnostics.py 2026-03-21 16:16:12 +00:00
36df9de03d Update diagnostics/os_diagnostics.py 2026-03-21 15:26:26 +00:00
f0d862014e Tested properly on a bobot 2026-03-20 21:57:25 +00:00
3901f62db2 Add tests/testgc.py 2026-03-19 18:38:34 +00:00
9ab873baf6 Update diagnostics/micropython_diagnostics.py 2026-03-19 18:33:54 +00:00
a72af812f6 Update diagnostics/os_diagnostics.py 2026-03-19 18:33:33 +00:00
1a8d04de91 Began UsysTest 2026-03-19 18:09:02 +00:00
aa133253d0 Removed printVersionDiagnostics. Moving to osdiagnostics under class UsysTest 2026-03-19 18:06:02 +00:00
f37df8b99a Update diagnostics/os_diagnostics.py 2026-03-18 12:18:08 +00:00
c1808cfa75 Working on ustruct 2026-03-17 17:40:53 +00:00
79a992ac72 Finished umath, urandom, and uselect 2026-03-14 23:03:43 +00:00
f0b728a43b added stuff (json, some umath) 2026-03-13 13:33:09 +00:00
82d498a04c Update diagnostics/os_diagnostics.py 2026-03-13 13:28:40 +00:00
00c47aab66 Finish UIO 2026-03-13 12:59:36 +00:00
3bb4a80a46 Update diagnostics/os_diagnostics.py 2026-03-13 12:49:13 +00:00
67dacd2a2f Updated class structure to allow for extensions later 2026-03-12 19:23:36 +00:00
db747b0e7d Update diagnostics/os_diagnostics.py 2026-03-11 22:01:14 +00:00
3b35fa548c Update diagnostics/os_diagnostics.py 2026-03-11 21:56:37 +00:00
94bc1f7b14 Update tests/test-allow-missing-uart.py 2026-03-11 01:06:02 +00:00
17f5ea53f5 Add dev-tests/test-allow-missing-uart.py 2026-03-11 01:05:50 +00:00
07141a9c35 Update diagnostics/os_diagnostics.py 2026-03-11 01:03:44 +00:00
94b9b64ef3 Update diagnostics/os_diagnostics.py 2026-03-06 18:35:52 +00:00
644d338957 Add diagnostics/os_diagnostics.py 2026-03-06 16:34:42 +00:00
eb13361f4f Update diagnostics/color_sensor_diagnostics.py 2026-02-13 13:22:50 +00:00
d09222967b Update diagnostics/drive_base_diagnostics.py 2026-02-13 13:22:40 +00:00
4f23a4d308 Update diagnostics/full_diagnostics.py 2026-02-13 13:22:31 +00:00
c4b6ee5d97 Update diagnostics/FullDiagnostics.py 2026-02-13 13:22:21 +00:00
9a192d8eb8 Update diagnostics/hub_diagnostics.py 2026-02-13 13:21:49 +00:00
8c39974c5a Update diagnostics/micropython_diagnostics.py 2026-02-13 13:21:10 +00:00
2a555aedbc Update diagnostics/motor_diagnostics.py 2026-02-13 13:20:52 +00:00
b7bef93301 Update diagnostics/other_functions.py 2026-02-13 13:20:40 +00:00
f66438019e Update diagnostics/battery_diagnostics.py 2026-02-13 13:20:17 +00:00
5e0925b540 Update templates/xbox_controller.py 2026-02-13 13:19:03 +00:00
129bd9af93 Update templates/color_sensor_start_logic.py 2026-02-13 13:18:53 +00:00
540ff62836 Update diagnostics/MicroPythonDiagnostics.py 2026-02-06 14:38:41 +00:00
f5b51cb3aa Update diagnostics/MicroPythonDiagnostics.py 2026-01-30 14:30:56 +00:00
07bbba41e4 Update diagnostics/MicroPythonDiagnostics.py 2026-01-30 13:49:03 +00:00
8c5e90e0ec Update diagnostics/MicroPythonDiagnostics.py 2026-01-29 19:17:50 +00:00
6beeb837cf Fixed everything, final commit before 1.0.0 2026-01-22 16:25:09 -06:00
c8b520c12c Add templates/xboxcontroller.py 2026-01-22 20:29:11 +00:00
fab9650a9f Add templates/color-sensor-start-logic.py 2026-01-22 18:30:18 +00:00
8489a87ada 2026-01-21 16:49:54 -06:00
17 changed files with 1279 additions and 44 deletions

View File

@@ -6,11 +6,14 @@ A collection of Pybricks utilities to assist in your FLL robot programming with
How to use this:
- Download the repository by clicking on the "Code" tab, clicking the "< > Code" button, then downloading as a ZIP. Additionally, you can also use ```git clone https://codes.fll-65266.org/Arcmyx/pybricks-utils.git```. Unzip the archive and open code.pybricks.com. Then choose which folder you'd like to use, and open each file in pybricks by using the import button. For example, to use the diagnostics tool, simply open each program in the ```diagnostics``` folder into Pybricks. Then, follow the instructions for each utility.
- Download the repository by clicking on the "Code" tab, clicking the "< > Code" button, then downloading as a ZIP. Additionally, you can also use ```git clone https://codes.fll-65266.org/Arcmyx/pynamics.git```. Unzip the archive and open code.pybricks.com. Then choose which folder you'd like to use, and open each file in Pybricks by using the import button. For example, to use the diagnostics tool, simply open each program in the ```diagnostics``` folder into Pybricks. Then, follow the instructions for each utility.
- This method is not recommended due to the high probability of error. The team is currently working on a custom web Pynamics IDE that automatically fetches the latest compiled bytecode, sends it to your robot, and has an output viewer with custom formatting and integration with the program through (in the future) custom Pynamics ANSI escape codes.
Included utilities:
- Diagnostics - a program that allows you to diagnose issues and test parts of your robot, such as battery, motor, and color sensor. Open each program in the ```diagnostics``` folder in Pybricks, (you can select all of them at once) connect your robot, switch to the ```FullDiagnostics.py``` file and press run.
- Diagnostics - a program that allows you to diagnose issues and test parts of your robot, such as battery, motor, and color sensor. Open each program in the ```diagnostics``` folder in Pybricks, (you can select all of them at once) connect your robot, switch to the ```FullDiagnostics.py``` file and press run. The program might take a bit to compile, since there are thousands of lines of code being imported from the other files (partly the reason why the Pynamics IDE will be an improvement, since the Pynamics team will distribute the pre-compiled bytecode)
- Color Sensor Tests (UPCOMING) - a program that identifies what color the sensor is detecting. If you'd like, you can use our color ranges in your own programs.
Please set your window size to 90% on small screens for best results with the ASCII art.

View File

@@ -1,35 +0,0 @@
from pybricks.tools import wait, StopWatch
from pybricks.parameters import Port
from pybricks import version
import OtherFunctions as debug
import usys
class HubDiagnostics:
def __init__(self, hub):
self.hub = hub
self.port_map = {
"A": Port.A,
"B": Port.B,
"C": Port.C,
"D": Port.D,
"E": Port.E,
"F": Port.F,
}
def printAbout(self):
print("Pybricks version information:", version)
print("MicroPython information:", usys.implementation)
print("MicroPython version:", usys.version)
def testLightSources(self, verbose):
v = verbose
self.hub.display.off()
for x in range(5):
for y in range(5):
debug.log(f"Turning on pixel at position {x}, {y}...", v)
self.hub.display.pixel(x, y, brightness=100)
wait(100)
debug.log(f"Turning off pixel at position {x}, {y}...", v)
self.hub.display.pixel(x, y, brightness=0)
def printAll(self):
self.printAbout()
self.testLightSources(False)

View File

@@ -4,14 +4,16 @@ from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch
HUB = PrimeHub()
from BatteryDiagnostics import BatteryDiagnostics
from MotorDiagnostics import MotorDiagnostics
from ColorSensorDiagnostics import ColorSensorDiagnostics
from DriveBaseDiagnostics import DriveBaseDiagnostics
from battery_diagnostics import BatteryDiagnostics
from motor_diagnostics import MotorDiagnostics
from color_sensor_diagnostics import ColorSensorDiagnostics
from drive_base_diagnostics import DriveBaseDiagnostics
from hub_diagnostics import HubDiagnostics
battery = BatteryDiagnostics(HUB)
motor = MotorDiagnostics(HUB, Motor)
colorsensor = ColorSensorDiagnostics(HUB, ColorSensor)
drivebase = DriveBaseDiagnostics(HUB, Motor, DriveBase)
hubdiagnostics = HubDiagnostics(HUB)
CLEARCONFIRM = input("Clear the console before proceeding? Y/N (default: yes): ")
if(CLEARCONFIRM == "Y" or CLEARCONFIRM == "y" or CLEARCONFIRM == "yes" or CLEARCONFIRM == ""):
print("Clearing console... \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
@@ -35,6 +37,8 @@ while True:
print("Enter 'b' for battery diagnostics")
print("Enter 'm' for motor diagnostics")
print("Enter 'cs' for color sensor diagnostics")
print("Enter 'db' for drive base diagnostics")
print("Enter 'h' for hub diagnostics")
print("Enter 'q' to quit")
choice = input("Your choice: ").strip().lower()
@@ -49,7 +53,7 @@ while True:
elif choice == "m":
print("------------------------MOTOR DIAGNOSTICS------------------------")
motor.fullTest()
print("Motor diagnostics completed.")
print("[Motor Diagnostics] Motor diagnostics completed.")
elif choice == "q":
print("Diagnostics completed successfully. Exiting program.")
@@ -57,10 +61,13 @@ while True:
elif choice == "cs":
print("---------------------COLOR SENSOR DIAGNOSTICS---------------------")
colorsensor.printAll()
print("Color sensor diagnostics completed.")
print("[Color Sensor Diagnostics] Color sensor diagnostics completed.")
elif choice == "db":
print("----------------------DRIVE BASE DIAGNOSTICS----------------------")
drivebase.printAll()
print("Drivebase diagnostics completed.")
print("[Drivebase Diagnostics] Drivebase diagnostics completed.")
elif choice == "h":
print("--------------------------HUB DIAGNOSTICS--------------------------")
hubdiagnostics.printAll(False)
else:
print("Invalid choice. Please enter 'b', 'm', or 'q'.")

View File

@@ -0,0 +1,48 @@
from pybricks.tools import wait, StopWatch
from pybricks import version
import other_functions as debug
from micropython_diagnostics import MicroPythonDiagnostics
from pybricks.parameters import Port, Color
from os_diagnostics import OSDiagnostics
class HubDiagnostics:
def __init__(self, hub):
self.hub = hub
self.port_map = {
"A": Port.A,
"B": Port.B,
"C": Port.C,
"D": Port.D,
"E": Port.E,
"F": Port.F,
}
def testLightSources(self, verbose):
v = verbose
self.hub.display.off()
for x in range(5):
for y in range(5):
debug.log(f"[Hub Diagnostics - Light Sources] Turning on pixel at position {x}, {y}...", v)
self.hub.display.pixel(x, y, brightness=100)
wait(100)
debug.log(f"[Hub Diagnostics - Light Sources] Turning off pixel at position {x}, {y}...", v)
self.hub.display.pixel(x, y, brightness=0)
self.hub.light.on(Color.RED)
def printAll(self, verbose=True):
v = verbose
debug.log("[Hub Diagnostics] Starting hub diagnostics...", v)
while True:
choice = input("[Hub Diagnostics] Which hub diagnostic would you like to run?\n[Hub Diagnostics] Enter 'l' for light source test\n[Hub Diagnostics] Enter 'm' for MicroPython diagnostics\n[Hub Diagnostics] Enter 'o' for operating system diagnostics\n[Hub Diagnostics] Enter 'q' to quit\n[Hub Diagnostics] Your choice: ").strip().lower()
if choice == "l":
debug.log("[Hub Diagnostics] Running light source test...", v)
self.testLightSources(v)
if choice == "m":
debug.log("[Hub Diagnostics] Running MicroPython diagnostics...", v)
MicroPythonDiagnostics.printAll()
if choice == "o"
debug.log("[Hub Diagnostics] Running OS diagnostics...", v)
diag = OSDiagnostics(hub=PrimeHub(), motorclass=Motor)
diag.printAll()
if choice == "q":
print("[Hub Diagnostics] Hub diagnostics completed.")
return

View File

@@ -0,0 +1,128 @@
import micropython
import gc
from pybricks import version
class MicroPythonDiagnostics:
def __init__(self, hub):
self.successfultests = 0
self.failedtests = {}
def testgcmanual(self):
gc.disable()
print(f"Initial free: {gc.mem_free()} bytes")
large_data = [i for i in range(10000)]
print(f"After allocation: {gc.mem_free()} bytes")
gc.collect()
aftergcstillref = gc.mem_free()
print(f"After gc.collect (data still referenced): {aftergcstillref} bytes")
large_data = None
print("Reference to data removed.")
aftergcnoref = gc.mem_free()
gc.collect()
print(f"After gc.collect (data dead): {aftergcnoref} bytes")
if(aftergcnoref < aftergcstillref):
print("Completed Test 4/5: Manual garbage collection - SUCCESSFUL")
self.successfultests += 1
else:
print("Completed Test 4/5: Manual garbage collection - FAILED")
self.failedtests["Manual garbage collection"] = "Heap not cleared"
def testgcauto(self):
input("Disabling garbage collection. The amount of used memory should quickly increase. Press Enter to begin:")
gc.disable()
gc.threshold(5000)
total_mem = 255616
bytes_per_hash = 3000
print("Memory Monitor: [# = Used] [. = Free]")
print("-" * (total_mem // bytes_per_hash))
for i in range(500):
_ = bytearray(300)
if i % 25 == 0:
used = gc.mem_alloc()
free = gc.mem_free()
hashes = used // bytes_per_hash
dots = free // bytes_per_hash
print(f"{i:03d}: [{'#' * hashes}{'.' * dots}] {free} bytes free")
final_disabled_free = gc.mem_free()
input("Enabling garbage collection. The amount of used memory should stay relatively low. Press Enter to begin:")
gc.enable()
gc.threshold(5000)
total_mem = 255616
bytes_per_hash = 3000
print("Memory Monitor: [# = Used] [. = Free]")
print("-" * (total_mem // bytes_per_hash))
for i in range(500):
_ = bytearray(300)
if i % 25 == 0:
used = gc.mem_alloc()
free = gc.mem_free()
hashes = used // bytes_per_hash
dots = free // bytes_per_hash
print(f"{i:03d}: [{'#' * hashes}{'.' * dots}] {free} bytes free")
final_enabled_free = gc.mem_free()
if final_enabled_free > final_disabled_free:
print("Completed Test 5/5: Automatic garbage collection - SUCCESSFUL")
print(f"Difference: {final_enabled_free - final_disabled_free} bytes saved.")
self.successfultests += 1
else:
print("Completed Test 5/5: Automatic garbage collection - FAILED")
self.failedtests["Automatic garbage collection"] = "No GC difference"
def performMemoryDiagnostics(self):
input("Press Enter to retrieve memory information:")
print("[Hub Diagnostics - MicroPython - Memory] Memory information (retrieved from the MicroPython environment):")
micropython.mem_info(1)
input("After you're done reading the results, press Enter to run heap diagnostics:")
print("[Hub Diagnostics - MicroPython - Memory] Testing heap lock and unlock.")
print("[Hub Diagnostics - MicroPython - Memory] Allocating memory while heap is unlocked:")
try:
x = [1, 2, 3, 4, 5]
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 1/5: Normal memory allocation - SUCCESS")
print("There was no MemoryError raised. The value of the new variable x is", x)
self.successfultests += 1
except MemoryError:
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 1/5: Normal memory allocation - FAILED")
self.failedtests["Normal memory allocation"] = "MemoryError"
print("[Hub Diagnostics - MicroPython - Memory] Locking the heap:")
micropython.heap_lock()
print("[Hub Diagnostics - MicroPython - Memory] Heap was locked. Attempting to allocate memory (this should fail):")
try:
y = [10, 20, 30, 40, 50]
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 2/5: Heap lock - FAILED")
self.failedtests["Heap lock"] = "No heap lock"
except MemoryError:
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 2/5: Heap lock - SUCCESS")
self.successfultests += 1
print("[Hub Diagnostics - MicroPython - Memory] Unlocking the heap:")
micropython.heap_unlock()
print("[Hub Diagnostics - MicroPython - Memory] Heap was unlocked. Attempting to allocate memory (this should succeed):")
try:
z = [100, 200, 300, 400, 500]
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 3/5: Heap unlock - FAILED")
print("The value of the new variable z is", z)
self.successfultests += 1
except MemoryError:
print("[Hub Diagnostics - MicroPython - Memory] Completed Test 3/5: Heap unlock - FAILED")
self.failedtests["Heap unlock"] = "No heap unlock"
def printAll(self):
self.performMemoryDiagnostics()
input("After you're done reading the results, press Enter to run manual garbage collection test:")
self.testgcmanual()
input("After you're done reading the results, press Enter to run automatic garbage collection test:")
self.testgcauto()
print(f"\n=== Results: {self.successfultests}/5 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
#test = MicroPythonDiagnostics(hub=PrimeHub())
#test.printAll()

View File

@@ -0,0 +1,933 @@
from pybricks.parameters import Port
from uerrno import EAGAIN, EBUSY, ECANCELED, EINVAL, EIO, ENODEV, EOPNOTSUPP, EPERM, ETIMEDOUT
import uio
import ujson
import umath
import uselect
import ustruct
import usys
import urandom
from urandom import random
from pybricks.tools import wait, multitask, run_task
import pybricks as pybricksforvers
class FakeUART:
def __init__(self, port, baudrate, timeout):
self.timeout = timeout
self._force_error = None
print("Warning: No physical UART detected. Using simulator.")
def set_error(self, errno):
self._force_error = errno
def read(self, length=1):
if self._force_error is not None:
err = self._force_error
self._force_error = None
raise OSError(err)
if self.timeout is not None:
wait(self.timeout)
raise OSError(ETIMEDOUT)
else:
while True:
wait(1000)
def write(self, data):
if self._force_error is not None:
err = self._force_error
self._force_error = None
raise OSError(err)
def UARTDevice(port, baudrate=9600, timeout=None):
return FakeUART(port, baudrate, timeout)
class OSDiagnostics:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def testUErrno(self):
uerrnotestobject = UerrnoTest(self.hub, self.motorclass)
uerrnotestobject.testeagain()
uerrnotestobject.testebusy()
uerrnotestobject.testecanceled()
uerrnotestobject.testeinval()
uerrnotestobject.testeio()
uerrnotestobject.testenodev()
uerrnotestobject.testeopnotsupp()
uerrnotestobject.testeperm()
uerrnotestobject.testetimedout()
uerrnotestobject.print_results()
self.successfultests += uerrnotestobject.successfultests
self.failedtests.update(uerrnotestobject.failedtests)
def testUIO(self):
uiotestobject = UIOTest(self.hub, self.motorclass)
uiotestobject.print_results()
self.successfultests += uiotestobject.successfultests
self.failedtests.update(uiotestobject.failedtests)
def testUJSON(self):
ujsontestobject = UJSONTest(self.hub, self.motorclass)
ujsontestobject.print_results()
self.successfultests += ujsontestobject.successfultests
self.failedtests.update(ujsontestobject.failedtests)
def testUMath(self):
umathtestobject = UMathTest(self.hub, self.motorclass)
umathtestobject.print_results()
self.successfultests += umathtestobject.successfultests
self.failedtests.update(umathtestobject.failedtests)
def testURandom(self):
urandtestobject = URandomTest(self.hub, self.motorclass)
urandtestobject.print_results()
self.successfultests += urandtestobject.successfultests
self.failedtests.update(urandtestobject.failedtests)
def testUSelect(self):
uselecttestobject = USelectTest(self.hub, self.motorclass)
uselecttestobject.print_results()
self.successfultests += uselecttestobject.successfultests
self.failedtests.update(uselecttestobject.failedtests)
def testUStruct(self):
ustructtestobject = UStructTest(self.hub, self.motorclass)
ustructtestobject.print_results()
self.successfultests += ustructtestobject.successfultests
self.failedtests.update(ustructtestobject.failedtests)
def testUSys(self):
usystestobject = USysTest(self.hub, self.motorclass)
usystestobject.print_results()
self.successfultests += usystestobject.successfultests
self.failedtests.update(usystestobject.failedtests)
def printAll(self):
self.testUErrno()
self.testUIO()
self.testUJSON()
self.testUMath()
self.testURandom()
self.testUSelect()
self.testUStruct()
self.testUSys()
print(f"\n=== Results: {self.successfultests}/62 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
else:
print("No tests failed. Great job!")
class UerrnoTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def testeagain(self):
print("Starting Test 1/9: EAGAIN - Try Again Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(EAGAIN)
try:
uart.read(1)
print("No error raised.\nCompleted Test 1/9: EAGAIN - FAILED")
self.failedtests["EAGAIN"] = "No error raised"
except OSError as ex:
if ex.errno == EAGAIN:
print("EAGAIN can be thrown and caught.\nCompleted Test 1/9: EAGAIN - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 1/9: EAGAIN - FAILED")
self.failedtests["EAGAIN"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 1/9: EAGAIN - FAILED")
self.failedtests["EAGAIN"] = ex.errno
def testebusy(self):
# No reliable hardware trigger; use FakeUART
print("Starting Test 2/9: EBUSY - Device Busy Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(EBUSY)
try:
uart.read(1)
print("No error raised.\nCompleted Test 2/9: EBUSY - FAILED")
self.failedtests["EBUSY"] = "No error raised"
except OSError as ex:
if ex.errno == EBUSY:
print("EBUSY can be thrown and caught.\nCompleted Test 2/9: EBUSY - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 2/9: EBUSY - FAILED")
self.failedtests["EBUSY"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 2/9: EBUSY - FAILED")
self.failedtests["EBUSY"] = ex.errno
def testecanceled(self):
# No reliable hardware trigger; use FakeUART
print("Starting Test 3/9: ECANCELED - Operation Canceled Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(ECANCELED)
try:
uart.read(1)
print("No error raised.\nCompleted Test 3/9: ECANCELED - FAILED")
self.failedtests["ECANCELED"] = "No error raised"
except OSError as ex:
if ex.errno == ECANCELED:
print("ECANCELED can be thrown and caught.\nCompleted Test 3/9: ECANCELED - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 3/9: ECANCELED - FAILED")
self.failedtests["ECANCELED"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 3/9: ECANCELED - FAILED")
self.failedtests["ECANCELED"] = ex.errno
def testeinval(self):
# Triggered by passing an out-of-range value to motor.control.limits()
print("Starting Test 4/9: EINVAL - Invalid Argument Error")
try:
usys.stderr.flush()
except (OSError) as ex:
if ex.errno == EINVAL:
print("EINVAL can be thrown and caught.\nCompleted Test 4/9: EINVAL - SUCCESSFUL")
self.successfultests += 1
elif errno_val == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 4/9: EINVAL - FAILED")
self.failedtests["EINVAL"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex}.\nCompleted Test 4/9: EINVAL - FAILED")
self.failedtests["EINVAL"] = str(ex)
def testeio(self):
# No reliable scriptable trigger (requires physical unplug); use FakeUART
print("Starting Test 5/9: EIO - I/O Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(EIO)
try:
uart.read(1)
print("No error raised.\nCompleted Test 5/9: EIO - FAILED")
self.failedtests["EIO"] = "No error raised"
except OSError as ex:
if ex.errno == EIO:
print("EIO can be thrown and caught.\nCompleted Test 5/9: EIO - SUCCESSFUL")
self.successfultests += 1
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 5/9: EIO - FAILED")
self.failedtests["EIO"] = ex.errno
def testenodev(self):
# Triggered by initializing a motor on an empty port
print("Starting Test 6/9: ENODEV - Device Not Found Error")
input("Make sure Port A doesn't have anything plugged in, then press Enter.")
try:
my_motor = self.motorclass(Port.A)
print("OS detected a motor when there was nothing. You may have allowed missing motors. This is useful for debugging, but not recommended for production as it can cause issues with device control.")
self.failedtests["ENODEV"] = "No error raised"
except OSError as ex:
if ex.errno == ENODEV:
print("There is no motor on this port. ENODEV can be thrown and caught.\nCompleted Test 6/9: ENODEV - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 6/9: ENODEV - FAILED")
self.failedtests["ENODEV"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 6/9: ENODEV - FAILED")
self.failedtests["ENODEV"] = ex.errno
def testeopnotsupp(self):
# No reliable scriptable trigger without specific hardware; use FakeUART
print("Starting Test 7/9: EOPNOTSUPP - Operation Not Supported Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(EOPNOTSUPP)
try:
uart.read(1)
print("No error raised.\nCompleted Test 7/9: EOPNOTSUPP - FAILED")
self.failedtests["EOPNOTSUPP"] = "No error raised"
except OSError as ex:
if ex.errno == EOPNOTSUPP:
print("EOPNOTSUPP can be thrown and caught.\nCompleted Test 7/9: EOPNOTSUPP - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 7/9: EOPNOTSUPP - FAILED")
self.failedtests["EOPNOTSUPP"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 7/9: EOPNOTSUPP - FAILED")
self.failedtests["EOPNOTSUPP"] = ex.errno
def testeperm(self):
print("Starting Test 8/9: EPERM - Operation Not Permitted Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
uart.set_error(EPERM)
try:
uart.read(1)
print("No error raised.\nCompleted Test 8/9: EPERM - FAILED")
self.failedtests["EPERM"] = "No error raised"
except OSError as ex:
if ex.errno == EPERM:
print("EPERM can be thrown and caught.\nCompleted Test 8/9: EPERM - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 8/9: EPERM - FAILED")
self.failedtests["EPERM"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 8/9: EPERM - FAILED")
self.failedtests["EPERM"] = ex.errno
def testetimedout(self):
# Triggered by FakeUART (or real UART) timing out on read
print("Starting Test 9/9: ETIMEDOUT - Timed Out Error")
uart = UARTDevice(Port.A, baudrate=9600, timeout=1000)
try:
data = uart.read(10)
print("No error raised.\nCompleted Test 9/9: ETIMEDOUT - FAILED")
self.failedtests["ETIMEDOUT"] = "No error raised"
except OSError as ex:
if ex.errno == ETIMEDOUT:
print("Timed out with synthetic UART device. ETIMEDOUT can be thrown and caught.\nCompleted Test 9/9: ETIMEDOUT - SUCCESSFUL")
self.successfultests += 1
elif ex.errno == EIO:
print("An unspecified error occurred (EIO).\nCompleted Test 9/9: ETIMEDOUT - FAILED")
self.failedtests["ETIMEDOUT"] = "EIO - Unspecified Error"
else:
print(f"Another error occurred with code: {ex.errno}.\nCompleted Test 9/9: ETIMEDOUT - FAILED")
self.failedtests["ETIMEDOUT"] = ex.errno
def print_results(self):
print(f"\n=== Results: {self.successfultests}/9 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class UIOTest(OSDiagnostics):
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
# uio contains BytesIO, StringIO, and FileIO, but due to SPIKE Prime's lack of a filesystem, the test will omit FileIO and only include BytesIO and StringIO
def testbytesio(self):
try:
buffer = uio.BytesIO()
buffer.write(b'Hello, ')
buffer.write(b'Pybricks byte stream!')
current_content = buffer.getvalue()
print(f"Buffer content (via getvalue()): {current_content}")
print(f"Current cursor position: {buffer.tell()}")
# TODO: After testing that BytesIO actually works on this system, add checks to make sure that the outputs match what they should.
buffer.seek(0)
read_data = buffer.read()
print(f"Read data (via read()): {read_data}")
print(f"Current cursor position after reading: {buffer.tell()}")
buffer.close()
print("Buffer was closed successfully.")
print("Completed Test 1/2: BytesIO - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("An unexpected error occured.")
print("Completed Test 1/2: BytesIO - FAILED")
self.failedtests["BytesIO"] = ex.errno
def teststringio(self):
try:
buffer = uio.StringIO()
buffer.write('Hello, ')
buffer.write('Pybricks string stream!')
current_content = buffer.getvalue()
print(f"Buffer content (via getvalue()): {current_content}")
print(f"Current cursor position: {buffer.tell()}")
# TODO: After testing that StringIO actually works on this system, add checks to make sure that the outputs match what they should.
buffer.seek(0)
read_data = buffer.read()
print(f"Read data (via read()): {read_data}")
print(f"Current cursor position after reading: {buffer.tell()}")
buffer.close()
print("Buffer was closed successfully.")
print("Completed Test 2/2: StringIO - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("An unexpected error occured.")
print("Completed Test 2/2: StringIO - FAILED")
self.failedtests["StringIO"] = ex.errno
def print_results(self):
self.testbytesio()
self.teststringio()
print(f"\n=== Results: {self.successfultests}/2 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class UJSONTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
# Tests ujson.dumps() and ujson.loads()
def testdumpsloads(self):
try:
original = {"robot": "Pybricks", "speed": 500, "active": True}
json_str = ujson.dumps(original)
print(f"Serialized (via dumps()): {json_str}")
restored = ujson.loads(json_str)
print(f"Deserialized (via loads()): {restored}")
# TODO: After confirming dumps/loads works on this system, add equality tests
print("Completed Test 1/3: dumps/loads - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("An unexpected error occurred.")
print("Completed Test 1/3: dumps/loads - FAILED")
self.failedtests["dumps/loads"] = getattr(ex, "errno", str(ex))
# Tests ujson.loads() raising ValueError on malformed input
def testloadsinvalid(self):
try:
ujson.loads("{not valid json}")
print("No error raised.")
print("Completed Test 2/3: loads invalid - FAILED")
self.failedtests["loads_invalid"] = "No error raised"
except ValueError:
print("ValueError raised on malformed JSON, as expected.")
print("Completed Test 2/3: loads invalid - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("An unexpected error occurred.")
print("Completed Test 2/3: loads invalid - FAILED")
self.failedtests["loads_invalid"] = getattr(ex, "errno", str(ex))
# Tests ujson.dump() and ujson.load() using a uio.StringIO stream
def testdumpload(self):
try:
original = {"hub": "SPIKE Prime", "port": "A", "value": 42}
stream = uio.StringIO()
ujson.dump(original, stream)
print(f"Serialized to stream (via dump()): {stream.getvalue()}")
stream.seek(0)
restored = ujson.load(stream)
print(f"Deserialized from stream (via load()): {restored}")
stream.close()
# TODO: After confirming dump/load works on this system, add
# equality assertions to verify round-trip fidelity.
print("Completed Test 3/3: dump/load (stream) - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("An unexpected error occurred.")
print("Completed Test 3/3: dump/load (stream) - FAILED")
self.failedtests["dump/load"] = getattr(ex, "errno", str(ex))
def print_results(self):
self.testdumpsloads()
self.testloadsinvalid()
self.testdumpload()
print(f"\n=== Results: {self.successfultests}/3 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class UMathTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def test_math(self):
EPSILON = 0.0001
if(umath.ceil(87.21) == 88):
self.successfultests += 1
else:
self.failedtests["ceilpos"] = "Failed"
if(umath.floor(14.61) == 14):
self.successfultests += 1
else:
self.failedtests["floorpos"] = "Failed"
if(umath.ceil(-87.21) == -87):
self.successfultests += 1
else:
self.failedtests["ceilneg"] = "Failed"
if(umath.floor(-14.61) == -15):
self.successfultests += 1
else:
self.failedtests["floorneg"] = "Failed"
if(umath.trunc(33.22) == 33):
self.successfultests += 1
else:
self.failedtests["truncpos"] = "Failed"
if(umath.trunc(-33.22) == -33):
self.successfultests += 1
else:
self.failedtests["truncneg"] = "Failed"
if(umath.fmod(6040, 3) == 1):
self.successfultests += 1
else:
self.failedtests["fmod"] = "Failed"
if(umath.fabs(88273) == 88273):
self.successfultests += 1
else:
self.failedtests["fabspos"] = "Failed"
if(umath.fabs(-27482) == 27482):
self.successfultests += 1
else:
self.failedtests["fabsneg"] = "Failed"
if(umath.fabs(-2742.233) == 2742.233):
self.successfultests += 1
else:
self.failedtests["fabsflt"] = "Failed"
if(umath.copysign(3928, -182) == -3928):
self.successfultests += 1
else:
self.failedtests["copysign"] = "Failed"
if(umath.exp(umath.log(1)) == 1):
self.successfultests += 2
else:
self.failedtests["eexp"] = "Failed"
self.failedtests["ln"] = "Failed"
if(abs(umath.e - 2.718282) < EPSILON):
self.successfultests += 1
else:
self.failedtests["e"] = "Failed"
if(umath.pow(19, 7) == 893871739):
self.successfultests += 1
else:
self.failedtests["pow"] = "Failed"
if(umath.sqrt(242064) == 492):
self.successfultests += 1
else:
self.failedtests["sqrt"] = "Failed"
if(abs(umath.pi - 3.141593) < EPSILON):
self.successfultests += 1
else:
self.failedtests["pi"] = "Failed"
if abs(umath.degrees(umath.pi * 3) - 540) < EPSILON:
self.successfultests += 1
else:
self.failedtests["degrees"] = "Failed"
if abs(umath.radians(270) - umath.pi * 1.5) < EPSILON:
self.successfultests += 1
else:
self.failedtests["radians"] = "Failed"
if(abs(umath.sin(umath.pi)) < EPSILON):
self.successfultests += 1
else:
self.failedtests["sin"] = "Failed"
if(abs(umath.asin(1) - umath.pi * 0.5) < EPSILON):
self.successfultests += 1
else:
self.failedtests["asin"] = "Failed"
if(abs(umath.cos(umath.pi) + 1) < EPSILON):
self.successfultests += 1
else:
self.failedtests["cos"] = "Failed"
if(abs(umath.acos(1)) < EPSILON):
self.successfultests += 1
else:
self.failedtests["acos"] = "Failed"
if(abs(umath.tan(umath.pi)) < EPSILON):
self.successfultests += 1
else:
self.failedtests["tan"] = "Failed"
if(abs(umath.atan(1) - umath.pi * 0.25) < EPSILON):
self.successfultests += 1
else:
self.failedtests["atan"] = "Failed"
if(abs(umath.atan2(1, -1) - umath.pi * 0.75) < EPSILON):
self.successfultests += 1
else:
self.failedtests["atan2"] = "Failed"
infinitenum = float('inf')
finitenum = 123456
if(umath.isfinite(finitenum) == True):
self.successfultests += 1
else:
self.failedtests["isfinitefinite"] = "Failed"
if(umath.isfinite(infinitenum) == False):
self.successfultests += 1
else:
self.failedtests["isfiniteinfinite"] = "Failed"
if(umath.isinf(finitenum) == False):
self.successfultests += 1
else:
self.failedtests["isinfinitefinite"] = "Failed"
if(umath.isinf(infinitenum) == True):
self.successfultests += 1
else:
self.failedtests["isinfiniteinfinite"] = "Failed"
nannum = float("nan")
if(umath.isnan(nannum) == True):
self.successfultests += 1
else:
self.failedtests["isnannan"] = "Failed"
if(umath.isnan(finitenum) == False):
self.successfultests += 1
else:
self.failedtests["isnannotnan"] = "Failed"
frac, integer = umath.modf(87.21)
if abs(integer - 87.0) < 0.01 and abs(frac - 0.21) < 0.01:
self.successfultests += 1
else:
self.failedtests["modf"] = "Failed"
mantissa, exponent = umath.frexp(64)
if mantissa == 0.5 and exponent == 7:
self.successfultests += 1
else:
self.failedtests["frexp"] = "Failed"
result = umath.ldexp(0.5, 7)
if result == 64:
self.successfultests += 1
else:
self.failedtests["ldexp"] = "Failed"
def print_results(self):
self.test_math()
print(f"\n=== Results: {self.successfultests}/35 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class URandomTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def testrandom(self):
NUM_SAMPLES = 6553
NUM_BUCKETS = 10
CHART_WIDTH = 50
SAMPLE_PEEK = 20
samples = [random() for _ in range(NUM_SAMPLES)]
bucket_counts = [0] * NUM_BUCKETS
for x in samples:
i = int(x * NUM_BUCKETS)
if i == NUM_BUCKETS:
i -= 1
bucket_counts[i] += 1
mean = sum(samples) / NUM_SAMPLES
ideal = NUM_SAMPLES / NUM_BUCKETS
max_count = max(bucket_counts)
print("=" * 66)
print(" random() distribution test n=" + str(NUM_SAMPLES))
print("=" * 66)
print("")
print(" Range Count Bar")
print(" -------------- ----- " + "-" * CHART_WIDTH)
for i in range(NUM_BUCKETS):
lo = i / NUM_BUCKETS
hi = (i + 1) / NUM_BUCKETS
count = bucket_counts[i]
bar = int(round(count / max_count * CHART_WIDTH))
dev = abs(count - ideal) / ideal
if dev <= 0.10:
marker = "#"
elif dev <= 0.20:
marker = "+"
else:
marker = "."
lo_str = "{:.2f}".format(lo)
hi_str = "{:.2f}".format(hi)
print(" " + "{:.2f}".format(lo) + " - " + "{:.2f}".format(hi) + " " + str(count) + " " + marker * bar)
print("")
print(" Samples : " + str(NUM_SAMPLES))
print(" Mean : " + "{:.6f}".format(mean) + " (ideal 0.500000)")
print(" Min : " + "{:.6f}".format(min(samples)))
print(" Max : " + "{:.6f}".format(max(samples)))
print(" Legend : # within 10% + within 20% . beyond 20%")
print("")
print(" First " + str(SAMPLE_PEEK) + " raw values:")
row = " "
for idx, val in enumerate(samples[:SAMPLE_PEEK], 1):
row += "{:.4f} ".format(val)
if idx % 5 == 0:
print(row)
row = " "
if row.strip():
print(row)
print("")
if(abs(0.5 - mean) < 0.06):
print("Random Distribution Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Random Distribution Test: FAILED")
self.failedtests["randomdistribution"] = "Too much error"
def test_other_rands(self):
N = 1000
choicelist = ["apple", "banana", "grape", "orange"]
randint_vals = [urandom.randint(1, 100) for _ in range(N)]
randint_mean = sum(randint_vals) / N
print("Randint mean (ideally 50.5): {:.4f}".format(randint_mean))
if abs(50.5 - randint_mean) < 3.0:
print("Randint Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Randint Test: FAILED")
self.failedtests["randint"] = "Too much error"
getrandbits_vals = [urandom.getrandbits(7) for _ in range(N)]
getrandbits_mean = sum(getrandbits_vals) / N
print("Getrandbits(7) mean (ideally 63.5): {:.4f}".format(getrandbits_mean))
if abs(63.5 - getrandbits_mean) < 4:
print("Getrandbits Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Getrandbits Test: FAILED")
self.failedtests["getrandbits"] = "Too much error"
randrange_vals = [urandom.randrange(1, 1001, 4) for _ in range(N)]
randrange_mean = sum(randrange_vals) / N
print("Randrange(1,1001,4) mean (ideally 501.0): {:.4f}".format(randrange_mean))
if abs(501.0 - randrange_mean) < 20.0:
print("Randrange Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Randrange Test: FAILED")
self.failedtests["randrange"] = "Too much error"
uniform_vals = [urandom.uniform(1, 10) for _ in range(N)]
uniform_mean = sum(uniform_vals) / N
print("Uniform(1,10) mean (ideally 5.5): {:.4f}".format(uniform_mean))
if abs(5.5 - uniform_mean) < 0.3:
print("Uniform Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Uniform Test: FAILED")
self.failedtests["uniform"] = "Too much error"
choice_counts = {}
for item in choicelist:
choice_counts[item] = 0
for _ in range(N):
choice_counts[urandom.choice(choicelist)] += 1
ideal_pct = 100.0 / len(choicelist)
print("Choice distribution (ideally {:.1f}% each):".format(ideal_pct))
choice_ok = True
for item in choicelist:
pct = choice_counts[item] / N * 100
print(" " + item + ": {:.1f}%".format(pct))
if abs(pct - ideal_pct) > 5.0:
choice_ok = False
if choice_ok:
print("Choice Test: SUCCESSFUL")
self.successfultests += 1
else:
print("Choice Test: FAILED")
self.failedtests["choice"] = "Too much error"
def print_results(self):
self.testrandom()
self.test_other_rands()
print(f"\n=== Results: {self.successfultests}/6 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class USelectTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def print_results(self):
# Register the standard input so we can read keyboard presses.
keyboard = uselect.poll()
keyboard.register(usys.stdin)
print("Type a few keys, make sure you get back what character you typed, then press Escape.")
while True:
# Check if a key has been pressed.
if keyboard.poll(0):
# Read the key and print it.
key = usys.stdin.read(1)
if key == '\x1b':
print("Escape key pressed. Exiting...")
break
else:
print("Pressed:", key)
result = input("Input Y if the results were accurate:")
if(result == "Y" or result == "y"):
print(f"\n=== Results: 1/1 tests passed ===")
self.successfultests += 1
else:
self.failedtests["input"] = "Unsatisfied"
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class UStructTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def print_results(self):
packed = ustruct.pack('ii', 42, 100)
print(f'Packed bytes using pack(): {packed}')
unpacked = ustruct.unpack('ii', packed)
print(f'Unpacked values using unpack(): {unpacked}')
print(unpacked == (42, 100))
if(unpacked == (42, 100)):
print("Completed Test 1/2: pack - SUCCESSFUL")
self.successfultests += 1
else:
print("Completed Test 1/2: pack - FAILED")
self.failedtests["pack"] = "Failed"
format_string = 'hhl'
size = ustruct.calcsize(format_string)
buffer = bytearray(size)
ustruct.pack_into(format_string, buffer, 0, 5, 10, 15)
print("Packed buffer using pack_into():", buffer)
unpackedfrom = ustruct.unpack_from(format_string, buffer, 0)
print("Unpacked buffer using unpack_from():", unpackedfrom)
if(unpackedfrom == (5, 10, 15)):
print("Completed Test 2/2: pack_into - SUCCESSFUL")
self.successfultests += 1
else:
print("Completed Test 2/2: pack_into - FAILED")
self.failedtests["pack_into"] = "Failed"
print(f"\n=== Results: {self.successfultests}/2 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
class USysTest:
def __init__(self, hub, motorclass):
self.hub = hub
self.motorclass = motorclass
self.successfultests = 0
self.failedtests = {}
def printVersionDiagnostics(self):
try:
print("Hub version information:", pybricksforvers.version)
print("MicroPython version:", usys.version)
print("Pybricks version information:", usys.version_info)
print("MicroPython information:", usys.implementation)
self.successfultests += 1
print("Completed Test 1/4: versioninfo - SUCCESSFUL")
except Exception as ex:
self.failedtests["versioninfo"] = ex.errno
print("Completed Test 4/4: versioninfo - FAILED")
def teststdin(self):
# Register the standard input so we can read keyboard presses.
keyboard = uselect.poll()
keyboard.register(usys.stdin)
print("Type a few keys, make sure you get back what character you typed, then press Escape.")
while True:
# Check if a key has been pressed.
if keyboard.poll(0):
# Read the key and print it.
key = usys.stdin.read(1)
if key == '\x1b':
print("Escape key pressed. Exiting...")
break
else:
print("Pressed:", key)
result = input("Input Y if the results were accurate:")
if(result == "Y" or result == "y"):
print("Completed Test 1/4: stdin - SUCCESSFUL")
self.successfultests += 1
else:
self.failedtests["stdin"] = "Unsatisfied"
print("Completed Test 1/4: stdin - FAILED")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
def teststdout(self):
usys.stdout.flush()
try:
usys.stdout.buffer.write(b"stdout worked!\n")
print("Completed Test 2/4: stdout - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("Completed Test 2/4: stdout - FAILED")
self.failedtests["stdout"] = ex.errno
def teststderr(self):
usys.stdout.flush()
try:
usys.stderr.buffer.write(b"stderr worked!\n")
print("Completed Test 3/4: stderr - SUCCESSFUL")
self.successfultests += 1
except Exception as ex:
print("Completed Test 3/4: stderr - FAILED")
self.failedtests["stderr"] = ex.errno
def print_results(self):
self.teststdin()
self.teststdout()
self.teststderr()
self.printVersionDiagnostics()
print(f"\n=== Results: {self.successfultests}/4 tests passed ===")
if self.failedtests:
print("Failed tests:")
for key, value in self.failedtests.items():
print(f" {key}: {value}")
#diag = OSDiagnostics(hub=PrimeHub(), motorclass=Motor)
#diag.testAll()

1
experiments/game.py Normal file
View File

@@ -0,0 +1 @@
# will use the light matrix and btns

View File

@@ -0,0 +1,62 @@
from pybricks.pupdevices import ColorSensor
from pybricks.parameters import Color, Port
from pybricks.tools import run_task
from pybricks.tools import wait
from pybricks.hubs import PrimeHub
hub = PrimeHub()
color_sensor = ColorSensor(Port.F) # Change the port to your color sensor's port
# Function to classify color based on HSV
def detect_color(h, s, v, reflected):
if reflected > 4:
if h < 4 or h > 350: # red
return "Red"
elif 3 < h < 40 and s > 70: # orange
return "Orange"
elif 47 < h < 56: # yellow
return "Yellow"
elif 70 < h < 160: # green - your brick should approach from the top for accuracy
return "Green"
elif 195 < h < 198: # light blue
return "Light_Blue"
elif 210 < h < 225: # blue - your brick should approach from the top for accuracy
return "Blue"
elif 260 < h < 350: # purple
return "Purple"
else:
return "Unknown"
return "Unknown"
async def main():
while True:
h, s, v = await color_sensor.hsv()
reflected = await color_sensor.reflection()
color = detect_color(h, s, v, reflected)
if color == "Green":
print('Running Task 1')
# Run a function with await Function() here
elif color == "Red":
print('Running Task 2')
# Run a function with await Function() here
elif color == "Yellow":
print('Running Task 3')
# Run a function with await Function() here
elif color == "Blue":
print('Running Task 4')
# Run a function with await Function() here
elif color == "Orange":
print('Running Task 5')
# Run a function with await Function() here
elif color == "Purple":
print('Running Task 6')
# Run a function with await Function() here
elif color == "Light_Blue":
print("Running Task 7")
# Run a function with await Function() here
else:
print(f"Unknown color detected (Hue: {h}, Sat: {s}, Val: {v})")
#pass
await wait(10)
# Run the main function
run_task(main())

44
templates/logger.py Normal file
View File

@@ -0,0 +1,44 @@
from pybricks.tools import StopWatch
class Logger:
def __init__(self, verboseness=7):
self.time = StopWatch()
self.time.pause()
self.verboseness = verboseness
self.lvldict = {
0: "FATAL",
1: "ALERT",
2: "CRIT",
3: "ERR",
4: "WARNING",
5: "NOTICE",
6: "INFO",
7: "DEBUG"
}
def start(self):
self.time.reset()
self.time.resume()
def log(self, message, level, origin):
if level <= self.verboseness:
ms = self.time.time()
timestamp = "{:02d}:{:02d}.{:03d}".format(
(ms // 60000) % 60,
(ms // 1000) % 60,
ms % 1000
)
label = self.lvldict.get(level, "UNKNOWN")
padding = " " * (7 - len(label))
print("[{}] {}{} [{}] {}".format(timestamp, label, padding, origin, message))
def fatal(self, message, origin): self.log(message, 0, origin)
def alert(self, message, origin): self.log(message, 1, origin)
def crit(self, message, origin): self.log(message, 2, origin)
def err(self, message, origin): self.log(message, 3, origin)
def warning(self, message, origin): self.log(message, 4, origin)
def notice(self, message, origin): self.log(message, 5, origin)
def info(self, message, origin): self.log(message, 6, origin)
def debug(self, message, origin): self.log(message, 7, origin)
def crash(self, message, origin):
self.log(message, 0, origin)
raise FatalLoggerError("[FATAL] [{}] {}".format(origin, message))

View File

@@ -0,0 +1,9 @@
from pybricks.iodevices import XboxController
from pybricks.parameters import Direction, Port
from pybricks.tools import wait
xbox = XboxController()
while True:
print("Xbox left joystick x-position:", xbox.joystick_left()[0])
wait(50)

View File

@@ -0,0 +1,25 @@
from pybricks.iodevices import UARTDevice as _UARTDevice
from pybricks.tools import wait
from uerrno import ETIMEDOUT
class FakeUART:
def __init__(self, port, baudrate, timeout):
self.timeout = timeout
print("Warning: No physical UART detected. Using simulator.")
def read(self, length=1):
if self.timeout is not None:
wait(self.timeout)
raise OSError(ETIMEDOUT)
else:
while True:
wait(1000)
def write(self, data):
pass
def UARTDevice(port, baudrate=9600, timeout=None):
try:
return _UARTDevice(port, baudrate, timeout)
except OSError:
return FakeUART(port, baudrate, timeout)

10
tests/testgc.py Normal file
View File

@@ -0,0 +1,10 @@
input("gc")
try:
import gc
except Exception as ex:
print(ex.errno)
input("ugc")
try:
import ugc
except Exception as ex:
print(ex.errno)