diff --git a/lightstrip.py b/lightstrip.py index e0fd76f..176b854 100644 --- a/lightstrip.py +++ b/lightstrip.py @@ -3,32 +3,14 @@ # Serial Data Modes modes = { - "READY_WITHOUT_NOTE": "1", + "AMP_SIGNAL": "1", "READY_TO_SHOOT": "2", "ROBOT_CONTAINS_NOTE": "3", - "CENTER_CAM_SEES_NOTE": "4", - "SIDE_CAM_SEES_NOTE": "7", - "PURELY_ENABLED": "5", # None of modes 1-4 are active - "ALL_CAMS_WORKING_DEFAULT": "8", - "NO_CAMS_WORKING_DEFEAULT": "9", - "SOME_CAMS_WORKING_DEFAULT": "10", - "ALL_CAMS_WORKING_CUSTOM": "11", - "NO_CAMS_WORKING_CUSTOM": "12", - "SOME_CAMS_WORKING_CUSTOM": "13", - "ROBOT_NOCODE": "15" -} - -colors = { - "GREEN": (0, 255, 0), - "CYAN": (0, 255, 255), - "ORANGE": (255, 140, 0), - "YELLOW": (255, 255, 0), - "HOT_PINK": (255, 105, 180), - "PURPLE": (160, 32, 240), - "BLUE": (0, 0, 255), - "WHITE": (255, 255, 255), - "RED": (255, 0, 0), - "NO_COLOR": (0, 0, 0) + "VISION_SEES_NOTE": "4", + "DISABLED_WITHOUT_AUTO": "32", + "DISABLED_WITH_AUTO": "33", + "PURELY_ENABLED": "34", # None of modes 1-4 are active + "ROBOT_NOCODE": "31" } @@ -60,17 +42,16 @@ def assign_mode(self, current_mode: str, last_mode: str): self.pattern_starting_loop = patterns.loopcount # Update color and pattern on light to display - if current_mode == modes["READY_TO_SHOOT"]: + if current_mode == modes["AMP_SIGNAL"]: + self.pattern_function = patterns.rainbow + + elif current_mode == modes["READY_TO_SHOOT"]: # Ready to shoot, railgun pattern (requested by drivers) - self.primary = colors["GREEN"] + self.primary = (0, 255, 0) self.pattern_function = patterns.railgun - elif current_mode == modes["READY_WITHOUT_NOTE"]: - self.primary = colors["GREEN"] - self.pattern_function = patterns.static - elif current_mode == modes["ROBOT_CONTAINS_NOTE"]: - self.primary = colors["ORANGE"] + self.primary = (255, 165, 0) self.pattern_function = patterns.static elif current_mode == modes["CENTER_CAM_SEES_NOTE"]: @@ -90,24 +71,24 @@ def assign_mode(self, current_mode: str, last_mode: str): self.pattern_function = patterns.wavy elif current_mode == modes["NO_CAMS_WORKING_DEFEAULT"]: - self.primary = colors["PURPLE"] + self.primary == colors["PURPLE"] self.pattern_function = patterns.breathing elif current_mode == modes["ALL_CAMS_WORKING_CUSTOM"]: - self.primary = colors["BLUE"] + self.primary == colors["HOT_PINK"] self.pattern_function = patterns.static elif current_mode == modes["SOME_CAMS_WORKING_CUSTOM"]: - self.primary = colors["BLUE"] + self.primary == colors["HOT_PINK"] self.pattern_function = patterns.wavy elif current_mode == modes["NO_CAMS_WORKING_CUSTOM"]: - self.primary = colors["BLUE"] + self.primary == colors["HOT_PINK"] self.pattern_function = patterns.breathing elif current_mode == modes["PURELY_ENABLED"]: - self.primary = colors["WHITE"] + self.primary = (255, 255, 255) self.pattern_function = patterns.static else: - self.primary = colors["RED"] + self.primary = (255, 0, 0) self.pattern_function = patterns.static \ No newline at end of file diff --git a/main.py b/main.py index 3136517..7ac902f 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ -from main_loop import main +# from main_loop import main +from serial_loop import main if __name__ == "__main__": main() \ No newline at end of file diff --git a/main_loop.py b/main_loop.py index 960b1fe..af283c1 100644 --- a/main_loop.py +++ b/main_loop.py @@ -104,7 +104,8 @@ def main_loop(): patterns.loopcount = patterns.loopcount + 1 # Read data sent by RoboRIO - current_mode = str(get_binary_data()) + # current_mode = str(get_binary_data()) + current_mode = "11" # Match lights with serial data and update lights #for lightstrip in lightstrips: diff --git a/patterns.py b/patterns.py index 6228cb1..f8b3fb5 100644 --- a/patterns.py +++ b/patterns.py @@ -7,23 +7,41 @@ # Constant color -def static(light): +def static(light: LightStrip): for pixel in range(light.PIXEL_COUNT): light.neopixel[pixel] = light.primary light.neopixel.show() -# Gradient breathing -def breathing(light): +# Gradient flashing +def flashing(light: LightStrip): multiplier = sin(loopcount / 5) + 1 for pixel in range(light.PIXEL_COUNT): light.neopixel[pixel] = tuple(x * (multiplier/2) for x in light.primary) light.neopixel.show() + +# Alternates between two color of lights, Ex. +# Loop 1: All green +# Loop 2: All red +def alternating(light: LightStrip): + global alternating_loopcount + for pixel in range(light.PIXEL_COUNT): + # Alternate appproximately 2 times a second + if loopcount % (frames_per_second // 2) != light.pattern_starting_loop % (frames_per_second // 2): + continue + + alternating_loopcount += 1 + if alternating_loopcount % 2 == 0: + light.neopixel[pixel] = light.primary + else: + light.neopixel[pixel] = light.secondary + light.neopixel.show() + # Think of this pattern as if you are static and cars in front of you # Are constantly driving by (one direction) -def wavy(light): +def wavy(light: LightStrip): for pixel in range(light.PIXEL_COUNT): multiplier = max(0, min(sin(pixel + loopcount), 1)) light.neopixel[pixel] = tuple(x * multiplier for x in light.primary) @@ -31,7 +49,7 @@ def wavy(light): # Disco party baby! -def rainbow(light): +def rainbow(light: LightStrip): for pixel in range(light.PIXEL_COUNT): light.neopixel[pixel] = colorwheel(((255 / frames_per_second) * loopcount) % 255) light.neopixel.show() @@ -54,23 +72,9 @@ def alternating(light): light.neopixel.show() # Charge up -def railgun(light): +def railgun(light: LightStrip): for pixel in range(light.PIXEL_COUNT): - if ((loopcount - light.pattern_starting_loop) % light.PIXEL_COUNT) > pixel: - light.neopixel[pixel] = light.primary - else: - light.neopixel[pixel] = (0, 0, 0) - light.neopixel.show() - - -def flashing(light): - global alternating_loopcount - loop = loopcount - light.pattern_starting_loop - if loop % (frames_per_second // 2) == 0: - alternating_loopcount += 1 - - for pixel in range(light.PIXEL_COUNT): - if alternating_loopcount % 2 == 0: + if loopcount - light.pattern_starting_loop > pixel: light.neopixel[pixel] = light.primary else: light.neopixel[pixel] = (0, 0, 0) diff --git a/serial_loop.py b/serial_loop.py new file mode 100644 index 0000000..946b2b6 --- /dev/null +++ b/serial_loop.py @@ -0,0 +1,88 @@ +""" +MODES: +[31] No code on robot: +RoboRIO inactive/not receiving serial data from RoboRIO + +[32] Disabled without auto +RoboRIO is disabled, and has NO autonomous program set + +[33] Disabled with auto +RoboRIO is disabled, and DOES have autonomous program set + + +--< Modes for when RoboRIO is enabled >-- +Priority: 1 > 2 > 3 > 4 > 34 + +[34] Enabled +RoboRIO is enabled, but none of the above are active. + +[1] Signal: +For communication with teammates to activate amplifier + +[2] Ready to shoot: +The robot shooter and arm is in position, ready to shoot note + +[3] Has note: +The robot currently is holding a note + +[4] Vision: +The robot spots a note (tells the driver that they can press a button for +robot to retrieve a note) +""" + + +import supervisor +import board +from lightstrip import LightStrip, modes +import patterns +import time +import sys + +# Serial data variables +serial = sys.stdin +tolerance = 2 +tolerance_count = 0 +current_mode = modes["ROBOT_NOCODE"] +last_mode = modes["ROBOT_NOCODE"] + +# Create light objects +strip1 = LightStrip(board.D5, 8) +lightstrips: tuple[LightStrip] = (strip1,) + + +# Retrieves and returns serial data sent by Java side +def get_serial_data() -> str: + global tolerance_count + + # Return serial data if any + if supervisor.runtime.serial_bytes_available: + data = serial.readline() + + if not data.isspace(): + return data.strip() + + return last_mode + + +def main_loop(): + global current_mode + global last_mode + + # Increment loopcount + patterns.loopcount += 1 + + # Read serial data sent by RoboRIO + current_mode = str(get_serial_data()) + + # # Match lights with serial data and update lights + for ls in lightstrips: + ls.assign_mode(current_mode, last_mode) + ls.pattern_function(ls) + + last_mode = current_mode + + +def main(): + while True: + main_loop() + time.sleep(1 / patterns.frames_per_second) \ No newline at end of file diff --git a/test_serial.bat b/test_serial.bat new file mode 100644 index 0000000..9fbdeb8 --- /dev/null +++ b/test_serial.bat @@ -0,0 +1,13 @@ +REM how to run: ./test_serial.bat + +@echo off +REM define variables +set COM_PORT = COM15 +set BAUD_RATE = 115200 + +( + for /l %%x in (1, 1, 4) do ( + echo %%x + timeout /t 2 >nul + ) +) | plink.exe -batch -v -serial COM15 -sercfg 115200,8,1,n,N \ No newline at end of file