import argparse import importlib.metadata import os import sys import typing import wpilib if sys.version_info < (3, 10): def entry_points(group): eps = importlib.metadata.entry_points() return eps.get(group, []) else: entry_points = importlib.metadata.entry_points def _int_env_default(name: str, fallback: int) -> int: value = os.environ.get(name) if value is None: return fallback try: return int(value) except ValueError: return fallback class RunRomi: """ Runs the robot using the HAL simulator connected to a ROMI """ def __init__(self, parser: argparse.ArgumentParser): parser.add_argument( "--nogui", default=False, action="store_true", help="Don't use the WPILib simulation gui", ) sim_group = parser.add_argument_group("Additional simulation extensions") self.simexts = {} for entry_point in entry_points(group="robotpy_sim.2027"): try: sim_ext_module = entry_point.load() except ImportError: print(f"WARNING: Error detected in {entry_point}") continue self.simexts[entry_point.name] = sim_ext_module try: if entry_point.name == "ws-client": cmd_help = argparse.SUPPRESS else: cmd_help = importlib.metadata.metadata(entry_point.dist.name)[ "summary" ] except AttributeError: cmd_help = "Load specified simulation extension" sim_group.add_argument( f"--{entry_point.name}", default=False, action="store_true", help=cmd_help, ) parser.add_argument( "--host", default=os.environ.get("HALSIMWS_HOST", "10.0.0.2"), help="ROMI websocket host (default: HALSIMWS_HOST or 10.0.0.2)", ) parser.add_argument( "--port", type=int, default=_int_env_default("HALSIMWS_PORT", 3300), help="ROMI websocket port (default: HALSIMWS_PORT or 3300)", ) def run( self, options: argparse.Namespace, project_path: "os.PathLike[str]", robot_class: typing.Type[wpilib.RobotBase], ): if "ws-client" not in self.simexts: print( "ws-client HALSim extension is missing. Reinstall robotpy-halsim-ws to use run-romi", file=sys.stderr, ) return False os.environ["HALSIMWS_HOST"] = options.host os.environ["HALSIMWS_PORT"] = str(options.port) options.ws_client = True if not options.nogui: try: import halsim_gui except ImportError: print("robotpy-halsim-gui is not installed!", file=sys.stderr) return False else: halsim_gui.loadExtension() cwd = os.getcwd() for name, module in self.simexts.items(): if getattr(options, name.replace("-", "_"), False): try: module.loadExtension() except Exception: print(f"Error loading {name}!", file=sys.stderr) raise os.chdir(cwd) return robot_class.main(robot_class)