From bacfacf116ef52b702dc5ead5e6f53087981e0ed Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Mon, 20 May 2024 18:43:10 -0400 Subject: [PATCH 01/24] chnage port depending on argument --- .../game_controller.py | 35 ++++++++++++++----- .../thunderscope/thunderscope_main.py | 6 +++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index a8c01f87cb..a8a5e33c6a 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -27,7 +27,7 @@ class Gamecontroller(object): REFEREE_IP = "224.5.23.1" CI_MODE_OUTPUT_RECEIVE_BUFFER_SIZE = 9000 - def __init__(self, supress_logs: bool = False) -> None: + def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None: """Run Gamecontroller :param supress_logs: Whether to suppress the logs @@ -37,8 +37,15 @@ def __init__(self, supress_logs: bool = False) -> None: # We need to find 2 free ports to use for the gamecontroller # so that we can run multiple gamecontroller instances in parallel self.referee_port = self.next_free_port() - self.ci_port = self.next_free_port() + + self.ci_port = gamecontroller_port + if gamecontroller_port is None: + self.ci_port = self.next_free_port() + if not self.is_valid_port(self.ci_port): + raise Exception("Port: {} is not available!".format(self.ci_port)) + + print("I am using: {} port".format(self.ci_port)) # this allows gamecontroller to listen to override commands self.command_override_buffer = ThreadSafeBuffer( buffer_size=2, protobuf_type=ManualGCCommand @@ -55,6 +62,7 @@ def __enter__(self) -> "self": command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] command += ["-ciAddress", f"localhost:{self.ci_port}"] + print(f"command: {command}") if self.supress_logs: with open(os.devnull, "w") as fp: self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) @@ -102,6 +110,20 @@ def refresh(self): ) manual_command = self.command_override_buffer.get(return_cached=False) + def is_valid_port(self, port): + """ + :param port: the port we are checking + :return: True if the port is available, False otherwise + """ + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + sock.bind(("", port)) + sock.close() + return True + except OSError: + return False + def next_free_port(self, port: int = 40000, max_port: int = 65535) -> None: """Find the next free port. We need to find 2 free ports to use for the gamecontroller so that we can run multiple gamecontroller instances in parallel. @@ -111,15 +133,10 @@ def next_free_port(self, port: int = 40000, max_port: int = 65535) -> None: :return: The next free port """ - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - while port <= max_port: - try: - sock.bind(("", port)) - sock.close() + if self.is_valid_port(port): return port - except OSError: - port += 1 + port += 1 raise IOError("no free ports") diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index fd53817470..df592004d7 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -217,6 +217,8 @@ default=False, help="Whether to populate with default robot positions (False) or start with an empty field (True) for AI vs AI", ) + + parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') args = parser.parse_args() @@ -225,6 +227,7 @@ if args.interface is None: parser.error("Must specify interface") + ########################################################################### # Visualize CPP Tests # ########################################################################### @@ -428,7 +431,8 @@ def __ticker(tick_rate_ms: int) -> None: should_restart_on_crash=False, run_sudo=args.sudo, ) as yellow_fs, Gamecontroller( - supress_logs=(not args.verbose) + supress_logs=(not args.verbose), + gamecontroller_port=args.gamecontroller_port ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. From d620120b8b64e8a62a7cecaa1cd880e8fa32afdb Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Mon, 20 May 2024 18:44:59 -0400 Subject: [PATCH 02/24] added docs --- .../thunderscope/binary_context_managers/game_controller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index a8a5e33c6a..515745669c 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -45,7 +45,6 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None if not self.is_valid_port(self.ci_port): raise Exception("Port: {} is not available!".format(self.ci_port)) - print("I am using: {} port".format(self.ci_port)) # this allows gamecontroller to listen to override commands self.command_override_buffer = ThreadSafeBuffer( buffer_size=2, protobuf_type=ManualGCCommand @@ -112,6 +111,8 @@ def refresh(self): def is_valid_port(self, port): """ + Check if a port is available + :param port: the port we are checking :return: True if the port is available, False otherwise """ From 1557448fa64ebe09366b8604bb4fdebfb066c0e7 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Mon, 20 May 2024 19:06:46 -0400 Subject: [PATCH 03/24] remove stuff --- .../thunderscope/binary_context_managers/game_controller.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 515745669c..13140abf11 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -61,7 +61,6 @@ def __enter__(self) -> "self": command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] command += ["-ciAddress", f"localhost:{self.ci_port}"] - print(f"command: {command}") if self.supress_logs: with open(os.devnull, "w") as fp: self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) From 5478f153b04687be2cf5bf6fc04fa832ade994f0 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Mon, 20 May 2024 19:53:24 -0400 Subject: [PATCH 04/24] updated entry points --- src/software/field_tests/field_test_fixture.py | 6 +++++- src/software/simulated_tests/simulated_test_fixture.py | 5 ++++- .../thunderscope/binary_context_managers/game_controller.py | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 7ae36de467..4334fd0b54 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -313,6 +313,8 @@ def load_command_line_arguments(): help="Estop Baudrate", ) + parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') + parser.add_argument( "--run_yellow", action="store_true", @@ -348,6 +350,7 @@ def field_test_runner(): blue_full_system_proto_unix_io = ProtoUnixIO() args = load_command_line_arguments() + # Grab the current test name to store the proto log for the test case current_test = os.environ.get("PYTEST_CURRENT_TEST").split(":")[-1].split(" ")[0] current_test = current_test.replace("]", "") @@ -382,7 +385,8 @@ def field_test_runner(): enable_radio=args.enable_radio, ) as rc_friendly: with Gamecontroller( - supress_logs=(not args.show_gamecontroller_logs) + supress_logs=(not args.show_gamecontroller_logs), + gamecontroller_port=args.gamecontroller_port ) as gamecontroller: friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) rc_friendly.setup_for_fullsystem() diff --git a/src/software/simulated_tests/simulated_test_fixture.py b/src/software/simulated_tests/simulated_test_fixture.py index 104f1a407a..63e73b24fa 100644 --- a/src/software/simulated_tests/simulated_test_fixture.py +++ b/src/software/simulated_tests/simulated_test_fixture.py @@ -493,6 +493,8 @@ def load_command_line_arguments(): default=False, help="Use realism in the simulator", ) + + parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') return parser.parse_args() @@ -542,7 +544,8 @@ def simulated_test_runner(): should_restart_on_crash=False, ) as yellow_fs: with Gamecontroller( - supress_logs=(not args.show_gamecontroller_logs) + supress_logs=(not args.show_gamecontroller_logs), + gamecontroller_port=args.gamecontroller_port ) as gamecontroller: blue_fs.setup_proto_unix_io(blue_full_system_proto_unix_io) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 13140abf11..788cbd5e4a 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -39,7 +39,7 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None self.referee_port = self.next_free_port() self.ci_port = gamecontroller_port - if gamecontroller_port is None: + if self.ci_port is None: self.ci_port = self.next_free_port() if not self.is_valid_port(self.ci_port): From 8d394cd6357772c6e66a316c14dc9c6d02a447c1 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Mon, 20 May 2024 22:08:13 -0400 Subject: [PATCH 05/24] fixed stuff --- .../binary_context_managers/game_controller.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 788cbd5e4a..b58098244e 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -40,10 +40,9 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None self.ci_port = gamecontroller_port if self.ci_port is None: - self.ci_port = self.next_free_port() - - if not self.is_valid_port(self.ci_port): - raise Exception("Port: {} is not available!".format(self.ci_port)) + self.ci_port = self.next_free_port(40000) + else: + self.ci_port = self.next_free_port(self.ci_port) # this allows gamecontroller to listen to override commands self.command_override_buffer = ThreadSafeBuffer( @@ -124,7 +123,7 @@ def is_valid_port(self, port): except OSError: return False - def next_free_port(self, port: int = 40000, max_port: int = 65535) -> None: + def next_free_port(self, start_port: int = 40000, max_port: int = 65535) -> None: """Find the next free port. We need to find 2 free ports to use for the gamecontroller so that we can run multiple gamecontroller instances in parallel. @@ -133,10 +132,10 @@ def next_free_port(self, port: int = 40000, max_port: int = 65535) -> None: :return: The next free port """ - while port <= max_port: - if self.is_valid_port(port): - return port - port += 1 + while start_port <= max_port: + if self.is_valid_port(start_port): + return start_port + start_port += 1 raise IOError("no free ports") From 0b5d2a65b00a359b21abcc3674296f2f6ed25609 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 19:08:28 +0000 Subject: [PATCH 06/24] [pre-commit.ci lite] apply automatic fixes --- src/software/field_tests/field_test_fixture.py | 10 +++++++--- .../simulated_tests/simulated_test_fixture.py | 9 +++++++-- .../binary_context_managers/game_controller.py | 4 ++-- src/software/thunderscope/thunderscope_main.py | 12 ++++++++---- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 4334fd0b54..d43a809254 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -313,7 +313,12 @@ def load_command_line_arguments(): help="Estop Baudrate", ) - parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') + parser.add_argument( + "--gamecontroller_port", + type=int, + default=None, + help="The port number for the game controller.", + ) parser.add_argument( "--run_yellow", @@ -350,7 +355,6 @@ def field_test_runner(): blue_full_system_proto_unix_io = ProtoUnixIO() args = load_command_line_arguments() - # Grab the current test name to store the proto log for the test case current_test = os.environ.get("PYTEST_CURRENT_TEST").split(":")[-1].split(" ")[0] current_test = current_test.replace("]", "") @@ -386,7 +390,7 @@ def field_test_runner(): ) as rc_friendly: with Gamecontroller( supress_logs=(not args.show_gamecontroller_logs), - gamecontroller_port=args.gamecontroller_port + gamecontroller_port=args.gamecontroller_port, ) as gamecontroller: friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) rc_friendly.setup_for_fullsystem() diff --git a/src/software/simulated_tests/simulated_test_fixture.py b/src/software/simulated_tests/simulated_test_fixture.py index 63e73b24fa..65b60e6425 100644 --- a/src/software/simulated_tests/simulated_test_fixture.py +++ b/src/software/simulated_tests/simulated_test_fixture.py @@ -494,7 +494,12 @@ def load_command_line_arguments(): help="Use realism in the simulator", ) - parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') + parser.add_argument( + "--gamecontroller_port", + type=int, + default=None, + help="The port number for the game controller.", + ) return parser.parse_args() @@ -545,7 +550,7 @@ def simulated_test_runner(): ) as yellow_fs: with Gamecontroller( supress_logs=(not args.show_gamecontroller_logs), - gamecontroller_port=args.gamecontroller_port + gamecontroller_port=args.gamecontroller_port, ) as gamecontroller: blue_fs.setup_proto_unix_io(blue_full_system_proto_unix_io) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index b58098244e..bacebe3af0 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -37,9 +37,9 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None # We need to find 2 free ports to use for the gamecontroller # so that we can run multiple gamecontroller instances in parallel self.referee_port = self.next_free_port() - + self.ci_port = gamecontroller_port - if self.ci_port is None: + if self.ci_port is None: self.ci_port = self.next_free_port(40000) else: self.ci_port = self.next_free_port(self.ci_port) diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index df592004d7..7bd29dbf70 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -217,8 +217,13 @@ default=False, help="Whether to populate with default robot positions (False) or start with an empty field (True) for AI vs AI", ) - - parser.add_argument('--gamecontroller_port', type=int, default=None, help='The port number for the game controller.') + + parser.add_argument( + "--gamecontroller_port", + type=int, + default=None, + help="The port number for the game controller.", + ) args = parser.parse_args() @@ -227,7 +232,6 @@ if args.interface is None: parser.error("Must specify interface") - ########################################################################### # Visualize CPP Tests # ########################################################################### @@ -432,7 +436,7 @@ def __ticker(tick_rate_ms: int) -> None: run_sudo=args.sudo, ) as yellow_fs, Gamecontroller( supress_logs=(not args.verbose), - gamecontroller_port=args.gamecontroller_port + gamecontroller_port=args.gamecontroller_port, ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. From 5d5e130c93c9d0d8c116ba696b6cd64ba52c4c23 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 22 May 2024 18:27:53 -0400 Subject: [PATCH 07/24] copied code from nima --- src/software/networking/ssl_proto_communication.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/software/networking/ssl_proto_communication.py b/src/software/networking/ssl_proto_communication.py index 54a571977c..aaccbf4c01 100644 --- a/src/software/networking/ssl_proto_communication.py +++ b/src/software/networking/ssl_proto_communication.py @@ -34,9 +34,15 @@ def __init__(self, port: int) -> None: :param port the port to bind to """ - # bind to all local interfaces, TCP - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.connect(("", port)) + try: + # bind to all local interfaces, TCP + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.connect(("", port)) + except ConnectionRefusedError: + raise ConnectionRefusedError( + f"SSL Socket connection refused on port {port}. Is binary already running in a separate process?" + ) + def send(self, proto: protobuf_message.Message) -> None: """ From 53b31200583510e4a2e227e0a79ad73452419df5 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 22 May 2024 18:29:19 -0400 Subject: [PATCH 08/24] added some new port to fix --- .../thunderscope/binary_context_managers/game_controller.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index bacebe3af0..2f15e973c0 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -107,7 +107,7 @@ def refresh(self): ) manual_command = self.command_override_buffer.get(return_cached=False) - def is_valid_port(self, port): + def is_valid_port(self, port:int) -> bool: """ Check if a port is available @@ -123,11 +123,11 @@ def is_valid_port(self, port): except OSError: return False - def next_free_port(self, start_port: int = 40000, max_port: int = 65535) -> None: + def next_free_port(self, start_port: int = 40000, max_port: int = 65535) -> int: """Find the next free port. We need to find 2 free ports to use for the gamecontroller so that we can run multiple gamecontroller instances in parallel. - :param port: The port to start looking from + :param start_port: The port to start looking from :param max_port: The maximum port to look up to :return: The next free port From c052a973ca08a55ed2b8857fc39b91673264eda6 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Thu, 23 May 2024 17:09:54 -0400 Subject: [PATCH 09/24] change bind address and stuff like that --- .../binary_context_managers/game_controller.py | 12 ++++++++++-- src/software/thunderscope/thunderscope_main.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 2f15e973c0..deb52e816c 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -27,10 +27,12 @@ class Gamecontroller(object): REFEREE_IP = "224.5.23.1" CI_MODE_OUTPUT_RECEIVE_BUFFER_SIZE = 9000 - def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None: + def __init__(self, supress_logs: bool = False, gamecontroller_port:int =None, referee_addresse:int= None) -> None: """Run Gamecontroller :param supress_logs: Whether to suppress the logs + :param gamecontroller_port: the port that the gamecontroller would bind to + :param referee_address: the address the referee binds to """ self.supress_logs = supress_logs @@ -38,6 +40,11 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port=None) -> None # so that we can run multiple gamecontroller instances in parallel self.referee_port = self.next_free_port() + self.REFEREE_IP = referee_addresse + if referee_addresse is None: + self.REFEREE_IP = "224.5.23.1" + print(self.REFEREE_IP) + self.ci_port = gamecontroller_port if self.ci_port is None: self.ci_port = self.next_free_port(40000) @@ -60,6 +67,7 @@ def __enter__(self) -> "self": command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] command += ["-ciAddress", f"localhost:{self.ci_port}"] + print(command) if self.supress_logs: with open(os.devnull, "w") as fp: self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) @@ -166,7 +174,7 @@ def __send_referee_command(data: Referee) -> None: autoref_proto_unix_io.send_proto(Referee, data) self.receive_referee_command = tbots_cpp.SSLRefereeProtoListener( - Gamecontroller.REFEREE_IP, self.referee_port, __send_referee_command, True, + self.REFEREE_IP, self.referee_port, __send_referee_command, True, ) blue_full_system_proto_unix_io.register_observer( diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 7bd29dbf70..fcf097a44a 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -27,6 +27,7 @@ from software.thunderscope.binary_context_managers.full_system import FullSystem from software.thunderscope.binary_context_managers.simulator import Simulator from software.thunderscope.binary_context_managers.game_controller import Gamecontroller + from software.thunderscope.binary_context_managers.tigers_autoref import TigersAutoref @@ -224,8 +225,16 @@ default=None, help="The port number for the game controller.", ) + + parser.add_argument("--sslvision_multicast_address", type=str, default=None, help="the multicast address for ssl vision") + + parser.add_argument("--sslreferee_multicast_address", type=str, default=None, help="the multicast address for referee (game controller likely)") + args = parser.parse_args() + + print(args.sslvision_multicast_address) + print(args.sslreferee_multicast_address) # Sanity check that an interface was provided if args.run_blue or args.run_yellow: @@ -437,6 +446,7 @@ def __ticker(tick_rate_ms: int) -> None: ) as yellow_fs, Gamecontroller( supress_logs=(not args.verbose), gamecontroller_port=args.gamecontroller_port, + referee_addresse=args.sslreferee_multicast_address ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. From ace67d66df7bec1ac72a4e37476956ea7968f2ce Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Thu, 23 May 2024 17:18:34 -0400 Subject: [PATCH 10/24] added new stuff to robot communication --- .../binary_context_managers/game_controller.py | 2 -- src/software/thunderscope/robot_communication.py | 14 ++++++++++++-- src/software/thunderscope/thunderscope_main.py | 3 --- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index deb52e816c..3c9b6db45f 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -43,7 +43,6 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port:int =None, re self.REFEREE_IP = referee_addresse if referee_addresse is None: self.REFEREE_IP = "224.5.23.1" - print(self.REFEREE_IP) self.ci_port = gamecontroller_port if self.ci_port is None: @@ -67,7 +66,6 @@ def __enter__(self) -> "self": command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] command += ["-ciAddress", f"localhost:{self.ci_port}"] - print(command) if self.supress_logs: with open(os.devnull, "w") as fp: self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 8f37b76664..531e656803 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -27,6 +27,8 @@ def __init__( estop_path: os.PathLike = None, estop_baudrate: int = 115200, enable_radio: bool = False, + referee_address: str = None, + sslvision_address: str = None, ): """Initialize the communication with the robots @@ -100,19 +102,27 @@ def __init__( except Exception: raise Exception(f"Invalid Estop found at location {self.estop_path}") + self.ssl_vision_address = sslvision_address + if self.ssl_vision_address is None: + self.ssl_vision_address = SSL_VISION_ADDRESS + + self.referee_address = referee_address + if self.ssl_vision_address is None: + self.ssl_vision_address = SSL_REFEREE_ADDRESS + def setup_for_fullsystem(self) -> None: """ Sets up a listener for SSL vision and referee data, and connects all robots to fullsystem as default """ self.receive_ssl_wrapper = tbots_cpp.SSLWrapperPacketProtoListener( - SSL_VISION_ADDRESS, + self.ssl_vision_address, SSL_VISION_PORT, lambda data: self.__forward_to_proto_unix_io(SSL_WrapperPacket, data), True, ) self.receive_ssl_referee_proto = tbots_cpp.SSLRefereeProtoListener( - SSL_REFEREE_ADDRESS, + self.referee_address, SSL_REFEREE_PORT, lambda data: self.current_proto_unix_io.send_proto(Referee, data), True, diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index fcf097a44a..8096e9528e 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -232,9 +232,6 @@ args = parser.parse_args() - - print(args.sslvision_multicast_address) - print(args.sslreferee_multicast_address) # Sanity check that an interface was provided if args.run_blue or args.run_yellow: From 730753a08e49f865d39cfd0aa03ed21455d25776 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 21:27:35 +0000 Subject: [PATCH 11/24] [pre-commit.ci lite] apply automatic fixes --- .../networking/ssl_proto_communication.py | 1 - .../binary_context_managers/game_controller.py | 11 ++++++++--- .../thunderscope/robot_communication.py | 4 ++-- src/software/thunderscope/thunderscope_main.py | 17 +++++++++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/software/networking/ssl_proto_communication.py b/src/software/networking/ssl_proto_communication.py index aaccbf4c01..a6c4ac686a 100644 --- a/src/software/networking/ssl_proto_communication.py +++ b/src/software/networking/ssl_proto_communication.py @@ -43,7 +43,6 @@ def __init__(self, port: int) -> None: f"SSL Socket connection refused on port {port}. Is binary already running in a separate process?" ) - def send(self, proto: protobuf_message.Message) -> None: """ Send the proto through the socket. diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 3c9b6db45f..4159ea007f 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -27,7 +27,12 @@ class Gamecontroller(object): REFEREE_IP = "224.5.23.1" CI_MODE_OUTPUT_RECEIVE_BUFFER_SIZE = 9000 - def __init__(self, supress_logs: bool = False, gamecontroller_port:int =None, referee_addresse:int= None) -> None: + def __init__( + self, + supress_logs: bool = False, + gamecontroller_port: int = None, + referee_addresse: int = None, + ) -> None: """Run Gamecontroller :param supress_logs: Whether to suppress the logs @@ -41,7 +46,7 @@ def __init__(self, supress_logs: bool = False, gamecontroller_port:int =None, re self.referee_port = self.next_free_port() self.REFEREE_IP = referee_addresse - if referee_addresse is None: + if referee_addresse is None: self.REFEREE_IP = "224.5.23.1" self.ci_port = gamecontroller_port @@ -113,7 +118,7 @@ def refresh(self): ) manual_command = self.command_override_buffer.get(return_cached=False) - def is_valid_port(self, port:int) -> bool: + def is_valid_port(self, port: int) -> bool: """ Check if a port is available diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 531e656803..2fe217f583 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -27,8 +27,8 @@ def __init__( estop_path: os.PathLike = None, estop_baudrate: int = 115200, enable_radio: bool = False, - referee_address: str = None, - sslvision_address: str = None, + referee_address: str = None, + sslvision_address: str = None, ): """Initialize the communication with the robots diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 8096e9528e..550cb0eb21 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -225,11 +225,20 @@ default=None, help="The port number for the game controller.", ) - - parser.add_argument("--sslvision_multicast_address", type=str, default=None, help="the multicast address for ssl vision") - parser.add_argument("--sslreferee_multicast_address", type=str, default=None, help="the multicast address for referee (game controller likely)") + parser.add_argument( + "--sslvision_multicast_address", + type=str, + default=None, + help="the multicast address for ssl vision", + ) + parser.add_argument( + "--sslreferee_multicast_address", + type=str, + default=None, + help="the multicast address for referee (game controller likely)", + ) args = parser.parse_args() @@ -443,7 +452,7 @@ def __ticker(tick_rate_ms: int) -> None: ) as yellow_fs, Gamecontroller( supress_logs=(not args.verbose), gamecontroller_port=args.gamecontroller_port, - referee_addresse=args.sslreferee_multicast_address + referee_addresse=args.sslreferee_multicast_address, ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. From 9b8d59d8b4ff33b95dcb174047ef239a4e6d208d Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Thu, 23 May 2024 17:27:53 -0400 Subject: [PATCH 12/24] added new stuff for robot communication --- src/software/field_tests/field_test_fixture.py | 6 ++++++ src/software/thunderscope/robot_communication.py | 16 +++++++++------- src/software/thunderscope/thunderscope_main.py | 2 ++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index d43a809254..5a3828a45d 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -327,6 +327,10 @@ def load_command_line_arguments(): help="Run the test with friendly robots in yellow mode", ) + parser.add_argument("--sslvision_multicast_address", type=str, default=None, help="the multicast address for ssl vision") + + parser.add_argument("--sslreferee_multicast_address", type=str, default=None, help="the multicast address for referee (game controller likely)") + estop_group = parser.add_mutually_exclusive_group() estop_group.add_argument( "--keyboard_estop", @@ -387,6 +391,8 @@ def field_test_runner(): estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, + referee_address=args.sslreferee_multicast_address, + sslvision_address=args.sslvision_multicast_address ) as rc_friendly: with Gamecontroller( supress_logs=(not args.show_gamecontroller_logs), diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 531e656803..c453fd9098 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -41,6 +41,15 @@ def __init__( :param enable_radio: Whether to use radio to send primitives to robots """ + # setting up the ssl vision and referee addresses + self.ssl_vision_address = sslvision_address + if self.ssl_vision_address is None: + self.ssl_vision_address = SSL_VISION_ADDRESS + + self.referee_address = referee_address + if self.referee_address is None: + self.referee_address = SSL_REFEREE_ADDRESS + self.receive_ssl_referee_proto = None self.receive_ssl_wrapper = None self.sequence_number = 0 @@ -102,13 +111,6 @@ def __init__( except Exception: raise Exception(f"Invalid Estop found at location {self.estop_path}") - self.ssl_vision_address = sslvision_address - if self.ssl_vision_address is None: - self.ssl_vision_address = SSL_VISION_ADDRESS - - self.referee_address = referee_address - if self.ssl_vision_address is None: - self.ssl_vision_address = SSL_REFEREE_ADDRESS def setup_for_fullsystem(self) -> None: """ diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 8096e9528e..6a48670b79 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -330,6 +330,8 @@ estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, + referee_address=args.sslreferee_multicast_address, + sslvision_address=args.sslvision_multicast_address ) as robot_communication: if estop_mode == EstopMode.KEYBOARD_ESTOP: From ebcc8d679dd2359cbeb90a33819a6c77935fe835 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 21:37:43 +0000 Subject: [PATCH 13/24] [pre-commit.ci lite] apply automatic fixes --- src/software/field_tests/field_test_fixture.py | 16 +++++++++++++--- src/software/thunderscope/robot_communication.py | 1 - src/software/thunderscope/thunderscope_main.py | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 5a3828a45d..4f382cf4ba 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -327,9 +327,19 @@ def load_command_line_arguments(): help="Run the test with friendly robots in yellow mode", ) - parser.add_argument("--sslvision_multicast_address", type=str, default=None, help="the multicast address for ssl vision") + parser.add_argument( + "--sslvision_multicast_address", + type=str, + default=None, + help="the multicast address for ssl vision", + ) - parser.add_argument("--sslreferee_multicast_address", type=str, default=None, help="the multicast address for referee (game controller likely)") + parser.add_argument( + "--sslreferee_multicast_address", + type=str, + default=None, + help="the multicast address for referee (game controller likely)", + ) estop_group = parser.add_mutually_exclusive_group() estop_group.add_argument( @@ -392,7 +402,7 @@ def field_test_runner(): estop_path=estop_path, enable_radio=args.enable_radio, referee_address=args.sslreferee_multicast_address, - sslvision_address=args.sslvision_multicast_address + sslvision_address=args.sslvision_multicast_address, ) as rc_friendly: with Gamecontroller( supress_logs=(not args.show_gamecontroller_logs), diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 6ff3594cd5..dd00bdf2bf 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -111,7 +111,6 @@ def __init__( except Exception: raise Exception(f"Invalid Estop found at location {self.estop_path}") - def setup_for_fullsystem(self) -> None: """ Sets up a listener for SSL vision and referee data, and connects all robots to fullsystem as default diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 4366dc11d0..1911d1430a 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -340,7 +340,7 @@ estop_path=estop_path, enable_radio=args.enable_radio, referee_address=args.sslreferee_multicast_address, - sslvision_address=args.sslvision_multicast_address + sslvision_address=args.sslvision_multicast_address, ) as robot_communication: if estop_mode == EstopMode.KEYBOARD_ESTOP: From 6ad2b477b6356119ea398655859df6e09c8954fe Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Fri, 31 May 2024 20:57:34 +0800 Subject: [PATCH 14/24] merged arune's changes --- src/software/field_tests/field_test_fixture.py | 4 ++-- src/software/thunderscope/thunderscope_main.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 4f382cf4ba..b4c5b6e031 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -330,14 +330,14 @@ def load_command_line_arguments(): parser.add_argument( "--sslvision_multicast_address", type=str, - default=None, + default=SSL_VISION_ADDRESS, help="the multicast address for ssl vision", ) parser.add_argument( "--sslreferee_multicast_address", type=str, - default=None, + default=SSL_REFEREE_ADDRESS, help="the multicast address for referee (game controller likely)", ) diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 1911d1430a..d08930cb64 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -229,14 +229,14 @@ parser.add_argument( "--sslvision_multicast_address", type=str, - default=None, + default=SSL_VISION_ADDRESS, help="the multicast address for ssl vision", ) parser.add_argument( "--sslreferee_multicast_address", type=str, - default=None, + default=SSL_REFEREE_ADDRESS, help="the multicast address for referee (game controller likely)", ) From e7308608adb90360b503a9d5ff1e916808039b52 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:19:39 +0800 Subject: [PATCH 15/24] added new feature that arune requested --- .../field_tests/field_test_fixture.py | 166 +++++++++--------- .../simulated_tests/simulated_test_fixture.py | 7 - .../game_controller.py | 99 ++++++----- .../thunderscope/robot_communication.py | 8 +- .../thunderscope/thunderscope_main.py | 44 +++-- 5 files changed, 172 insertions(+), 152 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index b4c5b6e031..d959e0aa92 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -51,7 +51,7 @@ def __init__( :param test_name: The name of the test to run :param blue_full_system_proto_unix_io: The blue full system proto unix io to use :param yellow_full_system_proto_unix_io: The yellow full system proto unix io to use - :param gamecontroller: The gamecontroller context managed instance + :param gamecontroller: The gamecontroller context managed instance :param publish_validation_protos: whether to publish validation protos :param: is_yellow_friendly: if yellow is the friendly team """ @@ -313,13 +313,6 @@ def load_command_line_arguments(): help="Estop Baudrate", ) - parser.add_argument( - "--gamecontroller_port", - type=int, - default=None, - help="The port number for the game controller.", - ) - parser.add_argument( "--run_yellow", action="store_true", @@ -335,10 +328,17 @@ def load_command_line_arguments(): ) parser.add_argument( - "--sslreferee_multicast_address", - type=str, - default=SSL_REFEREE_ADDRESS, - help="the multicast address for referee (game controller likely)", + "--use_unconventional_port", + action="store_true", + default=False, + help="setting this option would cause gamecontroller to bind on an unconventional port, likely 12393", + ) + + parser.add_argument( + "--not_launch_gc", + action="store_true", + default=False, + help="whether we are launching gamecontroller or not", ) estop_group = parser.add_mutually_exclusive_group() @@ -394,87 +394,89 @@ def field_test_runner(): debug_full_system=debug_full_sys, friendly_colour_yellow=args.run_yellow, should_restart_on_crash=False, - ) as friendly_fs, RobotCommunication( + ) as friendly_fs, Gamecontroller( + use_unconventional_port=args.use_unconventional_port, + not_launch_gc=args.not_launch_gc, + supress_logs=(not args.show_gamecontroller_logs), + ) as gamecontroller, RobotCommunication( current_proto_unix_io=friendly_proto_unix_io, multicast_channel=getRobotMulticastChannel(args.channel), interface=args.interface, estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - referee_address=args.sslreferee_multicast_address, sslvision_address=args.sslvision_multicast_address, + referee_port=gamecontroller.get_referee_port(), ) as rc_friendly: - with Gamecontroller( - supress_logs=(not args.show_gamecontroller_logs), - gamecontroller_port=args.gamecontroller_port, - ) as gamecontroller: - friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) - rc_friendly.setup_for_fullsystem() - - gamecontroller.setup_proto_unix_io( - blue_full_system_proto_unix_io, yellow_full_system_proto_unix_io, - ) - # Inject the proto unix ios into thunderscope and start the test - tscope = Thunderscope( - configure_field_test_view( - simulator_proto_unix_io=simulator_proto_unix_io, - blue_full_system_proto_unix_io=blue_full_system_proto_unix_io, - yellow_full_system_proto_unix_io=yellow_full_system_proto_unix_io, - yellow_is_friendly=args.run_yellow, - ), - layout_path=None, - ) - # connect the keyboard estop toggle to the key event if needed - if estop_mode == EstopMode.KEYBOARD_ESTOP: - tscope.keyboard_estop_shortcut.activated.connect( - rc_friendly.toggle_keyboard_estop - ) - # we call this method to enable estop automatically when a field test starts - rc_friendly.toggle_keyboard_estop() - logger.warning( - "\x1b[31;20m" - + "Keyboard Estop Enabled, robots will start moving automatically when test starts!" - + "\x1b[0m" - ) + friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) + rc_friendly.setup_for_fullsystem() - time.sleep(LAUNCH_DELAY_S) - runner = FieldTestRunner( - test_name=current_test, + gamecontroller.setup_proto_unix_io( + blue_full_system_proto_unix_io, + yellow_full_system_proto_unix_io, + ) + # Inject the proto unix ios into thunderscope and start the test + tscope = Thunderscope( + configure_field_test_view( + simulator_proto_unix_io=simulator_proto_unix_io, blue_full_system_proto_unix_io=blue_full_system_proto_unix_io, yellow_full_system_proto_unix_io=yellow_full_system_proto_unix_io, - gamecontroller=gamecontroller, - thunderscope=tscope, - is_yellow_friendly=args.run_yellow, + yellow_is_friendly=args.run_yellow, + ), + layout_path=None, + ) + + # connect the keyboard estop toggle to the key event if needed + if estop_mode == EstopMode.KEYBOARD_ESTOP: + tscope.keyboard_estop_shortcut.activated.connect( + rc_friendly.toggle_keyboard_estop + ) + # we call this method to enable estop automatically when a field test starts + rc_friendly.toggle_keyboard_estop() + logger.warning( + "\x1b[31;20m" + + "Keyboard Estop Enabled, robots will start moving automatically when test starts!" + + "\x1b[0m" ) - friendly_proto_unix_io.register_observer(World, runner.world_buffer) - - # Setup proto loggers. - # - # NOTE: Its important we use the test runners time provider because - # test will run as fast as possible with a varying tick rate. The - # SimulatorTestRunner time provider is tied to the simulators - # t_capture coming out of the wrapper packet (rather than time.time). - with ProtoLogger( - f"{args.blue_full_system_runtime_dir}/logs/{current_test}", - time_provider=runner.time_provider, - ) as blue_logger, ProtoLogger( - f"{args.yellow_full_system_runtime_dir}/logs/{current_test}", - time_provider=runner.time_provider, - ) as yellow_logger: - blue_full_system_proto_unix_io.register_to_observe_everything( - blue_logger.buffer - ) - yellow_full_system_proto_unix_io.register_to_observe_everything( - yellow_logger.buffer - ) - yield runner - print( - f"\n\nTo replay this test for the blue team, go to the `src` folder and run \n./tbots.py run thunderscope --blue_log {blue_logger.log_folder}", - flush=True, - ) - print( - f"\n\nTo replay this test for the yellow team, go to the `src` folder and run \n./tbots.py run thunderscope --yellow_log {yellow_logger.log_folder}", - flush=True, - ) + time.sleep(LAUNCH_DELAY_S) + runner = FieldTestRunner( + test_name=current_test, + blue_full_system_proto_unix_io=blue_full_system_proto_unix_io, + yellow_full_system_proto_unix_io=yellow_full_system_proto_unix_io, + gamecontroller=gamecontroller, + thunderscope=tscope, + is_yellow_friendly=args.run_yellow, + ) + + friendly_proto_unix_io.register_observer(World, runner.world_buffer) + + # Setup proto loggers. + # + # NOTE: Its important we use the test runners time provider because + # test will run as fast as possible with a varying tick rate. The + # SimulatorTestRunner time provider is tied to the simulators + # t_capture coming out of the wrapper packet (rather than time.time). + with ProtoLogger( + f"{args.blue_full_system_runtime_dir}/logs/{current_test}", + time_provider=runner.time_provider, + ) as blue_logger, ProtoLogger( + f"{args.yellow_full_system_runtime_dir}/logs/{current_test}", + time_provider=runner.time_provider, + ) as yellow_logger: + blue_full_system_proto_unix_io.register_to_observe_everything( + blue_logger.buffer + ) + yellow_full_system_proto_unix_io.register_to_observe_everything( + yellow_logger.buffer + ) + yield runner + print( + f"\n\nTo replay this test for the blue team, go to the `src` folder and run \n./tbots.py run thunderscope --blue_log {blue_logger.log_folder}", + flush=True, + ) + print( + f"\n\nTo replay this test for the yellow team, go to the `src` folder and run \n./tbots.py run thunderscope --yellow_log {yellow_logger.log_folder}", + flush=True, + ) diff --git a/src/software/simulated_tests/simulated_test_fixture.py b/src/software/simulated_tests/simulated_test_fixture.py index 65b60e6425..9a31c168dc 100644 --- a/src/software/simulated_tests/simulated_test_fixture.py +++ b/src/software/simulated_tests/simulated_test_fixture.py @@ -494,12 +494,6 @@ def load_command_line_arguments(): help="Use realism in the simulator", ) - parser.add_argument( - "--gamecontroller_port", - type=int, - default=None, - help="The port number for the game controller.", - ) return parser.parse_args() @@ -550,7 +544,6 @@ def simulated_test_runner(): ) as yellow_fs: with Gamecontroller( supress_logs=(not args.show_gamecontroller_logs), - gamecontroller_port=args.gamecontroller_port, ) as gamecontroller: blue_fs.setup_proto_unix_io(blue_full_system_proto_unix_io) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 4159ea007f..ce95461507 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -21,7 +21,7 @@ class Gamecontroller(object): - """ Gamecontroller Context Manager """ + """Gamecontroller Context Manager""" CI_MODE_LAUNCH_DELAY_S = 0.3 REFEREE_IP = "224.5.23.1" @@ -30,58 +30,71 @@ class Gamecontroller(object): def __init__( self, supress_logs: bool = False, - gamecontroller_port: int = None, - referee_addresse: int = None, + use_unconventional_port: bool = False, + not_launch_gc:bool = True ) -> None: - """Run Gamecontroller + """ + Run Gamecontroller :param supress_logs: Whether to suppress the logs - :param gamecontroller_port: the port that the gamecontroller would bind to - :param referee_address: the address the referee binds to + :disregard_gamecontroller_port: if set to True, the gamecontroller port would be set to 12393, else it would highly likely be 40000, i.e. the default port that everybodies uses! + :not_launch_gc Whether to launch the gamecontroller or not! """ - self.supress_logs = supress_logs - - # We need to find 2 free ports to use for the gamecontroller - # so that we can run multiple gamecontroller instances in parallel - self.referee_port = self.next_free_port() - self.REFEREE_IP = referee_addresse - if referee_addresse is None: - self.REFEREE_IP = "224.5.23.1" + self.supress_logs = supress_logs + self.not_launch_gc = not_launch_gc - self.ci_port = gamecontroller_port - if self.ci_port is None: - self.ci_port = self.next_free_port(40000) + if use_unconventional_port: + # the intention of setting this port is to ensure that we don't listen other people's + # gamecontroller. It is highly unlikely that other people would use port 12393 since + # this is a random number that was set by us! + self.referee_port = self.next_free_port(start_port=12393) else: - self.ci_port = self.next_free_port(self.ci_port) + # highly likely being 40000, the default gamecontroller port! + self.referee_port = self.next_free_port() + + self.ci_port = self.next_free_port() # this allows gamecontroller to listen to override commands self.command_override_buffer = ThreadSafeBuffer( buffer_size=2, protobuf_type=ManualGCCommand ) + def get_referee_port(self) -> int: + """ + Sometimes, the port that we are using changes depending on context. + We want a getter function that returns the port we are using. + + :return: the port that the game controller is currently using! + """ + + return self.referee_port + def __enter__(self) -> "self": - """Enter the gamecontroller context manager. + """Enter the gamecontroller context manager. :return: gamecontroller context managed instance """ - command = ["/opt/tbotspython/gamecontroller", "--timeAcquisitionMode", "ci"] + # sometimes we do not want to launch the gameconntroller because we are in robocup + # the referee at robotcup would be the person launching the gamecontroller. + if not self.not_launch_gc: + command = ["/opt/tbotspython/gamecontroller", "--timeAcquisitionMode", "ci"] - command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] - command += ["-ciAddress", f"localhost:{self.ci_port}"] + command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] + command += ["-ciAddress", f"localhost:{self.ci_port}"] - if self.supress_logs: - with open(os.devnull, "w") as fp: - self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) + if self.supress_logs: + with open(os.devnull, "w") as fp: + self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) - else: - self.gamecontroller_proc = Popen(command) + else: + self.gamecontroller_proc = Popen(command) - # We can't connect to the ci port right away, it takes - # CI_MODE_LAUNCH_DELAY_S to start up the gamecontroller - time.sleep(Gamecontroller.CI_MODE_LAUNCH_DELAY_S) - self.ci_socket = SslSocket(self.ci_port) + # We can't connect to the ci port right away, it takes + # CI_MODE_LAUNCH_DELAY_S to start up the gamecontroller + time.sleep(Gamecontroller.CI_MODE_LAUNCH_DELAY_S) + self.ci_socket = SslSocket(self.ci_port) return self @@ -108,19 +121,22 @@ def refresh(self): self.send_gc_command( gc_command=manual_command.manual_command.type, team=manual_command.manual_command.for_team, - final_ball_placement_point=tbots_cpp.Point( - manual_command.final_ball_placement_point.x, - manual_command.final_ball_placement_point.y, - ) - # HasField checks if the field was manually set by us - # as opposed to if a value exists (since a default value always exists) - if manual_command.HasField("final_ball_placement_point") else None, + final_ball_placement_point=( + tbots_cpp.Point( + manual_command.final_ball_placement_point.x, + manual_command.final_ball_placement_point.y, + ) + # HasField checks if the field was manually set by us + # as opposed to if a value exists (since a default value always exists) + if manual_command.HasField("final_ball_placement_point") + else None + ), ) manual_command = self.command_override_buffer.get(return_cached=False) def is_valid_port(self, port: int) -> bool: """ - Check if a port is available + Check if a port is available :param port: the port we are checking :return: True if the port is available, False otherwise @@ -177,7 +193,10 @@ def __send_referee_command(data: Referee) -> None: autoref_proto_unix_io.send_proto(Referee, data) self.receive_referee_command = tbots_cpp.SSLRefereeProtoListener( - self.REFEREE_IP, self.referee_port, __send_referee_command, True, + self.REFEREE_IP, + self.referee_port, + __send_referee_command, + True, ) blue_full_system_proto_unix_io.register_observer( diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index dd00bdf2bf..c14a5db565 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -27,8 +27,8 @@ def __init__( estop_path: os.PathLike = None, estop_baudrate: int = 115200, enable_radio: bool = False, - referee_address: str = None, sslvision_address: str = None, + referee_port:int = SSL_REFEREE_PORT ): """Initialize the communication with the robots @@ -46,9 +46,7 @@ def __init__( if self.ssl_vision_address is None: self.ssl_vision_address = SSL_VISION_ADDRESS - self.referee_address = referee_address - if self.referee_address is None: - self.referee_address = SSL_REFEREE_ADDRESS + self.referee_port = referee_port self.receive_ssl_referee_proto = None self.receive_ssl_wrapper = None @@ -123,7 +121,7 @@ def setup_for_fullsystem(self) -> None: ) self.receive_ssl_referee_proto = tbots_cpp.SSLRefereeProtoListener( - self.referee_address, + SSL_REFEREE_ADDRESS, SSL_REFEREE_PORT, lambda data: self.current_proto_unix_io.send_proto(Referee, data), True, diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index d08930cb64..c0db9eae22 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -219,13 +219,6 @@ help="Whether to populate with default robot positions (False) or start with an empty field (True) for AI vs AI", ) - parser.add_argument( - "--gamecontroller_port", - type=int, - default=None, - help="The port number for the game controller.", - ) - parser.add_argument( "--sslvision_multicast_address", type=str, @@ -234,10 +227,17 @@ ) parser.add_argument( - "--sslreferee_multicast_address", - type=str, - default=SSL_REFEREE_ADDRESS, - help="the multicast address for referee (game controller likely)", + "--use_unconventional_port", + action="store_true", + default=False, + help="setting this option would cause gamecontroller to bind on an unconventional port, likely 12393", + ) + + parser.add_argument( + "--not_launch_gc", + action="store_true", + default=False, + help="whether we are launching gamecontroller or not" ) args = parser.parse_args() @@ -310,7 +310,10 @@ args.run_diagnostics, args.visualization_buffer_size, ) - tscope = Thunderscope(config=tscope_config, layout_path=args.layout,) + tscope = Thunderscope( + config=tscope_config, + layout_path=args.layout, + ) current_proto_unix_io = None @@ -339,7 +342,6 @@ estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - referee_address=args.sslreferee_multicast_address, sslvision_address=args.sslvision_multicast_address, ) as robot_communication: @@ -367,7 +369,9 @@ if args.run_blue else args.yellow_full_system_runtime_dir ) - with ProtoLogger(full_system_runtime_dir,) as logger, FullSystem( + with ProtoLogger( + full_system_runtime_dir, + ) as logger, FullSystem( full_system_runtime_dir=runtime_dir, debug_full_system=debug, friendly_colour_yellow=friendly_colour_yellow, @@ -390,7 +394,9 @@ elif args.blue_log or args.yellow_log: tscope = Thunderscope( config=config.configure_replay_view( - args.blue_log, args.yellow_log, args.visualization_buffer_size, + args.blue_log, + args.yellow_log, + args.visualization_buffer_size, ), layout_path=args.layout, ) @@ -453,8 +459,8 @@ def __ticker(tick_rate_ms: int) -> None: run_sudo=args.sudo, ) as yellow_fs, Gamecontroller( supress_logs=(not args.verbose), - gamecontroller_port=args.gamecontroller_port, - referee_addresse=args.sslreferee_multicast_address, + use_unconventional_port=args.use_unconventional_port, + not_launch_gc=args.not_launch_gc, ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. @@ -503,7 +509,9 @@ def __ticker(tick_rate_ms: int) -> None: autoref_proto_unix_io, ) if args.enable_autoref: - autoref.setup_ssl_wrapper_packets(autoref_proto_unix_io,) + autoref.setup_ssl_wrapper_packets( + autoref_proto_unix_io, + ) # Start the simulator sim_ticker_thread = threading.Thread( From 60dad8133a18e30f5558bdda58066bf03ed60766 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:27:55 +0000 Subject: [PATCH 16/24] [pre-commit.ci lite] apply automatic fixes --- .../field_tests/field_test_fixture.py | 3 +-- .../game_controller.py | 13 +++++-------- .../thunderscope/robot_communication.py | 2 +- .../thunderscope/thunderscope_main.py | 19 +++++-------------- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index d959e0aa92..80faad354b 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -413,8 +413,7 @@ def field_test_runner(): rc_friendly.setup_for_fullsystem() gamecontroller.setup_proto_unix_io( - blue_full_system_proto_unix_io, - yellow_full_system_proto_unix_io, + blue_full_system_proto_unix_io, yellow_full_system_proto_unix_io, ) # Inject the proto unix ios into thunderscope and start the test tscope = Thunderscope( diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index ce95461507..bf9a792e7f 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -31,7 +31,7 @@ def __init__( self, supress_logs: bool = False, use_unconventional_port: bool = False, - not_launch_gc:bool = True + not_launch_gc: bool = True, ) -> None: """ Run Gamecontroller @@ -45,8 +45,8 @@ def __init__( self.not_launch_gc = not_launch_gc if use_unconventional_port: - # the intention of setting this port is to ensure that we don't listen other people's - # gamecontroller. It is highly unlikely that other people would use port 12393 since + # the intention of setting this port is to ensure that we don't listen other people's + # gamecontroller. It is highly unlikely that other people would use port 12393 since # this is a random number that was set by us! self.referee_port = self.next_free_port(start_port=12393) else: @@ -76,7 +76,7 @@ def __enter__(self) -> "self": :return: gamecontroller context managed instance """ - # sometimes we do not want to launch the gameconntroller because we are in robocup + # sometimes we do not want to launch the gameconntroller because we are in robocup # the referee at robotcup would be the person launching the gamecontroller. if not self.not_launch_gc: command = ["/opt/tbotspython/gamecontroller", "--timeAcquisitionMode", "ci"] @@ -193,10 +193,7 @@ def __send_referee_command(data: Referee) -> None: autoref_proto_unix_io.send_proto(Referee, data) self.receive_referee_command = tbots_cpp.SSLRefereeProtoListener( - self.REFEREE_IP, - self.referee_port, - __send_referee_command, - True, + self.REFEREE_IP, self.referee_port, __send_referee_command, True, ) blue_full_system_proto_unix_io.register_observer( diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index c14a5db565..705625b639 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -28,7 +28,7 @@ def __init__( estop_baudrate: int = 115200, enable_radio: bool = False, sslvision_address: str = None, - referee_port:int = SSL_REFEREE_PORT + referee_port: int = SSL_REFEREE_PORT, ): """Initialize the communication with the robots diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index c0db9eae22..a11734ee3c 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -237,7 +237,7 @@ "--not_launch_gc", action="store_true", default=False, - help="whether we are launching gamecontroller or not" + help="whether we are launching gamecontroller or not", ) args = parser.parse_args() @@ -310,10 +310,7 @@ args.run_diagnostics, args.visualization_buffer_size, ) - tscope = Thunderscope( - config=tscope_config, - layout_path=args.layout, - ) + tscope = Thunderscope(config=tscope_config, layout_path=args.layout,) current_proto_unix_io = None @@ -369,9 +366,7 @@ if args.run_blue else args.yellow_full_system_runtime_dir ) - with ProtoLogger( - full_system_runtime_dir, - ) as logger, FullSystem( + with ProtoLogger(full_system_runtime_dir,) as logger, FullSystem( full_system_runtime_dir=runtime_dir, debug_full_system=debug, friendly_colour_yellow=friendly_colour_yellow, @@ -394,9 +389,7 @@ elif args.blue_log or args.yellow_log: tscope = Thunderscope( config=config.configure_replay_view( - args.blue_log, - args.yellow_log, - args.visualization_buffer_size, + args.blue_log, args.yellow_log, args.visualization_buffer_size, ), layout_path=args.layout, ) @@ -509,9 +502,7 @@ def __ticker(tick_rate_ms: int) -> None: autoref_proto_unix_io, ) if args.enable_autoref: - autoref.setup_ssl_wrapper_packets( - autoref_proto_unix_io, - ) + autoref.setup_ssl_wrapper_packets(autoref_proto_unix_io,) # Start the simulator sim_ticker_thread = threading.Thread( From b44cdcf55a4bffc0679b6e59f45b57ae0e1302d7 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:54:32 +0800 Subject: [PATCH 17/24] added requested feature --- .../field_tests/field_test_fixture.py | 16 ++++-- .../game_controller.py | 37 +++++++------- .../thunderscope/robot_communication.py | 11 ++-- .../thunderscope/thunderscope_main.py | 50 +++++++++++-------- 4 files changed, 62 insertions(+), 52 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 80faad354b..62cecdb9b4 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -358,6 +358,14 @@ def load_command_line_arguments(): return parser.parse_args() +def get_referee_port(gamecontroller: Gamecontroller): + if gamecontroller is not None: + print("Using a weird gamecontroller port") + return gamecontroller.get_referee_port() + print("Using default port") + return 40000 + + @pytest.fixture def field_test_runner(): """ @@ -395,9 +403,9 @@ def field_test_runner(): friendly_colour_yellow=args.run_yellow, should_restart_on_crash=False, ) as friendly_fs, Gamecontroller( - use_unconventional_port=args.use_unconventional_port, - not_launch_gc=args.not_launch_gc, + # we would be using conventional port if and only if we are playing in robocup. supress_logs=(not args.show_gamecontroller_logs), + use_conventional_port=False ) as gamecontroller, RobotCommunication( current_proto_unix_io=friendly_proto_unix_io, multicast_channel=getRobotMulticastChannel(args.channel), @@ -408,12 +416,12 @@ def field_test_runner(): sslvision_address=args.sslvision_multicast_address, referee_port=gamecontroller.get_referee_port(), ) as rc_friendly: - friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) rc_friendly.setup_for_fullsystem() gamecontroller.setup_proto_unix_io( - blue_full_system_proto_unix_io, yellow_full_system_proto_unix_io, + blue_full_system_proto_unix_io, + yellow_full_system_proto_unix_io, ) # Inject the proto unix ios into thunderscope and start the test tscope = Thunderscope( diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index bf9a792e7f..1e74452492 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -1,5 +1,6 @@ from __future__ import annotations +import random import logging import os import socket @@ -27,14 +28,8 @@ class Gamecontroller(object): REFEREE_IP = "224.5.23.1" CI_MODE_OUTPUT_RECEIVE_BUFFER_SIZE = 9000 - def __init__( - self, - supress_logs: bool = False, - use_unconventional_port: bool = False, - not_launch_gc: bool = True, - ) -> None: - """ - Run Gamecontroller + def __init__(self, supress_logs: bool = False, use_conventional_port=False) -> None: + """Run Gamecontroller :param supress_logs: Whether to suppress the logs :disregard_gamecontroller_port: if set to True, the gamecontroller port would be set to 12393, else it would highly likely be 40000, i.e. the default port that everybodies uses! @@ -42,7 +37,6 @@ def __init__( """ self.supress_logs = supress_logs - self.not_launch_gc = not_launch_gc if use_unconventional_port: # the intention of setting this port is to ensure that we don't listen other people's @@ -54,7 +48,17 @@ def __init__( self.referee_port = self.next_free_port() self.ci_port = self.next_free_port() + # we are not using conventional by default since most of the time + # we are not in competition and. Thus, we would be conflicting with + # each other if we are using conventional port + self.referee_port = self.next_free_port(random.randint(1024, 65535)) + if use_conventional_port: + if not self.is_valid_port(40000): + raise OSError("Cannot use port 40000 for Gamecontroller") + self.referee_port = 40000 + + self.ci_port = self.next_free_port() # this allows gamecontroller to listen to override commands self.command_override_buffer = ThreadSafeBuffer( buffer_size=2, protobuf_type=ManualGCCommand @@ -84,12 +88,9 @@ def __enter__(self) -> "self": command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] command += ["-ciAddress", f"localhost:{self.ci_port}"] - if self.supress_logs: - with open(os.devnull, "w") as fp: - self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) - - else: - self.gamecontroller_proc = Popen(command) + if self.supress_logs: + with open(os.devnull, "w") as fp: + self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) # We can't connect to the ci port right away, it takes # CI_MODE_LAUNCH_DELAY_S to start up the gamecontroller @@ -134,12 +135,12 @@ def refresh(self): ) manual_command = self.command_override_buffer.get(return_cached=False) - def is_valid_port(self, port: int) -> bool: + def is_valid_port(self, port): """ - Check if a port is available + determine whether or not a given port is valid :param port: the port we are checking - :return: True if the port is available, False otherwise + :return: True if a port is valid False otherwise """ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 705625b639..9ed8466dce 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -27,8 +27,7 @@ def __init__( estop_path: os.PathLike = None, estop_baudrate: int = 115200, enable_radio: bool = False, - sslvision_address: str = None, - referee_port: int = SSL_REFEREE_PORT, + referee_port: int = SSL_REFEREE_PORT ): """Initialize the communication with the robots @@ -39,15 +38,11 @@ def __init__( :param estop_path: The path to the estop :param estop_baudrate: The baudrate of the estop :param enable_radio: Whether to use radio to send primitives to robots + :param referee_port: the referee port that we are using """ - # setting up the ssl vision and referee addresses - self.ssl_vision_address = sslvision_address - if self.ssl_vision_address is None: - self.ssl_vision_address = SSL_VISION_ADDRESS self.referee_port = referee_port - self.receive_ssl_referee_proto = None self.receive_ssl_wrapper = None self.sequence_number = 0 @@ -122,7 +117,7 @@ def setup_for_fullsystem(self) -> None: self.receive_ssl_referee_proto = tbots_cpp.SSLRefereeProtoListener( SSL_REFEREE_ADDRESS, - SSL_REFEREE_PORT, + self.referee_port, lambda data: self.current_proto_unix_io.send_proto(Referee, data), True, ) diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index a11734ee3c..6fdcf43c59 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -220,24 +220,10 @@ ) parser.add_argument( - "--sslvision_multicast_address", - type=str, - default=SSL_VISION_ADDRESS, - help="the multicast address for ssl vision", - ) - - parser.add_argument( - "--use_unconventional_port", + "--launch_gc", action="store_true", default=False, - help="setting this option would cause gamecontroller to bind on an unconventional port, likely 12393", - ) - - parser.add_argument( - "--not_launch_gc", - action="store_true", - default=False, - help="whether we are launching gamecontroller or not", + help="wheter or not to launch the gamecontroller when --run_blue or --run_yellow is ran", ) args = parser.parse_args() @@ -310,7 +296,10 @@ args.run_diagnostics, args.visualization_buffer_size, ) - tscope = Thunderscope(config=tscope_config, layout_path=args.layout,) + tscope = Thunderscope( + config=tscope_config, + layout_path=args.layout, + ) current_proto_unix_io = None @@ -332,14 +321,25 @@ args.keyboard_estop, args.disable_communication ) - with RobotCommunication( + def get_referee_port(gamecontroller: Gamecontroller): + if gamecontroller is not None: + print("Using a weird gamecontroller port") + return gamecontroller.get_referee_port() + print("Using default port") + return 40000 + + with ( + Gamecontroller(supress_logs=(not args.verbose), use_conventional_port=False) + if args.launch_gc + else contextlib.nullcontext() + ) as gamecontroller, RobotCommunication( current_proto_unix_io=current_proto_unix_io, multicast_channel=getRobotMulticastChannel(args.channel), interface=args.interface, estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - sslvision_address=args.sslvision_multicast_address, + referee_port=get_referee_port(gamecontroller), ) as robot_communication: if estop_mode == EstopMode.KEYBOARD_ESTOP: @@ -366,7 +366,9 @@ if args.run_blue else args.yellow_full_system_runtime_dir ) - with ProtoLogger(full_system_runtime_dir,) as logger, FullSystem( + with ProtoLogger( + full_system_runtime_dir, + ) as logger, FullSystem( full_system_runtime_dir=runtime_dir, debug_full_system=debug, friendly_colour_yellow=friendly_colour_yellow, @@ -389,7 +391,9 @@ elif args.blue_log or args.yellow_log: tscope = Thunderscope( config=config.configure_replay_view( - args.blue_log, args.yellow_log, args.visualization_buffer_size, + args.blue_log, + args.yellow_log, + args.visualization_buffer_size, ), layout_path=args.layout, ) @@ -502,7 +506,9 @@ def __ticker(tick_rate_ms: int) -> None: autoref_proto_unix_io, ) if args.enable_autoref: - autoref.setup_ssl_wrapper_packets(autoref_proto_unix_io,) + autoref.setup_ssl_wrapper_packets( + autoref_proto_unix_io, + ) # Start the simulator sim_ticker_thread = threading.Thread( From 0c984eb6d1c5566c0159a4a7516d9af4b86d0bbc Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:26:55 +0800 Subject: [PATCH 18/24] added comments and remove necessary print statements --- src/software/field_tests/field_test_fixture.py | 8 ++++++-- src/software/thunderscope/thunderscope_main.py | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 62cecdb9b4..238193e468 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -359,10 +359,14 @@ def load_command_line_arguments(): def get_referee_port(gamecontroller: Gamecontroller): + """ + return the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + + :param gamecontroller: the gamecontroller we are using + :return: the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + """ if gamecontroller is not None: - print("Using a weird gamecontroller port") return gamecontroller.get_referee_port() - print("Using default port") return 40000 diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 6fdcf43c59..b1ef596279 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -322,10 +322,14 @@ ) def get_referee_port(gamecontroller: Gamecontroller): + """ + return the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + + :param gamecontroller: the gamecontroller we are using + :return: the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + """ if gamecontroller is not None: - print("Using a weird gamecontroller port") return gamecontroller.get_referee_port() - print("Using default port") return 40000 with ( From 749fb3f432ef05048161c44695cfff004cfa60b7 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:57:46 +0800 Subject: [PATCH 19/24] remove code that are non necessary --- .../field_tests/field_test_fixture.py | 21 -------- .../simulated_tests/simulated_test_fixture.py | 3 +- .../game_controller.py | 51 +++++++------------ .../thunderscope/robot_communication.py | 2 +- .../thunderscope/thunderscope_main.py | 4 +- 5 files changed, 22 insertions(+), 59 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 238193e468..6d448d73b9 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -320,27 +320,6 @@ def load_command_line_arguments(): help="Run the test with friendly robots in yellow mode", ) - parser.add_argument( - "--sslvision_multicast_address", - type=str, - default=SSL_VISION_ADDRESS, - help="the multicast address for ssl vision", - ) - - parser.add_argument( - "--use_unconventional_port", - action="store_true", - default=False, - help="setting this option would cause gamecontroller to bind on an unconventional port, likely 12393", - ) - - parser.add_argument( - "--not_launch_gc", - action="store_true", - default=False, - help="whether we are launching gamecontroller or not", - ) - estop_group = parser.add_mutually_exclusive_group() estop_group.add_argument( "--keyboard_estop", diff --git a/src/software/simulated_tests/simulated_test_fixture.py b/src/software/simulated_tests/simulated_test_fixture.py index 9a31c168dc..104f1a407a 100644 --- a/src/software/simulated_tests/simulated_test_fixture.py +++ b/src/software/simulated_tests/simulated_test_fixture.py @@ -493,7 +493,6 @@ def load_command_line_arguments(): default=False, help="Use realism in the simulator", ) - return parser.parse_args() @@ -543,7 +542,7 @@ def simulated_test_runner(): should_restart_on_crash=False, ) as yellow_fs: with Gamecontroller( - supress_logs=(not args.show_gamecontroller_logs), + supress_logs=(not args.show_gamecontroller_logs) ) as gamecontroller: blue_fs.setup_proto_unix_io(blue_full_system_proto_unix_io) diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index 1e74452492..af421fbad6 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -32,21 +32,11 @@ def __init__(self, supress_logs: bool = False, use_conventional_port=False) -> N """Run Gamecontroller :param supress_logs: Whether to suppress the logs - :disregard_gamecontroller_port: if set to True, the gamecontroller port would be set to 12393, else it would highly likely be 40000, i.e. the default port that everybodies uses! :not_launch_gc Whether to launch the gamecontroller or not! """ self.supress_logs = supress_logs - if use_unconventional_port: - # the intention of setting this port is to ensure that we don't listen other people's - # gamecontroller. It is highly unlikely that other people would use port 12393 since - # this is a random number that was set by us! - self.referee_port = self.next_free_port(start_port=12393) - else: - # highly likely being 40000, the default gamecontroller port! - self.referee_port = self.next_free_port() - self.ci_port = self.next_free_port() # we are not using conventional by default since most of the time # we are not in competition and. Thus, we would be conflicting with @@ -75,27 +65,27 @@ def get_referee_port(self) -> int: return self.referee_port def __enter__(self) -> "self": - """Enter the gamecontroller context manager. + """Enter the gamecontroller context manager. :return: gamecontroller context managed instance """ - # sometimes we do not want to launch the gameconntroller because we are in robocup - # the referee at robotcup would be the person launching the gamecontroller. - if not self.not_launch_gc: - command = ["/opt/tbotspython/gamecontroller", "--timeAcquisitionMode", "ci"] + command = ["/opt/tbotspython/gamecontroller", "--timeAcquisitionMode", "ci"] - command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] - command += ["-ciAddress", f"localhost:{self.ci_port}"] + command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"] + command += ["-ciAddress", f"localhost:{self.ci_port}"] if self.supress_logs: with open(os.devnull, "w") as fp: self.gamecontroller_proc = Popen(command, stdout=fp, stderr=fp) - # We can't connect to the ci port right away, it takes - # CI_MODE_LAUNCH_DELAY_S to start up the gamecontroller - time.sleep(Gamecontroller.CI_MODE_LAUNCH_DELAY_S) - self.ci_socket = SslSocket(self.ci_port) + else: + self.gamecontroller_proc = Popen(command) + + # We can't connect to the ci port right away, it takes + # CI_MODE_LAUNCH_DELAY_S to start up the gamecontroller + time.sleep(Gamecontroller.CI_MODE_LAUNCH_DELAY_S) + self.ci_socket = SslSocket(self.ci_port) return self @@ -122,16 +112,13 @@ def refresh(self): self.send_gc_command( gc_command=manual_command.manual_command.type, team=manual_command.manual_command.for_team, - final_ball_placement_point=( - tbots_cpp.Point( - manual_command.final_ball_placement_point.x, - manual_command.final_ball_placement_point.y, - ) - # HasField checks if the field was manually set by us - # as opposed to if a value exists (since a default value always exists) - if manual_command.HasField("final_ball_placement_point") - else None - ), + final_ball_placement_point=tbots_cpp.Point( + manual_command.final_ball_placement_point.x, + manual_command.final_ball_placement_point.y, + ) + # HasField checks if the field was manually set by us + # as opposed to if a value exists (since a default value always exists) + if manual_command.HasField("final_ball_placement_point") else None, ) manual_command = self.command_override_buffer.get(return_cached=False) @@ -194,7 +181,7 @@ def __send_referee_command(data: Referee) -> None: autoref_proto_unix_io.send_proto(Referee, data) self.receive_referee_command = tbots_cpp.SSLRefereeProtoListener( - self.REFEREE_IP, self.referee_port, __send_referee_command, True, + Gamecontroller.REFEREE_IP, self.referee_port, __send_referee_command, True, ) blue_full_system_proto_unix_io.register_observer( diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 9ed8466dce..4994b5e978 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -109,7 +109,7 @@ def setup_for_fullsystem(self) -> None: Sets up a listener for SSL vision and referee data, and connects all robots to fullsystem as default """ self.receive_ssl_wrapper = tbots_cpp.SSLWrapperPacketProtoListener( - self.ssl_vision_address, + SSL_VISION_ADDRESS, SSL_VISION_PORT, lambda data: self.__forward_to_proto_unix_io(SSL_WrapperPacket, data), True, diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index b1ef596279..ef58dc2a73 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -459,9 +459,7 @@ def __ticker(tick_rate_ms: int) -> None: should_restart_on_crash=False, run_sudo=args.sudo, ) as yellow_fs, Gamecontroller( - supress_logs=(not args.verbose), - use_unconventional_port=args.use_unconventional_port, - not_launch_gc=args.not_launch_gc, + supress_logs=(not args.verbose) ) as gamecontroller, ( # Here we only initialize autoref if the --enable_autoref flag is requested. # To avoid nested Python withs, the autoref is initialized as None when this flag doesn't exist. From f3a42e720212aafb1a900ed52d968ac87e0e0964 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:07:02 +0800 Subject: [PATCH 20/24] removed one line of legacy code --- src/software/field_tests/field_test_fixture.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 6d448d73b9..a041b04dbd 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -396,7 +396,6 @@ def field_test_runner(): estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - sslvision_address=args.sslvision_multicast_address, referee_port=gamecontroller.get_referee_port(), ) as rc_friendly: friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) From bed3109d88bc294ab6b3f93523f80a1d571c48e3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:07:27 +0000 Subject: [PATCH 21/24] [pre-commit.ci lite] apply automatic fixes --- src/software/field_tests/field_test_fixture.py | 5 ++--- .../binary_context_managers/game_controller.py | 6 +++--- .../thunderscope/robot_communication.py | 2 +- src/software/thunderscope/thunderscope_main.py | 17 ++++------------- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 6d448d73b9..2eb47abf0d 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -388,7 +388,7 @@ def field_test_runner(): ) as friendly_fs, Gamecontroller( # we would be using conventional port if and only if we are playing in robocup. supress_logs=(not args.show_gamecontroller_logs), - use_conventional_port=False + use_conventional_port=False, ) as gamecontroller, RobotCommunication( current_proto_unix_io=friendly_proto_unix_io, multicast_channel=getRobotMulticastChannel(args.channel), @@ -403,8 +403,7 @@ def field_test_runner(): rc_friendly.setup_for_fullsystem() gamecontroller.setup_proto_unix_io( - blue_full_system_proto_unix_io, - yellow_full_system_proto_unix_io, + blue_full_system_proto_unix_io, yellow_full_system_proto_unix_io, ) # Inject the proto unix ios into thunderscope and start the test tscope = Thunderscope( diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index af421fbad6..b156c3405b 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -38,11 +38,11 @@ def __init__(self, supress_logs: bool = False, use_conventional_port=False) -> N self.supress_logs = supress_logs self.ci_port = self.next_free_port() - # we are not using conventional by default since most of the time - # we are not in competition and. Thus, we would be conflicting with + # we are not using conventional by default since most of the time + # we are not in competition and. Thus, we would be conflicting with # each other if we are using conventional port self.referee_port = self.next_free_port(random.randint(1024, 65535)) - if use_conventional_port: + if use_conventional_port: if not self.is_valid_port(40000): raise OSError("Cannot use port 40000 for Gamecontroller") diff --git a/src/software/thunderscope/robot_communication.py b/src/software/thunderscope/robot_communication.py index 4994b5e978..b9cbb06279 100644 --- a/src/software/thunderscope/robot_communication.py +++ b/src/software/thunderscope/robot_communication.py @@ -27,7 +27,7 @@ def __init__( estop_path: os.PathLike = None, estop_baudrate: int = 115200, enable_radio: bool = False, - referee_port: int = SSL_REFEREE_PORT + referee_port: int = SSL_REFEREE_PORT, ): """Initialize the communication with the robots diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index ef58dc2a73..634c87df79 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -296,10 +296,7 @@ args.run_diagnostics, args.visualization_buffer_size, ) - tscope = Thunderscope( - config=tscope_config, - layout_path=args.layout, - ) + tscope = Thunderscope(config=tscope_config, layout_path=args.layout,) current_proto_unix_io = None @@ -370,9 +367,7 @@ def get_referee_port(gamecontroller: Gamecontroller): if args.run_blue else args.yellow_full_system_runtime_dir ) - with ProtoLogger( - full_system_runtime_dir, - ) as logger, FullSystem( + with ProtoLogger(full_system_runtime_dir,) as logger, FullSystem( full_system_runtime_dir=runtime_dir, debug_full_system=debug, friendly_colour_yellow=friendly_colour_yellow, @@ -395,9 +390,7 @@ def get_referee_port(gamecontroller: Gamecontroller): elif args.blue_log or args.yellow_log: tscope = Thunderscope( config=config.configure_replay_view( - args.blue_log, - args.yellow_log, - args.visualization_buffer_size, + args.blue_log, args.yellow_log, args.visualization_buffer_size, ), layout_path=args.layout, ) @@ -508,9 +501,7 @@ def __ticker(tick_rate_ms: int) -> None: autoref_proto_unix_io, ) if args.enable_autoref: - autoref.setup_ssl_wrapper_packets( - autoref_proto_unix_io, - ) + autoref.setup_ssl_wrapper_packets(autoref_proto_unix_io,) # Start the simulator sim_ticker_thread = threading.Thread( From 1e8fcbab3cd0f20e1dd3e80461bb4bcf4d5f3b35 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:20:20 +0000 Subject: [PATCH 22/24] [pre-commit.ci lite] apply automatic fixes --- src/software/thunderscope/thunderscope_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 634c87df79..edfd0143af 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -223,7 +223,7 @@ "--launch_gc", action="store_true", default=False, - help="wheter or not to launch the gamecontroller when --run_blue or --run_yellow is ran", + help="whether or not to launch the gamecontroller when --run_blue or --run_yellow is ran", ) args = parser.parse_args() From 3218a323c9b9c6fb910ae84a309b0004f2e54e07 Mon Sep 17 00:00:00 2001 From: Mr-Anyone <53135664+Mr-Anyone@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:37:13 +0800 Subject: [PATCH 23/24] refactored function --- src/software/field_tests/field_test_fixture.py | 15 +-------------- .../binary_context_managers/game_controller.py | 13 +++++++++++++ src/software/thunderscope/thunderscope_main.py | 12 +----------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 787d458e29..5949712a29 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -336,19 +336,6 @@ def load_command_line_arguments(): return parser.parse_args() - -def get_referee_port(gamecontroller: Gamecontroller): - """ - return the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. - - :param gamecontroller: the gamecontroller we are using - :return: the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. - """ - if gamecontroller is not None: - return gamecontroller.get_referee_port() - return 40000 - - @pytest.fixture def field_test_runner(): """ @@ -396,7 +383,7 @@ def field_test_runner(): estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - referee_port=gamecontroller.get_referee_port(), + referee_port=Gamecontroller.get_referee_port_staticmethod(gamecontroller), ) as rc_friendly: friendly_fs.setup_proto_unix_io(friendly_proto_unix_io) rc_friendly.setup_for_fullsystem() diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index b156c3405b..d85e66298a 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -54,6 +54,19 @@ def __init__(self, supress_logs: bool = False, use_conventional_port=False) -> N buffer_size=2, protobuf_type=ManualGCCommand ) + @staticmethod + def get_referee_port_staticmethod(gamecontroller: Gamecontroller): + """ + return the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + + :param gamecontroller: the gamecontroller we are using + :return: the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. + """ + if gamecontroller is not None: + return gamecontroller.get_referee_port() + + return 40000 + def get_referee_port(self) -> int: """ Sometimes, the port that we are using changes depending on context. diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 634c87df79..a1f8ca4c8d 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -318,16 +318,6 @@ args.keyboard_estop, args.disable_communication ) - def get_referee_port(gamecontroller: Gamecontroller): - """ - return the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. - - :param gamecontroller: the gamecontroller we are using - :return: the default port if gamecontroller is None, otherwise the port that the gamecontroller is using. - """ - if gamecontroller is not None: - return gamecontroller.get_referee_port() - return 40000 with ( Gamecontroller(supress_logs=(not args.verbose), use_conventional_port=False) @@ -340,7 +330,7 @@ def get_referee_port(gamecontroller: Gamecontroller): estop_mode=estop_mode, estop_path=estop_path, enable_radio=args.enable_radio, - referee_port=get_referee_port(gamecontroller), + referee_port=Gamecontroller.get_referee_port_staticmethod(gamecontroller), ) as robot_communication: if estop_mode == EstopMode.KEYBOARD_ESTOP: From cf668bfeaff698097aadce1d01c60b4c731322c6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 03:46:15 +0000 Subject: [PATCH 24/24] [pre-commit.ci lite] apply automatic fixes --- src/software/field_tests/field_test_fixture.py | 1 + src/software/thunderscope/thunderscope_main.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/software/field_tests/field_test_fixture.py b/src/software/field_tests/field_test_fixture.py index 5949712a29..77e0f87c22 100644 --- a/src/software/field_tests/field_test_fixture.py +++ b/src/software/field_tests/field_test_fixture.py @@ -336,6 +336,7 @@ def load_command_line_arguments(): return parser.parse_args() + @pytest.fixture def field_test_runner(): """ diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 50cd79ec56..ee940d5d3f 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -318,7 +318,6 @@ args.keyboard_estop, args.disable_communication ) - with ( Gamecontroller(supress_logs=(not args.verbose), use_conventional_port=False) if args.launch_gc