-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gamecontroller can Bind to a Different Port Based on Command Line Argument #3207
base: master
Are you sure you want to change the base?
Changes from 15 commits
bacfacf
d620120
1557448
5478f15
8d394cd
0b5d2a6
5d5e130
53b3120
c052a97
ace67d6
730753a
9b8d59d
9453411
ebcc8d6
6ad2b47
e730860
60dad81
b44cdcf
0c984eb
749fb3f
f3a42e7
bed3109
51f42e2
1e8fcba
3218a32
b147096
cf668bf
036da38
4f1fbe5
9a3ef5f
82e6f87
c51c412
e616430
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -27,17 +27,33 @@ 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: int = None, | ||||||||||||
referee_addresse: int = None, | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bump: looks like it didn't get committed |
||||||||||||
) -> 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 | ||||||||||||
|
||||||||||||
# 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.REFEREE_IP = referee_addresse | ||||||||||||
if referee_addresse is None: | ||||||||||||
self.REFEREE_IP = "224.5.23.1" | ||||||||||||
|
||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Doesn't this contradicts what nima said? Am I misunderstanding something? Are we setting the port instead then but keeping the multicast address constant? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nima's right but in the implementation, don't modify Instead, use a new local variable:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, you're correct |
||||||||||||
self.ci_port = gamecontroller_port | ||||||||||||
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) | ||||||||||||
|
||||||||||||
# this allows gamecontroller to listen to override commands | ||||||||||||
self.command_override_buffer = ThreadSafeBuffer( | ||||||||||||
|
@@ -102,24 +118,35 @@ def refresh(self): | |||||||||||
) | ||||||||||||
manual_command = self.command_override_buffer.get(return_cached=False) | ||||||||||||
|
||||||||||||
def next_free_port(self, port: int = 40000, max_port: int = 65535) -> None: | ||||||||||||
def is_valid_port(self, port: int) -> bool: | ||||||||||||
""" | ||||||||||||
Check if a port is available | ||||||||||||
|
||||||||||||
: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, 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 | ||||||||||||
|
||||||||||||
""" | ||||||||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||||||||||
|
||||||||||||
while port <= max_port: | ||||||||||||
try: | ||||||||||||
sock.bind(("", port)) | ||||||||||||
sock.close() | ||||||||||||
return port | ||||||||||||
except OSError: | ||||||||||||
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") | ||||||||||||
|
||||||||||||
|
@@ -150,7 +177,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, | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can keep the old code |
||||||||||||
) | ||||||||||||
|
||||||||||||
blue_full_system_proto_unix_io.register_observer( | ||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need this param |
||
): | ||
"""Initialize the communication with the robots | ||
|
||
|
@@ -39,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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need this code |
||
|
||
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 | ||
|
@@ -105,14 +116,14 @@ 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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep the old code |
||
SSL_VISION_PORT, | ||
lambda data: self.__forward_to_proto_unix_io(SSL_WrapperPacket, data), | ||
True, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line 125 should be self.referee_port if it isn't |
||
) | ||
|
||
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, | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -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 | ||||||
|
||||||
|
||||||
|
@@ -218,6 +219,27 @@ | |||||
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, | ||||||
default=SSL_VISION_ADDRESS, | ||||||
help="the multicast address for ssl vision", | ||||||
) | ||||||
|
||||||
parser.add_argument( | ||||||
"--sslreferee_multicast_address", | ||||||
type=str, | ||||||
default=SSL_REFEREE_ADDRESS, | ||||||
help="the multicast address for referee (game controller likely)", | ||||||
) | ||||||
|
||||||
args = parser.parse_args() | ||||||
|
||||||
# Sanity check that an interface was provided | ||||||
|
@@ -317,6 +339,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, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if |
||||||
) as robot_communication: | ||||||
nimazareian marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
if estop_mode == EstopMode.KEYBOARD_ESTOP: | ||||||
|
@@ -428,7 +452,9 @@ 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, | ||||||
referee_addresse=args.sslreferee_multicast_address, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
) 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. | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need this arg, we can default to SSL_VISION_ADDRESS and just change the port