본문 바로가기
  • 경제적 자유를 얻는 그날까지
엔지니어링/임베디드

Docker로 Ubuntu 18.04 + ROS melodic 개발환경 구축

by 베니스상인 2022. 1. 8.

 

 

 

1. docker hub에서 ubuntu 이미지 다운로드

  • osrf 재단에서 배포하는 이미지는 ROS와 함께 그 버전에 적합한 ubuntu를 함께 배포
swift@swift-MacBookPro:~/workspace$ docker pull osrf/ros:melodic-desktop-full-bionic
melodic-desktop-full-bionic: Pulling from osrf/ros
Digest: sha256:f9268872571969d1fa20a64d1a9225dd592451862b21c34d66e7b6be3541b8dd
Status: Image is up to date for osrf/ros:melodic-desktop-full-bionic
docker.io/osrf/ros:melodic-desktop-full-bionic


swift@swift-MacBookPro:~/workspace$ docker images
REPOSITORY   TAG                           IMAGE ID       CREATED        SIZE
osrf/ros     melodic-desktop-full-bionic   ec5b9b9716e4   7 months ago   2.75GB
swift@swift-MacBookPro:~/workspace$

 

 

2. Docker 스크립트로 실행하기(run-ubuntu-melodic.sh)

 

#!/bin/bash
#set -x

# sudo usermod -aG docker $USER
# newgrp docker

USER_UID=$(id -u)
TAG='bionic-melodic-dev'
#IMAGE='ubuntu:18.04'
IMAGE='osrf/ros:melodic-desktop-full-bionic'
TTY='--device=/dev/ttyACM0'

#xhost +$(hostname -I | cut -d' ' -f1)

xhost +local:docker

echo "IMAGE=" $IMAGE
echo "TAG=" $TAG
echo "USER_UID=" $USER_UID
echo "USER=" $USER
echo "IPADDR=" $(hostname -I | cut -d' ' -f1)
echo "TTY=" $TTY


ENV_PARAMS=()
OTHER_PARAMS=()
args=("$@")
for ((a=0; a<"${#args[@]}"; ++a)); do
    case ${args[a]} in
        #-e) ENV_PARAMS+=("${args[a+1]}"); unset args[a+1]; ;;
        -e) ENV_PARAMS+=("${args[a]} ${args[a+1]}"); ((++a)); ;;
        --env=*) ENV_PARAMS+=("${args[a]}"); ;;
        *) OTHER_PARAMS+=("${args[a]}"); ;;
    esac
done


docker run -it \
    --init \
    --ipc=host \
    --shm-size=8G \
    --privileged \
    --net=host \
    -e DISPLAY=$DISPLAY \
    -e XDG_RUNTIME_DIR=/run/user/$USER_UID \
    -e QT_GRAPHICSSYSTEM=native \
    -e CONTAINER_NAME=$TAG \
    -e USER=$USER \
    --env=UDEV=1 \
    --env=LIBUSB_DEBUG=1 \
    --env="DISPLAY" \
    --env="QT_X11_NO_MITSHM=1" \
    ${ENV_PARAMS[@]} \
    -v /run/user/$USER_UID:/run/user/$USER_UID \
    -v /dev:/dev \
    -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
    -v /home/$USER/workspace:/workspace \
    --name=$TAG \
    $IMAGE \
    ${OTHER_PARAMS[@]}  \
    /bin/bash  
export containerId=$(docker ps -l -q)

 

 

3. Docker안에서 초기화(init-melodic.sh)

 

#!/bin/bash



cat /etc/apt/sources.list
apt-get autoremove --purge --yes \
    && rm -rf /var/lib/apt/lists/* \
    && rm -rf /etc/ros/rosdep/sources.list.d/20-default.list
sed -i -e 's+\(^deb http://security.*\)+# \1+g' /etc/apt/sources.list
apt-get clean && apt-get update 


apt-get install -y \
    tmux \
    curl \
    wget \
    vim \
    git \
    sudo \
    libgl1-mesa-glx \
    libgl1-mesa-dri \
    mesa-utils \
    unzip \
    ntp \
    whois \
    sudo \
    net-tools \
    locales \
    ssh


locale-gen en_US.UTF-8


# ROS 설치 과정
# ubuntu version fixed: bionic 
#sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list'
#sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
#sudo apt update

## Gazebo simulator dependencies
#sudo apt-get install -y \
#    protobuf-compiler \
#    libeigen3-dev \
#    libopencv-dev \
#    ros-melodic-rqt*

sudo apt-get install ros-melodic-rqt* -y 

# sudo apt-get install ros-melodic-desktop-full -y

sudo apt-get install python3 python3-pip python-rosinstall python-rosdep python-rosinstall-generator -y


rosdep init
rosdep update 
rosdep fix-permissions 

echo HOME=${HOME}


# 빌드 패키지 설치
#apt-get -y install \ 
#    build-essential \
#    sudo \
#    python3 \
#    python3-pip \
#    python-rosinstall \
#    python-rosinstall-generator \
#    python-wstool

apt-get autoclean


# 3
mkdir -p $HOME/catkin_ws/src && cd $HOME/catkin_ws/src && catkin_init_workspace

# 소스코드 다운로드

cd $HOME/catkin_ws && catkin_make

echo "source /opt/ros/melodic/setup.bash" >> $HOME/.bashrc
echo "source /$HOME/catkin_ws/devel/setup.bash" >> $HOME/.bashrc
echo "export ROS_HOSTNAME=localhost" >> $HOME/.bashrc
echo "export ROS_MASTER_URI=http://localhost:11311" >> $HOME/.bashrc
echo "alias cw='cd ~/catkin_ws'" >> $HOME/.bashrc
echo "alias cs='cd ~/catkin_ws/src'" >> $HOME/.bashrc
echo "alias cm='cd ~/catkin_ws && catkin_make'" >> $HOME/.bashrc

source /opt/ros/$ROS_DISTRO/setup.bash
source /$HOME/catkin_ws/devel/setup.bash

IPADDR=$(hostname -I | cut -d' ' -f1)
echo "USER=$USER"
echo "HOME=$HOME"
echo "IPADDR=$IPADDR"
echo "ROS_ROOT=$ROS_ROOT"
echo "ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH"
echo "ROS_HOSTNAME=$ROS_HOSTNAME"
echo "ROS_MASTER_URI=$ROS_MASTER_URI"

 

 

4. Dockerfile 이미지 빌드 및 사용법

 

1) Dockerfile 작성

  • base가 되는 이미지에 추가적인 수행 명령들을 dockerfile 에 작성하여 이미지화화
# Ubuntu:latest는 20.04를 의미합니다.
FROM osrf/ros:melodic-desktop-full-bionic

# 작성자 이름입니다
MAINTAINER shlee853

# apt로 패키지 받을 때 interative하게 사용하는 기능들을 끕니다. Docker에서 로그를 넘길 때 문제가 생길 수 있으므로 이 옵션은 필수입니다!
ARG DEBIAN_FRONTEND=noninteractive
ARG HOST_USER
ARG UNAME=${HOST_USER}
ARG UID=1000
ARG GID=1000
ARG HOME=/home/${UNAME}


#RUN xhost +local:docker

# clean up first
RUN apt-get autoremove --purge --yes \
    && rm -rf /var/lib/apt/lists/* \
    && rm -rf /etc/ros/rosdep/sources.list.d/20-default.list

# 필수 유틸리티 설치
RUN apt-get update && apt-get install -y \
    tmux \
    curl \
    wget \
    vim \
    git \
    sudo \
    libgl1-mesa-glx \
    libgl1-mesa-dri \
    mesa-utils \
    unzip \
    locales \
    ntp \
    whois \
    net-tools \
    sudo


RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8  


RUN rosdep init
RUN apt-get install ros-melodic-rqt* -y 
RUN apt-get install python3 python3-pip python-rosinstall python-rosdep python-rosinstall-generator -y

RUN mkdir -p /workspace && chmod -R +x /workspace
#COPY /home/${HOST_USER}/workspace/init-melodic.sh /workspace/

RUN useradd -rm -d ${HOME} -s /bin/bash -g root -G sudo,audio,video,plugdev -u ${UID} ${UNAME}
RUN mkdir -p /etc/sudoers.d && \
    echo "${UNAME} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/${UNAME} && \
    chmod 0440 /etc/sudoers.d/${UNAME} 

USER ${UNAME}
WORKDIR $HOME

RUN rosdep update 
RUN rosdep fix-permissions 

COPY init_tools.sh ./
#CMD ["/bin/bash", "init_tools.sh"]

RUN cd /

# 3
#RUN mkdir -p $HOME/catkin_ws/src && cd $HOME/catkin_ws/src 
#RUN catkin_init_workspace

# 소스코드 다운로드
#RUN cd $HOME/catkin_ws && catkin_make
#RUN source /opt/ros/$ROS_DISTRO/setup.bash
#RUN source /$HOME/catkin_ws/devel/setup.bash

#RUN echo "source /opt/ros/melodic/setup.bash" >> $HOME/.bashrc
#RUN echo "source /$HOME/catkin_ws/devel/setup.bash" >> $HOME/.bashrc
#RUN echo "export ROS_HOSTNAME=localhost" >> $HOME/.bashrc
#RUN echo "export ROS_MASTER_URI=http://localhost:11311" >> $HOME/.bashrc
#RUN echo "alias cw='cd ~/catkin_ws'" >> $HOME/.bashrc
#RUN echo "alias cs='cd ~/catkin_ws/src'" >> $HOME/.bashrc
#RUN echo "alias cm='cd ~/catkin_ws && catkin_make'" >> $HOME/.bashrc

 

 

2) 이미지 빌드하기

  • dockerfile을 이용하여 빌드 수행
  •  --no-cache: 이전 빌드에서 생성된 캐시 사용하지 않음
  •  --force-rm: 빌드하다가 fail시 자동 삭제
  •  -f: 사용할 Dockerfile의 이름을 명시
  •  -t: 생성할 이미지의 ID와 TAG 명시
  •  . 는 Dockerfile의 경로를 명시
swift@swift-MacBookPro:~/workspace$ sudo docker build --no-cache --force-rm -f Dockerfile --build-arg HOST_USER=$USER -t ros/melodic:base .

swift@swift-MacBookPro:~/workspace$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
swift@swift-MacBookPro:~/workspace$ docker images
REPOSITORY    TAG                           IMAGE ID       CREATED              SIZE
ros/melodic   base                          db4c9f983086   About a minute ago   3.01GB
osrf/ros      melodic-desktop-full-bionic   ec5b9b9716e4   7 months ago         2.75GB

 

 

3) docker 실행하기

  • docker run이전에 xhost로 host와 docker간 GUI 연동을 위한 명령어 실행
xhost +local:docker

 

  • docker run 실행
docker run -it \
    --init \
    --ipc=host \
    --shm-size=8G \
    --privileged \
    --net=host \
    -e DISPLAY=$DISPLAY \
    -e XDG_RUNTIME_DIR=/run/user/1000 \
    -e QT_GRAPHICSSYSTEM=native \
    -e USER=$USER \
    --env=UDEV=1 \
    --env=LIBUSB_DEBUG=1 \
    --env="DISPLAY" \
    --env="QT_X11_NO_MITSHM=1" \
    ${ENV_PARAMS[@]} \
    -v /home/$USER/workspace:/home/$USER/workspace \
    -v /dev:/dev \
    -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
    ros/melodic:base \
    ${OTHER_PARAMS[@]}  \
    /bin/bash

 

  • 컨테이너 안에서 초기화 명령 실행(init_tools.sh)
mkdir -p $HOME/catkin_ws/src && cd $HOME/catkin_ws/src && catkin_init_workspace

# 소스코드 다운로드

cd $HOME/catkin_ws && catkin_make

echo "source /opt/ros/melodic/setup.bash" >> $HOME/.bashrc
echo "source /$HOME/catkin_ws/devel/setup.bash" >> $HOME/.bashrc
echo "export ROS_HOSTNAME=localhost" >> $HOME/.bashrc
echo "export ROS_MASTER_URI=http://localhost:11311" >> $HOME/.bashrc
echo "alias cw='cd ~/catkin_ws'" >> $HOME/.bashrc
echo "alias cs='cd ~/catkin_ws/src'" >> $HOME/.bashrc
echo "alias cm='cd ~/catkin_ws && catkin_make'" >> $HOME/.bashrc

source /opt/ros/$ROS_DISTRO/setup.bash
source /$HOME/catkin_ws/devel/setup.bash

echo "USER=$USER"
echo "HOME=$HOME"
echo "ROS_ROOT=$ROS_ROOT"
echo "ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH"
echo "ROS_HOSTNAME=$ROS_HOSTNAME"
echo "ROS_MASTER_URI=$ROS_MASTER_URI"

 

 

 

실행결과

swift@swift-MacBookPro:~/workspace$ xhost +local:docker
non-network local connections being added to access control list
swift@swift-MacBookPro:~/workspace$ 
swift@swift-MacBookPro:~/workspace$ docker run -it \
>     --init \
>     --ipc=host \
>     --shm-size=8G \
>     --privileged \
>     --net=host \
>     -e DISPLAY=$DISPLAY \
>     -e XDG_RUNTIME_DIR=/run/user/1000 \
>     -e QT_GRAPHICSSYSTEM=native \
>     -e USER=$USER \
>     --env=UDEV=1 \
>     --env=LIBUSB_DEBUG=1 \
>     --env="DISPLAY" \
>     --env="QT_X11_NO_MITSHM=1" \
>     ${ENV_PARAMS[@]} \
>     -v /dev:/dev \
>     -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
>     ros/melodic:base \
>     ${OTHER_PARAMS[@]}  \
>     /bin/bash  


To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

swift@swift-MacBookPro:~$ 
swift@swift-MacBookPro:~$ 
swift@swift-MacBookPro:~$ ls
init_tools.sh
swift@swift-MacBookPro:~$ ./init_tools.sh 
Creating symlink "/home/swift/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/melodic/share/catkin/cmake/toplevel.cmake"
Base path: /home/swift/catkin_ws
Source space: /home/swift/catkin_ws/src
Build space: /home/swift/catkin_ws/build
Devel space: /home/swift/catkin_ws/devel
Install space: /home/swift/catkin_ws/install
####
#### Running command: "cmake /home/swift/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/swift/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/swift/catkin_ws/install -G Unix Makefiles" in "/home/swift/catkin_ws/build"
####
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using CATKIN_DEVEL_PREFIX: /home/swift/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/melodic
-- This workspace overlays: /opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/swift/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- Configuring done
-- Generating done
-- Build files have been written to: /home/swift/catkin_ws/build
####
#### Running command: "make -j4 -l4" in "/home/swift/catkin_ws/build"
####
USER=swift
HOME=/home/swift
ROS_ROOT=/opt/ros/melodic/share/ros
ROS_PACKAGE_PATH=/home/swift/catkin_ws/src:/opt/ros/melodic/share
ROS_HOSTNAME=
ROS_MASTER_URI=http://localhost:11311
swift@swift-MacBookPro:~$ 
swift@swift-MacBookPro:~$ 
swift@swift-MacBookPro:~$ bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

swift@swift-MacBookPro:~$
728x90

댓글