From de156dfbdb58e2a52416614caae5c3a86e8b7008 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 2 Jan 2026 06:09:15 +0000 Subject: [PATCH] Install Scripts Update --- docs/installation.md | 17 ++++++ gazebo/launch/drone_landing.launch.py | 78 +++++++++++++++++++++------ setup/install_arch.sh | 14 ++++- setup/install_macos.sh | 11 ++++ setup/install_ubuntu.sh | 22 +++++++- setup/install_windows.ps1 | 14 +++-- 6 files changed, 132 insertions(+), 24 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 8b8ba17..e0d948d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -222,6 +222,23 @@ nvidia-smi # PyBullet will use hardware rendering automatically ``` +**Install Gazebo (optional):** + +If you want to use Gazebo simulation: +```bash +# Install ros-gz bridge +sudo apt install ros-humble-ros-gz + +# Install Gazebo Fortress (provides 'ign' command) +sudo apt install gz-fortress + +# Verify - one of these should work: +gz sim --version # Newer Gazebo +ign gazebo --version # Fortress (ROS 2 Humble) +``` + +**Note:** ROS 2 Humble uses Gazebo Fortress, which uses `ign gazebo` command instead of `gz sim`. The launch file auto-detects which command is available. + **Troubleshooting WSL GUI:** If GUI doesn't work: diff --git a/gazebo/launch/drone_landing.launch.py b/gazebo/launch/drone_landing.launch.py index 94550aa..3ec89de 100644 --- a/gazebo/launch/drone_landing.launch.py +++ b/gazebo/launch/drone_landing.launch.py @@ -2,9 +2,11 @@ """ Gazebo Launch File - Drone Landing Simulation Launches Gazebo with the world and spawns the drone. +Supports both 'gz' (newer) and 'ign' (Fortress) commands. """ import os +import shutil from ament_index_python.packages import get_package_share_directory from launch import LaunchDescription from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription @@ -14,6 +16,17 @@ from launch.substitutions import LaunchConfiguration, PathJoinSubstitution from launch_ros.actions import Node +def get_gazebo_command(): + """Determine whether to use 'gz' or 'ign' command.""" + if shutil.which('gz'): + return 'gz' + elif shutil.which('ign'): + return 'ign' + else: + # Default to gz, will fail with helpful error + return 'gz' + + def generate_launch_description(): """Generate the launch description.""" @@ -25,12 +38,38 @@ def generate_launch_description(): drone_model = os.path.join(model_path, 'drone', 'model.sdf') gz_resource_path = os.environ.get('GZ_SIM_RESOURCE_PATH', '') - if model_path not in gz_resource_path: - os.environ['GZ_SIM_RESOURCE_PATH'] = f"{model_path}:{gz_resource_path}" + ign_resource_path = os.environ.get('IGN_GAZEBO_RESOURCE_PATH', '') + combined_path = f"{model_path}:{gz_resource_path}:{ign_resource_path}" + + os.environ['GZ_SIM_RESOURCE_PATH'] = combined_path + os.environ['IGN_GAZEBO_RESOURCE_PATH'] = combined_path use_sim_time = LaunchConfiguration('use_sim_time', default='true') headless = LaunchConfiguration('headless', default='false') + # Detect which Gazebo command is available + gz_cmd = get_gazebo_command() + + # For ign command, use 'gazebo' subcommand; for gz, use 'sim' + if gz_cmd == 'ign': + sim_cmd = [gz_cmd, 'gazebo', '-r', world_file] + spawn_cmd = [ + gz_cmd, 'service', '-s', '/world/drone_landing_world/create', + '--reqtype', 'ignition.msgs.EntityFactory', + '--reptype', 'ignition.msgs.Boolean', + '--timeout', '5000', + '--req', f'sdf_filename: "{drone_model}", name: "drone"' + ] + else: + sim_cmd = [gz_cmd, 'sim', '-r', world_file] + spawn_cmd = [ + gz_cmd, 'service', '-s', '/world/drone_landing_world/create', + '--reqtype', 'gz.msgs.EntityFactory', + '--reptype', 'gz.msgs.Boolean', + '--timeout', '5000', + '--req', f'sdf_filename: "{drone_model}", name: "drone"' + ] + return LaunchDescription([ DeclareLaunchArgument( 'use_sim_time', @@ -44,19 +83,16 @@ def generate_launch_description(): ), ExecuteProcess( - cmd=['gz', 'sim', '-r', world_file], + cmd=sim_cmd, output='screen', - additional_env={'GZ_SIM_RESOURCE_PATH': os.environ.get('GZ_SIM_RESOURCE_PATH', '')} + additional_env={ + 'GZ_SIM_RESOURCE_PATH': combined_path, + 'IGN_GAZEBO_RESOURCE_PATH': combined_path + } ), ExecuteProcess( - cmd=[ - 'gz', 'service', '-s', '/world/drone_landing_world/create', - '--reqtype', 'gz.msgs.EntityFactory', - '--reptype', 'gz.msgs.Boolean', - '--timeout', '5000', - '--req', f'sdf_filename: "{drone_model}", name: "drone"' - ], + cmd=spawn_cmd, output='screen' ), @@ -77,8 +113,18 @@ def generate_launch_description(): if __name__ == '__main__': - print("This is a ROS 2 launch file. Run with:") - print(" ros2 launch drone_landing.launch.py") - print("") - print("Or use the standalone script:") - print(" python3 gazebo_bridge.py") + print("This is a ROS 2 launch file.") + print() + print("Usage:") + print(" ros2 launch gazebo/launch/drone_landing.launch.py") + print() + print("Or start Gazebo manually:") + + gz_cmd = get_gazebo_command() + if gz_cmd == 'ign': + print(" ign gazebo gazebo/worlds/drone_landing.sdf") + else: + print(" gz sim gazebo/worlds/drone_landing.sdf") + + print() + print("Then run: python run_gazebo.py") diff --git a/setup/install_arch.sh b/setup/install_arch.sh index 76d5082..d89b718 100755 --- a/setup/install_arch.sh +++ b/setup/install_arch.sh @@ -167,12 +167,22 @@ echo "With moving rover:" echo " python standalone_simulation.py --pattern circular --speed 0.3" echo "" echo "==============================================" -echo " Optional: Install ROS 2 from AUR" +echo " Optional: Install ROS 2 + Gazebo from AUR" echo "==============================================" echo "" echo "If you need ROS 2 for the full simulation mode:" +echo "" +echo " # Install ROS 2 Humble" echo " yay -S ros-humble-desktop" +echo "" +echo " # Install Gazebo bridge" echo " yay -S ros-humble-ros-gz" echo "" -echo "Then use simulation_host.py + ros_bridge.py + controllers.py" +echo " # Install Gazebo Fortress (provides 'ign' command)" +echo " yay -S ignition-fortress" echo "" +echo "After installing, use:" +echo " ign gazebo gazebo/worlds/drone_landing.sdf # Terminal 1" +echo " python run_gazebo.py --pattern circular # Terminal 2" +echo "" + diff --git a/setup/install_macos.sh b/setup/install_macos.sh index 7a85bed..1457376 100755 --- a/setup/install_macos.sh +++ b/setup/install_macos.sh @@ -136,3 +136,14 @@ echo "" echo "With moving rover:" echo " python standalone_simulation.py --pattern circular --speed 0.3" echo "" +echo "==============================================" +echo " Want ROS 2 + Gazebo?" +echo "==============================================" +echo "" +echo "ROS 2 and Gazebo are not supported on macOS." +echo "For the full experience, use a Linux VM or Docker:" +echo " - UTM (Apple Silicon): https://mac.getutm.app" +echo " - Docker Desktop: docker run -it ubuntu:22.04" +echo " - Then run: ./setup/install_ubuntu.sh" +echo "" + diff --git a/setup/install_ubuntu.sh b/setup/install_ubuntu.sh index c247fe1..63c15b9 100755 --- a/setup/install_ubuntu.sh +++ b/setup/install_ubuntu.sh @@ -94,15 +94,33 @@ echo "[STEP 4/8] Installing Gazebo..." if [ "$ROS_DISTRO" = "jazzy" ]; then GZ_VERSION="harmonic" + GZ_PKG="gz-harmonic" else GZ_VERSION="fortress" + GZ_PKG="gz-fortress" fi +# Install ros-gz bridge sudo apt-get install -y ros-${ROS_DISTRO}-ros-gz || { - echo "[WARN] Could not install ros-gz, Gazebo simulation will not be available" - echo "[INFO] PyBullet simulation will still work" + echo "[WARN] Could not install ros-gz" } +# Install Gazebo itself (provides gz or ign command) +sudo apt-get install -y $GZ_PKG || { + echo "[WARN] Could not install $GZ_PKG" + echo "[INFO] Trying ros-ign-gazebo..." + sudo apt-get install -y ros-${ROS_DISTRO}-ros-ign-gazebo || true +} + +# Verify installation +if command -v gz &> /dev/null; then + echo "[INFO] Gazebo installed (gz command available)" +elif command -v ign &> /dev/null; then + echo "[INFO] Gazebo Fortress installed (ign command available)" +else + echo "[WARN] Gazebo command not found - use PyBullet instead" +fi + echo "[INFO] Gazebo installation complete" # ----------------------------------------------------------------------------- diff --git a/setup/install_windows.ps1 b/setup/install_windows.ps1 index 6b9d976..753502e 100644 --- a/setup/install_windows.ps1 +++ b/setup/install_windows.ps1 @@ -210,9 +210,9 @@ if ($LASTEXITCODE -eq 0) { } Write-Host "" -Write-Host "==============================================" -ForegroundColor Cyan +Write-Host "==============================================" -ForegroundColor Cyan Write-Host " Installation Complete!" -ForegroundColor Cyan -Write-Host "==============================================" -ForegroundColor Cyan +Write-Host "==============================================" -ForegroundColor Cyan Write-Host "" Write-Host "Quick start:" -ForegroundColor Yellow Write-Host " . .\activate.ps1" -ForegroundColor White @@ -221,6 +221,12 @@ Write-Host "" Write-Host "With moving rover:" -ForegroundColor Yellow Write-Host " python standalone_simulation.py --pattern circular --speed 0.3" -ForegroundColor White Write-Host "" -Write-Host "Note: ROS 2 and Gazebo are not supported on Windows." -ForegroundColor Gray -Write-Host " standalone_simulation.py provides the complete experience." -ForegroundColor Gray +Write-Host "==============================================" -ForegroundColor Cyan +Write-Host " Want ROS 2 + Gazebo? Use WSL2" -ForegroundColor Cyan +Write-Host "==============================================" -ForegroundColor Cyan +Write-Host "" +Write-Host "For the full experience with ROS 2 and Gazebo:" -ForegroundColor Gray +Write-Host " 1. Install WSL2: wsl --install -d Ubuntu-22.04" -ForegroundColor White +Write-Host " 2. Open Ubuntu and run: ./setup/install_ubuntu.sh" -ForegroundColor White +Write-Host " 3. See docs/installation.md for details" -ForegroundColor White Write-Host ""