[모두의연구소]docker에 ros2설치

ROSI·2023년 7월 6일
0

with_RL_study

목록 보기
2/4

0.docker

Docker를 사용하면 애플리케이션을 호스트 시스템과 분리된 컨테이너 내에서 실행할 수 있다. 이는 개발 환경과 프로덕션 환경 간의 일관성을 유지하면서 컨테이너를 다른 환경에 쉽게 배포할 수 있음을 의미한다.

  • Docker는 컨테이너화된 애플리케이션을 구축, 배포 및 실행하기 위한 오픈 소스 플랫폼이다.
  • 컨테이너는 애플리케이션과 그의 종속성을 격리된 환경으로 패키징하는 가상화 단위이다. Linux 커널을 기반으로 하는 기술이다.
  • Docker 이미지를 사용하여 Docker 컨테이너를 생성하고 실행한다.
  • 이미지는 컨테이너의 파일 시스템, 라이브러리, 애플리케이션 코드, 종속성 및 설정을 포함할 수 있다.

0.1. image vs container

도커 이미지

  • 정적인 패키지이다.
  • 읽기 전용이며, 여러 개의 컨테이너를 생성할 수 있다.
  • 빌드 단계에서 생성되며, Dockerfile이나 커맨드를 사용하여 정의된다.
  • 도커 레지스트리(docker hub)에 저장되거나 공유할 수 있습니다.
    도커 컨테이너
  • 이미지를 실행한 동적인 인스턴스이다.
  • 동작 중인 프로세스와 해당 프로세스가 실행되는 환경을 포함한다.
  • 이미지를 읽기 전용으로 가져오고, 해당 이미지 위에 쓰기 가능한 계층(layer)를 추가하여 변화를 저장한다.
  • 격리된 환경에서 실행되며, 자체 파일 시스템, 네트워크, 프로세스 공간을 갖는다.

0.2. linux가 아닌 host os에서

  • ex1.Windows의 경우, Hyper-V 기술을 사용하지 않는 "Windows Server Container"(windows 커널기능 사용)와 Hyper-V 가상화를 사용하는 "Hyper-V Container"(windows커널을 위한 hypervisor)가 있다.

  • ex2.macOS의 경우, Hyper-V 가상화를 사용하는Hypervisor.framework를 사용하여 가상화 환경을 생성한다.(macOS커널 을 위한 hypervisor) 컨테이너는 이 가상화 환경 내에서 실행된다.

  • ex3.그 외의 대부분의 os에서도 컨테이너 가상화를 지원한다.
    특정 OS에서 컨테이너를 사용하기 위해 해당 OS의 네이티브 가상화 기술이 적용된 컨테이너를 사용하기 싫다면 HyperKit, UTM, VirtualBox같은 가상머신에 컨테이너에 맞는 os를 설치하여 써야한다.

0.3.자주쓰는 명령어

// Download an image from a registry(docker hub)
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
// Docker에서 사용 가능한 이미지 목록을 표시
docker images
// Docker에서 이미지를 삭제
docker rmi [이미지 명]
// Docker에서 현재 실행 중인 컨테이너 목록을 표시
docker ps
//Remove one or more containers
docker rm [OPTIONS] CONTAINER [CONTAINER...]
// Create and run a new container from an image
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
// yml(yaml)파일을 사용하여 컨테이너 설정 및 실행하는 방법
https://docs.docker.com/compose/reference/
//Stop one or more running containers
docker stop [OPTIONS] CONTAINER [CONTAINER...]
//Start one or more stopped(Exited) containers
docker start [OPTIONS] CONTAINER [CONTAINER...]
// Execute a command in a running container
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

1.설치 간 발생 이슈

1.1.xterm에서 container측 gui data표현못하는 문제(docker가 x11 server와 연결되지 않음)

qt.qpa.xcb: could not connect to display host.docker.internal:0.0 에러 발생.

$: host , #: xterm
sol1: https://github.com/jozo/docker-pyqt5/issues/7
xhost +local:docker
실패
sol2: https://somatorio.org/en/post/running-gui-apps-with-docker/, https://github.com/moby/moby/issues/8710
// xquartz설치
https://www.xquartz.org/
//  XQuartz는 Mac OS에서 X11 애플리케이션을 실행하기 위한 별도의 서버및 클라이언트를 제공한다.
// application XQuartz실행
$: open -a XQuartz
// socat(소켓통신 명령어)을 사용하여 X11 포워딩.
// 호스트의 UNIX 도메인 소켓($DISPLAY)에서 XQuartz가 사용하고 있는(lsof -i :6000)TCP포트6000으로 연결한다.
$: socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
// docker container runing
$: docker-compose -f .\ros.yml up
//docker 터미널에 대화형으로 접근
$: docker exec -it ros-ros2 /bin/bash
해결

1.2.노드가 DDS프로토콜에서 검색되지 않는 문제

동일 터미널에서 노드1을 백그라운드 실행해놓고 rqt_graph로 확인해도 노드1이 안보였다. 노드간 토픽 전달문제 이전에 노드 자체가 DDS 프로토콜에서 검색이 안되는 것 같다.

m1칩은 arm64 아키텍쳐고, osrf/ros:humble-desktop-full은 linux/amd64전용이라서 문제가 생긴듯하다.

arm64 아키텍처를 지원하는 다른 image인 ros:humble를 pull하니까 잘된다.

2.설치

2.1.설치과정

// docker 설치
https://www.docker.com/
// xquartz 설치
https://www.xquartz.org/
// 호스트의 UNIX 도메인 소켓($DISPLAY. X11 client가 연결)에서 X11 server가 사용 중인(lsof -i :6000)tcp 6000번 port로 연결한다.
$: socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
// docker container runing
// Use -f to specify name and path of one or more Compose files.
$: docker-compose -f ./ros.yml up
// docker 터미널에 대화형으로 접근
$: docker exec -it ros-ros2 /bin/bash

apt update
// rqt
apt install ros-humble-rqt*
//turtlesim
apt install ros-humble-turtlesim
//demo_nodes_cpp
apt install ros-humble-demo-nodes-cpp

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
echo "export ROS_DOMAIN_ID=97" >> ~/.bashrc

** XQuartz
macOS에는 X11 클라이언트와 X11 서버가 없다.
XQuartz는 macOS용 X11 클라이언트 및 X11 서버를 모두 제공한다.
그래서 XQuartz를 설치한다.

** $DISPLAY
X11 클라이언트가 X11 서버로의 연결을 생성하기 위해서는 DISPLAY 환경 변수를 설정해야 한다.
이 환경변수는 hostname:displayNumber.screenNumber 형식으로 설정된다. hostname은 X11 서버의 호스트 이름이고, displayNumber는 X11 서버의 포트 번호이다. screenNumber는 선택적이며, 하나의 X11 서버에 여러 개의 화면이 있는 경우에 고려된다.
host.docker.internal은 Docker Desktop이나 Docker Desktop for Mac에서만 지원되는 기능이며, 호스트 시스템의 DISPLAY 환경 변수 값을 참조한다.
호스트 시스템에는 Xquartz에 의해 DISPLAY환경변수가 set되어있다.
하지만 macOS에서 Docker는 X11 클라이언트를 제공하지 않기때문에 X11 서버에 직접 접근할 수 없다.
그래서 소켓통신으로 x11 server가 연결된 6000번 포트로 전달시킨다.

2.2. ros.yml

# ports는 [host port]:[container port]로의 port forwarding이다.
# volumes은 [hist directory]:[container directory]로 연결한다.
# docker exec -it에서 stdin과 ptty를 사용한다.
그래서 명시적으로 stdin와 tty를 open한것으로 보인다.(할필요없어보임)
# entrypoint는 컨테이너가 시작될 때 실행되는 명령 또는 스크립트를 지정한다.(할필요없어보임)
name: ros 
services:
  ros2:
    image: ros:humble
    container_name: ros-ros2
    environment:
      DISPLAY: host.docker.internal:0.0
    ports:
      - "10000:10000"
    volumes:
      - "/Users/sdg/Documents/modu_study:/root/host_dir"
    stdin_open: true
    tty: true
    entrypoint: /bin/bash

ref

https://www.youtube.com/playlist?list=PLuHgQVnccGMDeMJsGq2O-55Ymtx0IdKWf

https://docs.docker.com/engine/reference/commandline/rmi/
https://docs.docker.com/compose/reference/
https://docs.ros.org/en/humble/
https://answers.ros.org/question/413576/nodes-cant-communicate-with-each-other-on-docker-macos/

http://with-rl.com/windows%EC%97%90%EC%84%9C-docker%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-ros2-gazebo-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/

https://hub.docker.com/_/ros/tags?page=2

https://answers.ros.org/question/413576/nodes-cant-communicate-with-each-other-on-docker-macos/?answer=413626#post-id-413626

https://ai-sinq.tistory.com/entry/ROS2%EC%99%80-DDS%EB%9E%80#article-3--dds:-communication-protocol-of-ros2

profile
https://songdaegeun.github.io/ 으로 블로그이전 중입니다

0개의 댓글