diff --git a/diagnostics/BatteryDiagnostics.py b/diagnostics/BatteryDiagnostics.py new file mode 100644 index 0000000..682793f --- /dev/null +++ b/diagnostics/BatteryDiagnostics.py @@ -0,0 +1,49 @@ +from pybricks.tools import wait +import umath +class BatteryDiagnostics: + def __init__(self, hub): + self.voltage = 0 + self.current = 0 + self.hub = hub + def printVoltage(self): + self.voltage = self.hub.battery.voltage() + if self.voltage > 7800: + print(f"Battery voltage is sufficient: {self.voltage}") + elif self.voltage < 7800 : + print(f"Charging needed: {self.voltage}") + def printCurrent(self): + self.current = self.hub.battery.current() + print("Battery current:", self.current) + def printAll(self): + timeelapsed = 0 + voltageList = [] + currentList = [] + while True: + print("\n\n\n\n\n") + self.printVoltage() + voltageList.append(self.voltage) + self.printCurrent() + currentList.append(self.current) + wait(50) + timeelapsed += 50 + + if(timeelapsed >= 3000): + break + print("--------------FINAL RESULTS OF BATTERY DIAGNOSTICS---------------") + print("Voltage deviation:", self.stdev(voltageList)) + print("Current deviation:", self.stdev(currentList)) + def stdev(self, vals): + DATA = vals + if len(DATA) < 2: + return 0 + # Calculate the mean + MEAN = sum(DATA) / len(DATA) + + # Calculate the variance (sum of squared differences from the mean, divided by n-1 for sample standard deviation) + VARIANCE = sum([(x - MEAN) ** 2 for x in DATA]) / float(len(DATA) - 1) + + # Calculate the standard deviation (square root of the variance) + STD_DEV_MANUAL = umath.sqrt(VARIANCE) + + + return (STD_DEV_MANUAL) \ No newline at end of file diff --git a/diagnostics/ColorSensorDiagnostics.py b/diagnostics/ColorSensorDiagnostics.py new file mode 100644 index 0000000..6b14971 --- /dev/null +++ b/diagnostics/ColorSensorDiagnostics.py @@ -0,0 +1,45 @@ +from pybricks.parameters import Color, Port, Stop +from pybricks.tools import wait, StopWatch + +class ColorSensorDiagnostics: + def __init__(self, hub, colorsensorclass): + self.colorsensor = None + self.PORT_MAP = { + "A": Port.A, + "B": Port.B, + "C": Port.C, + "D": Port.D, + "E": Port.E, + "F": Port.F, + } + def initializeColorSensor(self): + VALID_PORTS = {"A", "B", "C", "D", "E", "F"} + while True: + colorinput = input( + "This will test your color sensor.\n" + "Enter the port for the color sensor you would like to test (A, B, C, D, E, or F): " + ).strip().upper() + if colorinput not in VALID_PORTS: + print("Invalid port. Please enter A-F.") + continue + try: + if self.colorsensor is None: + self.colorsensor = self.colorsensorclass(self.PORT_MAP[colorinput]) + print(f"Color Sensor initialized on port {colorinput}.") + else: + print(f"Reusing existing color sensor on port {colorinput}.") + break + + except OSError as e: + if e.errno == 16: # EBUSY + print(f"Port {colorinput} is already in use. Reusing existing color sensor.") + break + else: + print(f"Error initializing color sensor on port {colorinput}: {e}") + print("Make sure a color sensor is actually connected to this port.") + self.colorsensor = None + self.colorsensor.detectable_colors(Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE, Color.WHITE, Color.NONE) + def printAll(self): + while True: + print("HSV output:", self.colorsensor.hsv) + print("Detected color:", self.colorsensor.color()) diff --git a/diagnostics/DriveBaseDiagnostics.py b/diagnostics/DriveBaseDiagnostics.py new file mode 100644 index 0000000..64a1e51 --- /dev/null +++ b/diagnostics/DriveBaseDiagnostics.py @@ -0,0 +1,51 @@ +from pybricks.parameters import Direction, Port, Side, Stop +from pybricks.robotics import DriveBase +from pybricks.tools import wait, StopWatch + +from usys import stdin +from uselect import poll + +class DriveBaseDiagnostics: + def __init__(self, hub, motorclass, dbclass): + self.PORT_MAP = { + "A": Port.A, + "B": Port.B, + "C": Port.C, + "D": Port.D, + "E": Port.E, + "F": Port.F, + } + def initializeDriveBase(): + leftmotorport = input("Enter the left motor port: ") + left_motor = self.motorclass(port_map[leftmotorport], Direction.COUNTERCLOCKWISE) + rightmotorport = input("Enter the right motor port: ") + right_motor = self.motorclass(port_map[rightmotorport],Direction.CLOCKWISE) + # DriveBase configuration + WHEEL_DIAMETER = 68.8 # mm + AXLE_TRACK = 180 # mm + drive_base = self.dbclass(left_motor, right_motor, WHEEL_DIAMETER, AXLE_TRACK) + drive_base.settings(600, 500, 300, 200) + drive_base.use_gyro(True) + def driveRobot(): + # Register the standard input so we can read keyboard presses. + keyboard = poll() + keyboard.register(stdin) + + while True: + # Check if a key has been pressed. + if keyboard.poll(0): + # Read the key and print it. + key = stdin.read(1) + print("You pressed:", key) + if(key == "W"): + print("Insert robot go forward code here") + elif(key == "A"): + print("Insert robot go left code here") + elif(key == "S"): + print("Insert robot go backwards code here") + elif(key == "D"): + print("Insert robot go right code here") + elif(key == "X") + break + else: + print("That key doesn't do anything.") \ No newline at end of file diff --git a/diagnostics/FullDiagnostics.py b/diagnostics/FullDiagnostics.py new file mode 100644 index 0000000..c6a1c10 --- /dev/null +++ b/diagnostics/FullDiagnostics.py @@ -0,0 +1,59 @@ +from pybricks.hubs import PrimeHub +from pybricks.pupdevices import Motor, ColorSensor, UltrasonicSensor, ForceSensor +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 +battery = BatteryDiagnostics(HUB) +motor = MotorDiagnostics(HUB, Motor) +colorsensor = ColorSensorDiagnostics(HUB, ColorSensor) +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") +print(""" + ███████████ █████ █████ ██████ █████ █████████ ██████ ██████ █████ █████████ █████████ +▒▒███▒▒▒▒▒███▒▒███ ▒▒███ ▒▒██████ ▒▒███ ███▒▒▒▒▒███ ▒▒██████ ██████ ▒▒███ ███▒▒▒▒▒███ ███▒▒▒▒▒███ + ▒███ ▒███ ▒▒███ ███ ▒███▒███ ▒███ ▒███ ▒███ ▒███▒█████▒███ ▒███ ███ ▒▒▒ ▒███ ▒▒▒ + ▒██████████ ▒▒█████ ▒███▒▒███▒███ ▒███████████ ▒███▒▒███ ▒███ ▒███ ▒███ ▒▒█████████ + ▒███▒▒▒▒▒▒ ▒▒███ ▒███ ▒▒██████ ▒███▒▒▒▒▒███ ▒███ ▒▒▒ ▒███ ▒███ ▒███ ▒▒▒▒▒▒▒▒███ + ▒███ ▒███ ▒███ ▒▒█████ ▒███ ▒███ ▒███ ▒███ ▒███ ▒▒███ ███ ███ ▒███ + █████ █████ █████ ▒▒█████ █████ █████ █████ █████ █████ ▒▒█████████ ▒▒█████████ +▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒ + +The free and open source diagnostics tool for the LEGO® Education SPIKE™ Prime robots, designed for FIRST Lego League. +Developed by Team 65266, Lego Dynamics. + """ + ) +while True: + + print("\nWhich diagnostic do you want to perform?") + print("Enter 'b' for battery diagnostics") + print("Enter 'm' for motor diagnostics") + print("Enter 'cs' for color sensor diagnostics") + print("Enter 'q' to quit") + + choice = input("Your choice: ").strip().lower() + + if choice == "b": + print("-----------------------BATTERY DIAGNOSTICS-----------------------") + print("This test will check the battery voltage and current. It will measure these over a period of 3 seconds and provide average and deviation values. Your voltage should be above 7800 mV for optimal performance.") + input("Press Enter to begin the battery diagnostics.") + battery.printAll() + print("Battery diagnostics completed.") + + elif choice == "m": + print("------------------------MOTOR DIAGNOSTICS------------------------") + motor.fullTest() + print("Motor diagnostics completed.") + + elif choice == "q": + print("Diagnostics completed successfully. Exiting with code 0. Good luck in the robot game!") + break + elif choice == "cs": + print("---------------------COLOR SENSOR DIAGNOSTICS---------------------") + break + else: + print("Invalid choice. Please enter 'b', 'm', or 'q'.") \ No newline at end of file diff --git a/diagnostics/HubDiagnostics.py b/diagnostics/HubDiagnostics.py new file mode 100644 index 0000000..acb8906 --- /dev/null +++ b/diagnostics/HubDiagnostics.py @@ -0,0 +1,28 @@ +from pybricks.tools import wait, StopWatch +from pybricks import version +from OtherFunctions import vprint +import usys + +print("Pybricks version information:", version) +print("MicroPython information:", usys.implementation) +print("MicroPython version:", usys.version) +class HubDiagnostics: + def __init__(self, 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): + vprint(f"Turning on pixel at position {x}, {y}...", v) + display.pixel(x, y, brightness=100) + wait(100) + vprint(f"Turning off pixel at position {x}, {y}...", v) + display.pixel(x, y, brightness=0)