Skip to content

Commit dd5c1d4

Browse files
committed
Update runner scripts
1 parent bb0740c commit dd5c1d4

File tree

3 files changed

+132
-70
lines changed

3 files changed

+132
-70
lines changed

scripts/generate_release.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@
7878
logger.info("Copying helper scripts to temp directory")
7979
shutil.copy(project_root / "scripts/setup.py", temp_dir / "setup.py")
8080
for script in project_root.glob("scripts/run_*.py"):
81+
if "run_comp_" in str(script):
82+
continue
8183
shutil.copy(script, temp_dir)
8284

85+
script_dir = temp_dir / "scripts"
86+
script_dir.mkdir()
8387
logger.info("Copying example code to temp directory")
8488
shutil.copytree(project_root / "example_robots", temp_dir / "example_robots")
8589

scripts/run_simulator.py

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,98 @@
33
A script to run the project in Webots.
44
55
Largely just a shortcut to running the arena world in Webots.
6-
Only functional in releases.
76
"""
7+
# ruff: noqa: E501
8+
from __future__ import annotations
9+
810
import sys
911
import traceback
12+
from os.path import expandvars
1013
from pathlib import Path
1114
from shutil import which
1215
from subprocess import Popen
1316

1417
if sys.platform == "win32":
1518
from subprocess import CREATE_NEW_PROCESS_GROUP, DETACHED_PROCESS
1619

17-
try:
18-
if not (Path(__file__).parent / 'simulator/VERSION').exists():
19-
print("This script is only functional in releases.")
20-
raise RuntimeError
20+
if (Path(__file__).parent / 'simulator/VERSION').exists():
21+
print("Running in release mode")
22+
SIM_BASE = Path(__file__).parent.resolve()
23+
else:
24+
print("Running in development mode")
25+
# Assume the script is in the scripts directory
26+
SIM_BASE = Path(__file__).parents[1].resolve()
27+
28+
POSSIBLE_WEBOTS_PATHS = [
29+
("darwin", "/Applications/Webots.app/Contents/MacOS/webots"),
30+
("win32", "C:\\Program Files\\Webots\\msys64\\mingw64\\bin\\webotsw.exe"),
31+
("win32", expandvars("%LOCALAPPDATA%\\Programs\\Webots\\msys64\\mingw64\\bin\\webotsw.exe")),
32+
# Attempt to use the start menu shortcut
33+
("win32", expandvars("%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Cyberbotics\\Webots.lnk")),
34+
("win32", expandvars("%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Cyberbotics\\Webots.lnk")),
35+
("linux", "/usr/local/bin/webots"),
36+
("linux", "/usr/bin/webots"),
37+
]
38+
39+
40+
def get_webots_parameters() -> tuple[Path, Path]:
41+
"""
42+
Get the paths to the Webots executable and the arena world file.
2143
22-
world_file = Path(__file__).parent / "simulator/worlds/arena.wbt"
44+
:return: The paths to the Webots executable and the arena world file
45+
"""
46+
world_file = SIM_BASE / "simulator/worlds/arena.wbt"
2347

48+
if not world_file.exists():
49+
raise RuntimeError("World file not found.")
50+
51+
if not (SIM_BASE / "venv").exists():
52+
raise RuntimeError("Please run the setup.py script before running the simulator.")
53+
54+
# Check if Webots is in the PATH
2455
webots = which("webots")
2556

2657
# Find the webots executable, if it is not in the PATH
2758
if webots is None:
28-
if sys.platform == "darwin":
29-
webots = "/Applications/Webots.app/Contents/MacOS/webots"
30-
elif sys.platform == "win32":
31-
webots = "C:\\Program Files\\Webots\\msys64\\mingw64\\bin\\webotsw.exe"
32-
elif sys.platform.startswith("linux"):
33-
possible_paths = ["/usr/local/bin/webots", "/usr/bin/webots"]
34-
for path in possible_paths:
59+
for system_filter, path in POSSIBLE_WEBOTS_PATHS:
60+
if sys.platform.startswith(system_filter):
61+
print(f"Checking {path}")
3562
if Path(path).exists():
3663
webots = path
3764
break
38-
else:
39-
print("Webots executable not found.")
40-
raise RuntimeError
65+
66+
if webots is None or not Path(webots).exists():
67+
raise RuntimeError("Webots executable not found.")
68+
69+
return Path(webots), world_file
70+
71+
72+
def main() -> None:
73+
"""Run the project in Webots."""
74+
try:
75+
webots, world_file = get_webots_parameters()
76+
77+
# Run the world file in Webots,
78+
# detaching the process so it does not close when this script does
79+
if sys.platform == "win32":
80+
Popen(
81+
[str(webots), str(world_file)],
82+
creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP,
83+
# shell=True is needed to run from shortcuts
84+
shell=(webots.suffix == ".lnk"),
85+
)
4186
else:
42-
print("Unsupported platform.")
43-
raise RuntimeError
44-
45-
if not Path(webots).exists():
46-
print("Webots executable not found.")
47-
raise RuntimeError
48-
49-
if not (Path(__file__).parent / "venv").exists():
50-
print("Please run the setup.py script before running the simulator.")
51-
raise RuntimeError
52-
53-
# Run the world file in Webots,
54-
# detaching the process so it does not close when this script does
55-
if sys.platform == "win32":
56-
Popen([webots, world_file], creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
57-
else:
58-
Popen([webots, world_file], start_new_session=True)
59-
except RuntimeError:
60-
input("Press enter to continue...")
61-
exit(1)
62-
except Exception as e:
63-
print(f"An error occurred: {e}")
64-
print(traceback.format_exc())
65-
input("Press enter to continue...")
66-
exit(1)
87+
Popen([str(webots), str(world_file)], start_new_session=True)
88+
except RuntimeError as e:
89+
print(f"An error occurred: {e}")
90+
input("Press enter to continue...")
91+
exit(1)
92+
except Exception as e:
93+
print(f"An error occurred: {e}")
94+
print(traceback.format_exc())
95+
input("Press enter to continue...")
96+
exit(1)
97+
98+
99+
if __name__ == "__main__":
100+
main()

scripts/setup.py

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,24 @@
1313
import logging
1414
import platform
1515
import shutil
16+
import sys
1617
from pathlib import Path
17-
from subprocess import run
18+
from subprocess import SubprocessError, check_call
1819
from venv import create
1920

2021
logging.basicConfig(level=logging.INFO, format="[%(asctime)s] %(levelname)s: %(message)s")
2122
logger = logging.getLogger(__name__)
2223

23-
try:
24-
if (Path(__file__).parent / 'simulator/VERSION').exists():
25-
# This is running from a release
26-
project_root = Path(__file__).parent
27-
requirements = project_root / "simulator/requirements.txt"
28-
else:
29-
# This is running from the repository
30-
project_root = Path(__file__).parents[1]
31-
requirements = project_root / "requirements.txt"
3224

33-
venv_dir = project_root / "venv"
25+
def populate_python_config(runtime_ini: Path, venv_python: Path) -> None:
26+
"""
27+
Populate the python configuration in the runtime.ini file.
3428
35-
logger.info(f"Creating virtual environment in {venv_dir.absolute()}")
36-
create(venv_dir, with_pip=True)
29+
This will set the python command to the virtual environment python.
3730
38-
logger.info(f"Installing dependencies from {requirements.absolute()}")
39-
if platform.system() == "Windows":
40-
pip = venv_dir / "Scripts/pip.exe"
41-
venv_python = venv_dir / "Scripts/python"
42-
else:
43-
pip = venv_dir / "bin/pip"
44-
venv_python = venv_dir / "bin/python"
45-
run(
46-
[str(venv_python), "-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"],
47-
cwd=venv_dir,
48-
)
49-
run([str(pip), "install", "-r", str(requirements)], cwd=venv_dir)
50-
51-
logger.info("Setting up Webots Python location")
52-
53-
runtime_ini = project_root / "simulator/controllers/usercode_runner/runtime.ini"
31+
:param runtime_ini: The path to the runtime.ini file
32+
:param venv_python: The path to the virtual environment python executable
33+
"""
5434
runtime_content: list[str] = []
5535
if runtime_ini.exists():
5636
prev_runtime_content = runtime_ini.read_text().splitlines()
@@ -79,12 +59,56 @@
7959

8060
runtime_ini.write_text('\n'.join(runtime_content))
8161

62+
63+
try:
64+
if (Path(__file__).parent / 'simulator/VERSION').exists():
65+
# This is running from a release
66+
print("Running in release mode")
67+
project_root = Path(__file__).parent
68+
requirements = project_root / "simulator/requirements.txt"
69+
else:
70+
# This is running from the repository
71+
print("Running in development mode")
72+
project_root = Path(__file__).parents[1]
73+
requirements = project_root / "requirements.txt"
74+
75+
print(f"Python version: {sys.version} on {platform.platform()}")
76+
77+
venv_dir = project_root / "venv"
78+
79+
logger.info(f"Creating virtual environment in {venv_dir.absolute()}")
80+
create(venv_dir, with_pip=True)
81+
82+
logger.info(f"Installing dependencies from {requirements.absolute()}")
83+
if platform.system() == "Windows":
84+
pip = venv_dir / "Scripts/pip.exe"
85+
venv_python = venv_dir / "Scripts/python"
86+
else:
87+
pip = venv_dir / "bin/pip"
88+
venv_python = venv_dir / "bin/python"
89+
check_call(
90+
[str(venv_python), "-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"],
91+
cwd=venv_dir,
92+
)
93+
check_call([str(pip), "install", "-r", str(requirements)], cwd=venv_dir)
94+
95+
logger.info("Setting up Webots Python location")
96+
97+
controllers_dir = project_root / "simulator/controllers"
98+
usercode_ini = controllers_dir / "usercode_runner/runtime.ini"
99+
supervisor_ini = controllers_dir / "competition_supervisor/runtime.ini"
100+
populate_python_config(usercode_ini, venv_python)
101+
populate_python_config(supervisor_ini, venv_python)
102+
82103
# repopulate zone 0 with example code if robot.py is missing
83104
zone_0 = project_root / "zone_0"
84105
if not (zone_0 / "robot.py").exists():
85106
logger.info("Repopulating zone 0 with example code")
86107
zone_0.mkdir(exist_ok=True)
87108
shutil.copy(project_root / "example_robots/basic_robot.py", zone_0 / "robot.py")
109+
except SubprocessError:
110+
logger.error("Setup failed due to an error.")
111+
input("An error occurred, press enter to close.")
88112
except Exception:
89113
logger.exception("Setup failed due to an error.")
90114
input("An error occurred, press enter to close.")

0 commit comments

Comments
 (0)