diff --git a/cobot/commands/delete.py b/cobot/commands/delete.py index d2ddacb..30dd6a6 100644 --- a/cobot/commands/delete.py +++ b/cobot/commands/delete.py @@ -127,8 +127,10 @@ def _remove_ros2(write) -> None: # Remove Webots from the system via apt. # Удаляем Webots из системы через apt. def _remove_webots(write) -> None: - """Remove the webots package via apt and run autoremove. Skips if webots is not found on PATH. - Удаляет пакет webots через apt и запускает autoremove. Пропускает если webots не найден в PATH. + """Remove the webots package via apt, run autoremove, and clean up WEBOTS_HOME + from .bashrc / .zshrc. Skips if webots is not found on PATH. + Удаляет пакет webots через apt, запускает autoremove и очищает WEBOTS_HOME из + .bashrc / .zshrc. Пропускает если webots не найден в PATH. """ write("[cyan][*][/cyan] Removing Webots...") if not shutil.which("webots"): @@ -138,6 +140,22 @@ def _remove_webots(write) -> None: subprocess.run(["sudo", "apt", "autoremove", "-y"], capture_output=True) write("[green][ok][/green] Webots removed") + # Remove the WEBOTS_HOME block that install_webots.sh added to shell configs. + # Удаляем блок WEBOTS_HOME, добавленный install_webots.sh в конфиги оболочки. + for rc_name in [".bashrc", ".zshrc"]: + rc = Path.home() / rc_name + if not rc.exists(): + continue + content = rc.read_text() + if "WEBOTS_HOME" not in content: + continue + new_content = content.replace("\n# Webots\nexport WEBOTS_HOME=/usr/local/webots\n", "\n") + new_content = new_content.replace("export WEBOTS_HOME=/usr/local/webots\n", "") + new_content = new_content.replace("# Webots\n", "") + if new_content != content: + rc.write_text(new_content) + write(f"[green][ok][/green] Cleaned WEBOTS_HOME from ~/{rc_name}") + # Uninstall the cobot CLI from the uv tool store. # Удаляем cobot CLI из хранилища инструментов uv. diff --git a/cobot/commands/run.py b/cobot/commands/run.py index 864803e..887127f 100644 --- a/cobot/commands/run.py +++ b/cobot/commands/run.py @@ -18,6 +18,9 @@ _PROJECT_DIR = Path(__file__).parent.parent.parent _CONFIG_PATH = _PROJECT_DIR / "cobot-setting.yaml" _INSTALL_DIR = _PROJECT_DIR / "install" _JAZZY_DIR = Path("/opt/ros/jazzy") +# Default Webots installation path for the official .deb package. +# Путь установки Webots по умолчанию для официального .deb-пакета. +_WEBOTS_DEFAULT_HOME = Path("/usr/local/webots") # Path where the config file is mounted inside the Docker container. # Путь по которому конфиг-файл монтируется внутри Docker-контейнера. @@ -86,6 +89,28 @@ def _ask(step: str, question: str, options: List[str], default: str) -> Optional return _Ask(step, question, options, default).run() +def _detect_webots_home() -> str: + """Return the WEBOTS_HOME path for the locally installed Webots. + + Checks the environment variable first, then the default deb install path, + then resolves the 'webots' symlink to find the real installation directory. + Returns an empty string if Webots cannot be located. + + Возвращает путь WEBOTS_HOME для локально установленного Webots. + Сначала проверяет переменную окружения, затем стандартный путь deb-установки, + затем разворачивает симлинк 'webots' до реальной директории установки. + Возвращает пустую строку если Webots не найден. + """ + if "WEBOTS_HOME" in os.environ: + return os.environ["WEBOTS_HOME"] + if _WEBOTS_DEFAULT_HOME.is_dir(): + return str(_WEBOTS_DEFAULT_HOME) + webots_bin = shutil.which("webots") + if webots_bin: + return str(Path(webots_bin).resolve().parent) + return "" + + # Detect the GPU type so we can pass the right flags to docker run for Webots rendering. # Определяем тип GPU, чтобы передать нужные флаги в docker run для рендеринга Webots. def _detect_gpu() -> str: @@ -208,7 +233,11 @@ def _task_run_local(screen: RunScreen, mode: str) -> None: if mode == "webots": ros_cmd += " simulate:=1" + webots_home = _detect_webots_home() if mode == "webots" else "" + webots_export = f"export WEBOTS_HOME={webots_home} && " if webots_home else "" + full_cmd = ( + f"{webots_export}" f"source {_JAZZY_DIR}/setup.bash && " f"source {_INSTALL_DIR}/setup.bash && " f"{ros_cmd}" @@ -216,7 +245,10 @@ def _task_run_local(screen: RunScreen, mode: str) -> None: label = "Webots simulator" if mode == "webots" else "Controller" screen.write(f"[bold]Launching {label} (local)[/bold]") - screen.write(f"[dim]{ros_cmd}[/dim]\n") + screen.write(f"[dim]{ros_cmd}[/dim]") + if webots_home: + screen.write(f"[dim]WEBOTS_HOME: {webots_home}[/dim]") + screen.write("") proc = subprocess.Popen( ["bash", "-c", full_cmd], diff --git a/scripts/install_webots.sh b/scripts/install_webots.sh index f3fc272..de4621b 100755 --- a/scripts/install_webots.sh +++ b/scripts/install_webots.sh @@ -9,6 +9,7 @@ export DEBIAN_FRONTEND=noninteractive PROGRESS() { echo "PROGRESS:$1:$2"; } WEBOTS_VERSION="2025a" +WEBOTS_HOME="/usr/local/webots" DEB_URL="https://github.com/cyberbotics/webots/releases/download/R${WEBOTS_VERSION}/webots_${WEBOTS_VERSION}_amd64.deb" TMP_DIR="$(mktemp -d)" DEB_PATH="${TMP_DIR}/webots_${WEBOTS_VERSION}_amd64.deb" @@ -28,5 +29,20 @@ echo "Download complete. Installing..." sudo apt-get install -y "$DEB_PATH" +PROGRESS 90 "Configuring WEBOTS_HOME..." +echo "Setting WEBOTS_HOME=${WEBOTS_HOME}..." + +WEBOTS_BLOCK="# Webots\nexport WEBOTS_HOME=${WEBOTS_HOME}" + +for RC in "$HOME/.bashrc" "$HOME/.zshrc"; do + [ -f "$RC" ] || continue + if ! grep -q "WEBOTS_HOME" "$RC"; then + printf "\n%b\n" "$WEBOTS_BLOCK" >> "$RC" + echo " Added WEBOTS_HOME to $RC" + fi +done + +export WEBOTS_HOME="${WEBOTS_HOME}" + PROGRESS 100 "Done" echo "Webots ${WEBOTS_VERSION} installed successfully."