← Back to Blog

[ROS2, Gazebo, PX4] Ubuntu Install Script

engineering > simulation

2026-07-082 min read

#engineering #simulation #ros2 #gazebo #px4 #ubuntu #shell #sitl

이 글은 1부: ROS2, Gazebo, PX4 설치와 연결 구조에 이어지는 자동 설치용 shell script 정리이다.

앞 글에서는 각 명령을 단계별로 설명했다. 하지만 실제로 Ubuntu 새 환경을 세팅할 때는 반복 명령이 많아서 script로 관리하는 편이 낫다.

설치 명령은 한 번에 실행하되, PX4 실행과 ROS2 topic 확인은 별도 terminal에서 나눠 실행하는 구조가 가장 관리하기 쉽다.

아래 script는 Ubuntu 22.04 + ROS2 Humble + Gazebo Harmonic + PX4 SITL + Micro XRCE-DDS Agent + px4_msgs workspace를 기준으로 한다.


실행 전 조건

이 script는 Ubuntu 22.04 기준이다. WSL2에서도 사용할 수 있지만, Gazebo GUI는 WSLg와 GPU driver 상태에 따라 다르게 동작할 수 있다.

먼저 OS version을 확인한다.

lsb_release -a

Ubuntu 22.04인지 확인한다.

Description:    Ubuntu 22.04.x LTS

전체 설치 Script

파일 이름은 예를 들어 setup_ros2_gazebo_px4.sh로 둔다.

#!/usr/bin/env bash
set -euo pipefail

ROS_DISTRO_NAME="humble"
WORKSPACE_DIR="$HOME/px4_ros2_ws"
PX4_DIR="$HOME/PX4-Autopilot"
XRCE_DIR="$HOME/Micro-XRCE-DDS-Agent"

log() {
  printf "\n\033[1;32m[setup]\033[0m %s\n" "$1"
}

require_ubuntu_2204() {
  source /etc/os-release
  if [[ "${VERSION_ID}" != "22.04" ]]; then
    echo "This script is written for Ubuntu 22.04. Current VERSION_ID=${VERSION_ID}"
    exit 1
  fi
}

install_base_packages() {
  log "Installing base packages"
  sudo apt update
  sudo apt upgrade -y
  sudo apt install -y \
    build-essential \
    cmake \
    git \
    curl \
    wget \
    lsb-release \
    gnupg \
    locales \
    python3-pip \
    python3-venv \
    software-properties-common
}

configure_locale() {
  log "Configuring locale"
  sudo locale-gen en_US en_US.UTF-8
  sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
  grep -q "export LANG=en_US.UTF-8" "$HOME/.bashrc" || \
    echo "export LANG=en_US.UTF-8" >> "$HOME/.bashrc"
  export LANG=en_US.UTF-8
}

install_ros2_humble() {
  log "Installing ROS2 Humble"
  sudo add-apt-repository -y universe
  sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
    -o /usr/share/keyrings/ros-archive-keyring.gpg

  echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo "$UBUNTU_CODENAME") main" \
    | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

  sudo apt update
  sudo apt install -y \
    ros-${ROS_DISTRO_NAME}-desktop \
    ros-dev-tools \
    ros-${ROS_DISTRO_NAME}-ros-gz-bridge \
    ros-${ROS_DISTRO_NAME}-mavros \
    ros-${ROS_DISTRO_NAME}-mavros-extras

  grep -q "source /opt/ros/${ROS_DISTRO_NAME}/setup.bash" "$HOME/.bashrc" || \
    echo "source /opt/ros/${ROS_DISTRO_NAME}/setup.bash" >> "$HOME/.bashrc"
}

install_gazebo_harmonic() {
  log "Installing Gazebo Harmonic"
  sudo curl https://packages.osrfoundation.org/gazebo.gpg \
    --output /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg

  echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] https://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" \
    | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null

  sudo apt update
  sudo apt install -y gz-harmonic
}

install_px4() {
  log "Cloning and setting up PX4"
  if [[ ! -d "${PX4_DIR}" ]]; then
    git clone https://github.com/PX4/PX4-Autopilot.git --recursive "${PX4_DIR}"
  else
    git -C "${PX4_DIR}" submodule update --init --recursive
  fi

  bash "${PX4_DIR}/Tools/setup/ubuntu.sh"
}

install_micro_xrce_agent() {
  log "Building Micro XRCE-DDS Agent"
  if [[ ! -d "${XRCE_DIR}" ]]; then
    git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git "${XRCE_DIR}"
  fi

  cmake -S "${XRCE_DIR}" -B "${XRCE_DIR}/build"
  cmake --build "${XRCE_DIR}/build" -j"$(nproc)"
  sudo cmake --install "${XRCE_DIR}/build"
  sudo ldconfig /usr/local/lib/
}

create_px4_ros2_workspace() {
  log "Creating PX4 ROS2 workspace"
  mkdir -p "${WORKSPACE_DIR}/src"

  if [[ ! -d "${WORKSPACE_DIR}/src/px4_msgs" ]]; then
    git clone https://github.com/PX4/px4_msgs.git "${WORKSPACE_DIR}/src/px4_msgs"
  fi

  if [[ ! -d "${WORKSPACE_DIR}/src/px4_ros_com" ]]; then
    git clone https://github.com/PX4/px4_ros_com.git "${WORKSPACE_DIR}/src/px4_ros_com"
  fi

  source "/opt/ros/${ROS_DISTRO_NAME}/setup.bash"
  cd "${WORKSPACE_DIR}"
  colcon build --symlink-install

  grep -q "source ${WORKSPACE_DIR}/install/local_setup.bash" "$HOME/.bashrc" || \
    echo "source ${WORKSPACE_DIR}/install/local_setup.bash" >> "$HOME/.bashrc"
}

install_geographiclib_datasets() {
  log "Installing MAVROS GeographicLib datasets"
  if [[ -x "/opt/ros/${ROS_DISTRO_NAME}/lib/mavros/install_geographiclib_datasets.sh" ]]; then
    sudo "/opt/ros/${ROS_DISTRO_NAME}/lib/mavros/install_geographiclib_datasets.sh"
  fi
}

print_next_steps() {
  cat <<EOF

Setup finished.

Open new terminals or run:

  source ~/.bashrc

Terminal 1:
  MicroXRCEAgent udp4 -p 8888

Terminal 2:
  cd ~/PX4-Autopilot
  make px4_sitl gz_x500

Terminal 3:
  source /opt/ros/humble/setup.bash
  source ~/px4_ros2_ws/install/local_setup.bash
  ros2 topic list | grep /fmu
  ros2 topic echo /fmu/out/sensor_combined

Headless PX4 + Gazebo:
  cd ~/PX4-Autopilot
  HEADLESS=1 make px4_sitl gz_x500

EOF
}

main() {
  require_ubuntu_2204
  install_base_packages
  configure_locale
  install_ros2_humble
  install_gazebo_harmonic
  install_px4
  install_micro_xrce_agent
  create_px4_ros2_workspace
  install_geographiclib_datasets
  print_next_steps
}

main "$@"

실행 방법

파일을 만든 뒤 실행 권한을 준다.

chmod +x setup_ros2_gazebo_px4.sh

실행한다.

./setup_ros2_gazebo_px4.sh

중간에 sudo password를 물어볼 수 있다. PX4 setup script도 dependency를 설치하므로 시간이 꽤 걸린다.

script가 끝났다고 바로 모든 프로세스가 실행되는 것은 아니다. 설치와 실행은 분리해서 관리해야 한다.


실행 Script도 따로 만든다

설치 script와 실행 script를 분리하면 반복 테스트가 편하다. 예를 들어 run_px4_gazebo.sh를 만든다.

#!/usr/bin/env bash
set -euo pipefail

cd "$HOME/PX4-Autopilot"
make px4_sitl gz_x500

headless용은 따로 둔다.

#!/usr/bin/env bash
set -euo pipefail

cd "$HOME/PX4-Autopilot"
HEADLESS=1 make px4_sitl gz_x500

Micro XRCE-DDS Agent도 script로 둔다.

#!/usr/bin/env bash
set -euo pipefail

MicroXRCEAgent udp4 -p 8888

ROS2 topic 확인 script도 만들 수 있다.

#!/usr/bin/env bash
set -euo pipefail

source /opt/ros/humble/setup.bash
source "$HOME/px4_ros2_ws/install/local_setup.bash"

ros2 topic list | grep /fmu
ros2 topic echo /fmu/out/sensor_combined

추천 디렉터리 구조

개인 실습용으로는 다음처럼 관리하면 된다.

~/drone_dev/
  scripts/
    setup_ros2_gazebo_px4.sh
    run_micro_xrce_agent.sh
    run_px4_gazebo.sh
    run_px4_gazebo_headless.sh
    check_px4_ros2_topics.sh
  notes/
    install-log.md

source code 자체는 기본 위치에 둔다.

~/PX4-Autopilot/
~/px4_ros2_ws/
~/Micro-XRCE-DDS-Agent/

PX4 source, ROS2 workspace, 설치/실행 script를 섞어두지 않는 것이 좋다. PX4 build directory는 자주 바뀌고, ROS2 workspace는 build, install, log가 계속 생성되기 때문이다.


실패했을 때 다시 실행해도 되는가

위 script는 어느 정도 재실행을 고려했지만 완전히 transactional하지는 않다. 예를 들어 apt repository는 덮어써도 괜찮고, git clone은 디렉터리가 있으면 건너뛰도록 되어 있다.

문제가 생기면 구간별로 다시 실행하는 편이 좋다.

sudo apt update
cd ~/PX4-Autopilot
git submodule update --init --recursive
bash Tools/setup/ubuntu.sh
cd ~/px4_ros2_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install

PX4 build가 꼬이면 다음처럼 정리한다.

cd ~/PX4-Autopilot
make distclean
make px4_sitl gz_x500

다음 글

설치가 끝났다면 다음은 Gazebo topic을 Python 코드로 다루는 구조를 잡아야 한다. 그 내용은 3부: Gazebo ROS2 Python Package 구조와 코드 관리에서 이어서 정리한다.


References