ROS 도커에서 사용해보기 - 튜토리얼 2

By qsp , Created on 1st Sep 2021

이번에는 도커 ROS 튜토리얼 2탄
쉽게 깃허브에서 클론이나 다운로드도 진행해서 할 수 있고 내용도 살펴볼 수 있습니더~~

Dockerfile 다운로드

깃허브에서 클론 한 후 쉽게 사용할 수도 있습니다.

docker 및 docker-compose가 설치되어 있어야 합니다

클론 받은 후에 build && up 하기

git clone https://github.com/terrificmn/docker-ros.git
docker-compose build 
docker-compose up

도커ros관련 깃허브 확인하기 사용법은 깃허브를 확인해 주세요

조금 설명을 보려면 아래를 더 읽어주시면 됩니다.


Dockerfile 완성하기

아무래도 기존의 방식으로 실행을 한다면 매번 docker run 을 실행하면서 많은 옵션을 넣어줘야하는데

기본 docker ros 실행하기 보러가기

하지만 그렇게 하면 너무 불편하므로 Dockerfile과 docker-compose.yml 파일을 좀 더 완성을 시켜보자~

전에 했던 것과 다른점은 Mesa Libraries 설치를 한 것이 있고 (AMD 라데온 그래픽용)
만약 Nvidia 그래픽 카드를 사용한다면 (Mesa Libraries 설치부분을 필요 없을 듯 하다)

nvidia-docker1 부분을 참고해보자

이제 Dockerfile 내용을 바꿔준다

FROM ros:melodic-ros-core-bionic

RUN apt-get update && apt-get install -y \
    ros-melodic-desktop-full

# 일반적인 melodic 설치위한 과정
RUN apt-get install --no-install-recommends -y \
    build-essential \
    python-rosdep \
    python-rosinstall \
    python-vcstools \
    python-rosinstall-generator \
    python-wstool \
    && rm -rf /var/lib/apt/lists/*

# Mesa libraries 설치 (AMD용)
RUN apt-get update && \
  apt-get -y install libgl1-mesa-glx libgl1-mesa-dri mesa-utils \
  vim gedit && \
  rm -rf /var/lib/apt/lists/*

# rsodep 최초실행  init 및 update만 하면 sudo 로 하라는 에러발생
RUN rosdep init \
  && rosdep update \
  && rosdep fix-permissions

RUN apt-get update && \
  apt-get install -y software-properties-common

RUN echo 'source /opt/ros/$ROS_DISTRO/setup.bash' >> /root/.bashrc && \
  echo "source /root/catkin_ws/devel/setup.bash" >> /root/.bashrc


docker-compose.yml 완성하기

기존에는 docker-compose up을 하면 실행이 안되었고
roscore도 따로 실행을 해야하는데 아예 컨테이너가 실행될 때 roscore만 실행하게 바꾸었다

docker-compose.yml 업데이트 해준다

version: "3.9"
services: 

  ros:
    container_name: ros
    build: 
      context: .  # 현재 디렉토리
      dockerfile: Dockerfile  
    volumes:
      - ./catkin_ws:/root/catkin_ws   # 현재 디렉토리 기본으로 연결
      - ~/.ssh:/root/.ssh  # 홈디렉토리에 있는 .ssh 연결
      - /tmp/.X11-unix:/tmp/.X11-unix  # 디스플레이 연결 (GUI 프로그램 실행하기 위해)
      - /dev:/dev
    ports:
      - "11311:11311"
    command:
      - roscore  
    stdin_open: true
    privileged: true
    tty: true
    devices:
      - /dev:/dev
    group_add:
      - video
    # network_mode: host
    environment:
      - ROS_MASTER_URI=http://localhost:11311
      - DISPLAY=$DISPLAY
      # - QT_X11_NO_MITSHM=1 # 이제 보니 Nvidia 전용인 듯하다

그리고 docker-compose.yml 파일에는 많은 옵션들이 들어가 있다
volumes에서 catkin_ws 디렉토리를 연결해준다~
다른 경로로 설정하려면 절대경로로 입력을 해주면 된다

또한 volumes 옵션에서 /dev:/dev 로 연결한 것은 : 왼쪽은 로컬호스트 : 오른쪽은 컨테이너의 디렉토리인데
이렇게 해줌으로써 USB등의 장치를 연결했을 때도 사용할 수 있다
즉, 도커를 사용해도 직접 카메라 등의 센서는 로컬 컴퓨터에 연결이 되기 때문에
그 로컬 호스트의 자원을 같이 사용하기 위해서 연결을 하는 것임

/dev 디렉토리를 통째로 연결하는 것은 보안상 안 좋을 수도 있다는 의견도 있는데
특정 장치만 예를 들어 /dev/ttyUSB0 이런식으로 연결하면 좋을 듯 한데
인식을 못해서 그냥 통째로 연결을 해주면 문제는 딱히 발생하지는 않음
특정 장치만 연결하는게 더 좋겠지만 일단 이렇게 넘어감 ㅠ


이제 빌드 && 실행하기

먼저 다시 해당 경로로 이동을 한 후에 (Dockerfile이 있는 디렉토리)
docker-ros라고 가정을 하고 이동을 한 후에 build 명령어 입력한다

cd ~/docker-ros
docker-compose build

build가 완료되면 docker 컨테이너를 실행시켜준다

docker-compose up

아래 처럼 roscore가 실행이 된다

생략...
ros    | SUMMARY
ros    | ========
ros    | 
ros    | PARAMETERS
ros    |  * /rosdistro: melodic
ros    |  * /rosversion: 1.14.11
ros    | 
ros    | NODES
ros    | 
ros    | auto-starting new master
ros    | process[master]: started with pid [40]
ros    | ROS_MASTER_URI=http://865a31d20c:11311/
ros    | 
ros    | setting /run_id to 9efa41ec-0aea-11ec-8d15-0242ac120002
ros    | process[rosout-1]: started with pid [51]
ros    | started core service [/rosout]

도커 컨테이너를 종료하려면 ctrl+c 를 눌러주면 된다


docker 실행 및 터미널 여러개 띄우기

취향문제이겠지만 terminator라는 터미널 프로그램을 받아서 사용하는 것을 강추~
여러 창을 한개의 터미널 창에서 나눠서 사용할 수 있어서 편함

터미네이터 설치 보러가기

먼저 그래픽 자원을 사용할 수 있게

xhost + local:docker 

그리고 docker-compose up으로 실행을 시킨다

docker-compose up

그리고 다른 터미널을 띄워준다.
다른 창에서 ros로 컨테이너 이름을 설정했으므로 ros로 컨테이너 접근할 수 있다

docker exec -it ros bash

이제 원하는 작업을 하면 된다. catkin 디렉토리로 이동해서 패키지를 만들어 보는 등

더 많은 창이 필요할 경우는 위의 명령어로 또 새로운 터미널에서 열고 작업하면 된다

docker exec -it ros bash

끝. 감사합니다~


트러블 슈팅

혹시라도 컨테이너 겹쳐서 이름이 겹치는 등의 에러가 발생하면 과감하게 컨테이너를 삭제하자

Conflict. The container name "/ros" is already in use by container "aab96b8ed891b7e78628f217cb8bfa26189c635380dea6058b05951c0b332aab". You have to remove (or rename) that container to be able to reuse that name.
docker ps -a 

예를 들어 결과가

CONTAINER ID   IMAGE                         COMMAND                  CREATED        STATUS                     PORTS                                   NAMES
aab96b8ed891   20e88a71ac1a                  "/ros_entrypoint.sh …"   9 hours ago    Exited (1) 9 hours ago                                             ros

컨테이너 지우기 (해당 Container ID로 지울 수 있다)

docker rm aab96

만약 컨테이너가 안지워지고 사용하고 있다거나 image 관련된 에러라면 image도 지워줄 수도 있다

docker images

결과가 아래처럼 나와서

REPOSITORY                    TAG                       IMAGE ID       CREATED         SIZE
docker-ros_ros                latest                    08e142c2e2bb   4 minutes ago   3.14GB
<none>                        <none>                    20e88a71ac1a   23 hours ago    2.99GB

none을 지우고 싶으면

docker image rm 20e88a

image나 container를 삭제할 떄는 ID번호를 다 안 적어줘도 되고
유니크한 id가 겹치지 않는 선까지만 입력해주면 된다. 대개 4자리 정도면 문제 없는 듯

다시 docker-compose build로 실행해본다

진짜 끝.

댓글

댓글이 없습니다.