Skip to content

Commit a07dd97

Browse files
williamckhanycrat
andauthored
Fix default gamecontroller interface for macos (#3840)
* Fix default gamecontroller interface for macos * Only apply dynamic ports for gamecontroller when parallel * Run ci for robocup branches (#3820) * Revert "Run ci for robocup branches (#3820)" This reverts commit 4d0dcc7. * nit --------- Co-authored-by: Eric Xiao <ericxiao0000@gmail.com>
1 parent b61b73c commit a07dd97

3 files changed

Lines changed: 40 additions & 19 deletions

File tree

src/software/gameplay_tests/simulated_test_fixture.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,8 @@ def simulated_test_runner():
591591
running_in_realtime=args.enable_thunderscope and not args.ci_mode,
592592
) as yellow_fs:
593593
with Gamecontroller(
594-
suppress_logs=(not args.show_gamecontroller_logs)
594+
suppress_logs=(not args.show_gamecontroller_logs),
595+
parallelized=True,
595596
) as gamecontroller:
596597
blue_fs.setup_proto_unix_io(blue_full_system_proto_unix_io)
597598
yellow_fs.setup_proto_unix_io(yellow_full_system_proto_unix_io)

src/software/thunderscope/binary_context_managers/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ py_library(
2424
"//software/networking:ssl_proto_communication",
2525
"//software/thunderscope:util",
2626
"//software/thunderscope/common:thread_safe_circular_buffer",
27+
requirement("netifaces"),
2728
],
2829
)
2930

src/software/thunderscope/binary_context_managers/game_controller.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import logging
88
import os
99
import time
10+
import netifaces
11+
1012
from subprocess import Popen
1113
from typing import Any
1214

@@ -44,15 +46,18 @@ def __init__(
4446
suppress_logs: bool = False,
4547
use_conventional_port: bool = False,
4648
automate_referee: bool = False,
49+
parallelized: bool = False,
4750
) -> None:
4851
"""Run Gamecontroller
4952
5053
:param suppress_logs: True if logs should be suppressed
5154
:param use_conventional_port: True when using static referee port. False for dynamic port assignments.
52-
:param automate_referee: True if referee commands should be automated
55+
:param automate_referee: True if referee commands should be automated.
56+
:param parallelized: True when this is one of many Gamecontrollers running at once.
5357
"""
5458
self.suppress_logs = suppress_logs
5559
self.automate_referee = automate_referee
60+
self.parallelized = parallelized
5661

5762
self.use_conventional_port = use_conventional_port
5863
self.referee_port = None
@@ -109,17 +114,20 @@ def __enter__(self) -> Gamecontroller:
109114

110115
command += ["-publishAddress", f"{self.REFEREE_IP}:{self.referee_port}"]
111116
command += ["-ciAddress", f"localhost:{self.ci_port}"]
112-
command += [
113-
"-address",
114-
"localhost:0",
115-
"-autorefAddress",
116-
"localhost:0",
117-
"-remoteControlAddress",
118-
"localhost:0",
119-
"-teamAddress",
120-
"localhost:0",
121-
"-backendOnly",
122-
]
117+
if self.parallelized:
118+
# One of many GCs running at once: no web UI and all-dynamic ports so
119+
# instances don't collide on the fixed UI / autoref ports.
120+
command += [
121+
"-address",
122+
"localhost:0",
123+
"-autorefAddress",
124+
"localhost:0",
125+
"-remoteControlAddress",
126+
"localhost:0",
127+
"-teamAddress",
128+
"localhost:0",
129+
"-backendOnly",
130+
]
123131

124132
if self.suppress_logs:
125133
with open(os.devnull, "w") as fp:
@@ -245,15 +253,10 @@ def __send_referee_command(data: Referee) -> None:
245253
if autoref_proto_unix_io is not None:
246254
autoref_proto_unix_io.send_proto(Referee, data)
247255

248-
if is_current_platform_macos():
249-
loopback_iface = "en0"
250-
else:
251-
loopback_iface = "lo"
252-
253256
self.receive_referee_command = tbots_cpp.SSLRefereeProtoListener(
254257
Gamecontroller.REFEREE_IP,
255258
self.referee_port,
256-
loopback_iface,
259+
self.__get_referee_multicast_interface(),
257260
__send_referee_command,
258261
True,
259262
)
@@ -630,3 +633,19 @@ def __update_robot_count(
630633
robot_states[removed_robot_ids.get_nowait()].CopyFrom(place_state)
631634
except queue.Empty:
632635
return
636+
637+
@staticmethod
638+
def __get_referee_multicast_interface() -> str:
639+
"""Determine the network interface to join the referee multicast group on.
640+
641+
:return: the name of the interface to receive referee multicast on
642+
"""
643+
if not is_current_platform_macos():
644+
return "lo"
645+
646+
default = netifaces.gateways().get("default", {}).get(netifaces.AF_INET)
647+
if default:
648+
gateway_ip, interface_name = default
649+
return gateway_ip
650+
651+
raise RuntimeError("Could not determine the default network interface on macOS")

0 commit comments

Comments
 (0)