편찌

myCobot 280 완전 정복 #2 — Docker로 ROS2 환경 구축하기 (Windows/macOS/Linux 전부 OK)

myCobot 280 완전 정복 시리즈

지난 글에서 myCobot 280 M5를 USB, WiFi, BLE로 연결하는 방법을 다뤘는데, 이번에는 한 단계 올라가서 ROS2 (Robot Operating System 2)로 교육용 로봇팔을 제어해보려고 한다.

근데 문제가 하나 있다. mycobot_ros2 패키지는 ROS2 Humble (Ubuntu 22.04)만 지원하는데, 나는 Ubuntu 24.04를 쓰고 있었다. Ubuntu 24.04의 ROS2는 Jazzy인데, mycobot_ros2가 Jazzy를 아직 지원 안 한다. 그래서 Docker로 해결했다.

Docker를 쓰면 Windows, macOS, Linux 어디서든 동일한 ROS2 환경을 구축할 수 있어서, OS 호환성 문제를 깔끔하게 해결할 수 있다. 이번 글에서는 Docker 기반 ROS2 환경 구축부터 RViz2 시각화, 슬라이더/키보드 제어, MoveIt2 모션 플래닝까지 전부 다뤄본다.

왜 Docker인가?

mycobot_ros2의 ROS2 호환성 표를 보면 이유가 바로 나온다:

브랜치ROS2 배포판Ubuntu
foxyROS2 Foxy20.04
humble (기본)ROS2 Humble22.04

Ubuntu 24.04에서 Humble을 네이티브로 설치하면 의존성 충돌이 터진다. Docker를 쓰면 호스트 OS가 뭐든 상관없이 컨테이너 안에서 Ubuntu 22.04 + ROS2 Humble 환경이 돌아간다.

크로스 플랫폼 지원:

  • Linux: Docker Engine 직접 설치 → X11 포워딩으로 GUI 표시
  • Windows: Docker Desktop + WSL2 → VcXsrv나 WSLg로 GUI
  • macOS: Docker Desktop → XQuartz로 X11 포워딩

이 글은 Linux(Ubuntu 24.04) 기준으로 작성했지만, Docker 설치 부분만 OS에 맞게 바꾸면 Windows나 macOS에서도 동일하게 동작한다.

아키텍처 개요

+--------------------------------------------------+
|  호스트 (Ubuntu 24.04 / Windows / macOS)          |
|                                                    |
|  +----------------------------------------------+ |
|  |  Docker 컨테이너 (Ubuntu 22.04)               | |
|  |                                                | |
|  |  ROS2 Humble + mycobot_ros2 + MoveIt2         | |
|  |  + Gazebo + RViz2                              | |
|  +----------------------------------------------+ |
|       |            |              |                 |
|  /dev/ttyACM0   X11 Socket    Host Network         |
|  (시리얼통신)   (GUI 표시)    (ROS2 통신)           |
+--------------------------------------------------+

핵심 포인트 3가지:

  • 시리얼 패스스루: /dev/ttyACM0을 컨테이너에 매핑하여 실제 로봇팔과 통신
  • X11 포워딩: RViz2, Gazebo 같은 GUI가 호스트 화면에 표시
  • Host 네트워크: ROS2 DDS 멀티캐스트 통신이 그대로 동작

준비물

  • myCobot 280 교육용 로봇팔 + USB 케이블
  • Docker 설치된 PC (Linux/Windows/macOS)
  • X11 서버: Linux는 기본 포함, Windows는 VcXsrv/WSLg, macOS는 XQuartz

시리얼 포트 확인 방법1편의 환경 세팅 섹션에서 OS별(macOS/Linux/Windows) 포트 확인 명령어를 정리해뒀다. 처음이면 그쪽 먼저 보고 오는 걸 추천한다.

프로젝트 구조

mycobot280_ros2/
├── Dockerfile              # ROS2 Humble + mycobot_ros2 이미지
├── docker-compose.yml      # 컨테이너 실행 설정
├── entrypoint.sh           # 자동 환경 설정 스크립트
├── run.sh                  # 원클릭 실행 (Linux)
├── workspace/              # 커스텀 ROS2 패키지 마운트
└── devcontainer/           # VS Code Dev Container 설정
    └── .devcontainer/
        ├── Dockerfile
        ├── devcontainer.json
        └── setup.sh

실행 방법이 2가지다: docker-compose (CLI)VS Code Dev Container. 취향에 따라 골라 쓰면 된다.

방법 1: Docker Compose로 실행 (CLI)

Dockerfile

FROM ros:humble

ENV DEBIAN_FRONTEND=noninteractive

# ROS2 + MoveIt2 + Gazebo + 필수 패키지 설치
RUN apt-get update && apt-get install -y \
    python3-pip python3-colcon-common-extensions \
    ros-humble-rviz2 ros-humble-xacro \
    ros-humble-gazebo-ros-pkgs ros-humble-moveit \
    ros-humble-ros2-control ros-humble-ros2-controllers \
    ros-humble-moveit-servo git wget vim \
    && rm -rf /var/lib/apt/lists/*

# pymycobot 설치
RUN pip3 install pymycobot

# mycobot_ros2 클론 & 빌드
RUN mkdir -p /ros2_ws/src
WORKDIR /ros2_ws/src
RUN git clone -b humble --depth 1 \
    https://github.com/elephantrobotics/mycobot_ros2.git

WORKDIR /ros2_ws
RUN . /opt/ros/humble/setup.sh && \
    colcon build --symlink-install 2>&1 || \
    colcon build --symlink-install \
    --packages-skip warehouse_ros_mongo 2>&1 || true

# 자동 소싱
RUN echo "source /opt/ros/humble/setup.bash" >> /root/.bashrc && \
    echo "source /ros2_ws/install/setup.bash" >> /root/.bashrc

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["bash"]

docker-compose.yml

services:
  mycobot:
    build: .
    container_name: mycobot_ros2
    privileged: true
    network_mode: host
    stdin_open: true
    tty: true
    environment:
      - DISPLAY=${DISPLAY}
      - QT_X11_NO_MITSHM=1
      - ROS_DOMAIN_ID=0
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix:rw
      - /dev:/dev
      - ./workspace:/ros2_ws/custom:rw
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    command: bash

빌드 & 실행

# 이미지 빌드 (첫 빌드 10~20분)
docker compose build

# X11 포워딩 허용 + 컨테이너 실행
xhost +local:docker
docker compose up -d
docker exec -it mycobot_ros2 bash

또는 run.sh 하나로 끝:

./run.sh

방법 2: VS Code Dev Container (추천)

VS Code를 쓴다면 Dev Container가 훨씬 편하다. devcontainer/ 폴더를 VS Code로 열면 자동으로 Docker 환경이 구축되고, 터미널, IntelliSense, 디버깅까지 전부 컨테이너 안에서 동작한다.

myCobot 280 VS Code Dev Container ROS2 빌드 화면
VS Code Dev Container에서 ROS2 환경 자동 빌드 중
  1. VS Code에서 Remote – Containers 확장 설치
  2. devcontainer/ 폴더를 VS Code로 열기
  3. 좌측 하단 초록색 버튼 → “Reopen in Container” 클릭
  4. 자동 빌드 후 컨테이너 안에서 개발 시작

빌드가 끝나면 터미널에 이런 메시지가 뜬다:

============================================
  myCobot 280 ROS2 Dev Container Ready
============================================

  Robot port: /dev/ttyACM0

  Quick start:
    ros2 launch mycobot_280 slider_control.launch.py port:=/dev/ttyACM0
    ros2 launch mycobot_280_moveit2 demo.launch.py

ROS2로 로봇팔 제어하기

컨테이너에 들어갔으면 이제 진짜 재미있는 부분이다. 교육용 로봇팔을 ROS2로 제어해보자.

슬라이더 제어 — RViz2 + GUI

ros2 launch mycobot_280 slider_control.launch.py port:=/dev/ttyACM0
myCobot 280 RViz2 슬라이더 GUI 로봇팔 제어
RViz2 + 슬라이더 GUI로 교육용 로봇팔 관절 제어

RViz2에 로봇 3D 모델이 뜨고, 옆에 슬라이더 GUI가 나온다. 슬라이더를 움직이면 실제 로봇팔이 따라 움직인다. 이게 제일 직관적이고 처음 테스트할 때 좋다.

키보드 제어 — teleop_keyboard

myCobot 280 ROS2 키보드 제어 teleop keyboard 터미널
teleop_keyboard로 로봇팔 키보드 제어 — 터미널 + RViz2 화면

터미널 2개가 필요하다:

# 터미널 1 — RViz2 + 로봇 연결
ros2 launch mycobot_280 teleop_keyboard.launch.py port:=/dev/ttyACM0

# 터미널 2 — 키보드 입력 (별도 실행 필요!)
ros2 run mycobot_280 teleop_keyboard
myCobot 280 RViz2 키보드 제어 터미널
키보드로 로봇팔을 제어하면서 RViz2에서 실시간 시각화
기능
W / Sx축 전진 / 후진
A / Dy축 좌 / 우
Z / Xz축 상승 / 하강
G / H그리퍼 열기 / 닫기
+ / –속도 증가 / 감소
myCobot 280 teleop keyboard 키보드 제어 터미널 실행 화면
teleop_keyboard 노드 실행 화면 — 키 매핑과 현재 상태 표시

주의할 점: teleop_keyboard.launch.py에 키보드 노드가 포함 안 되어 있어서 터미널 2에서 별도로 실행해야 한다. 이거 몰라서 처음에 왜 키보드가 안 먹히나 한참 삽질했다.

MoveIt2 — 모션 플래닝

MoveIt2는 로봇팔의 모션 플래닝 프레임워크다. 목표 위치를 설정하면 충돌 회피 경로를 자동으로 계산해준다.

# 시뮬레이션 모드 (로봇 없이도 됨)
ros2 launch mycobot_280_moveit2 demo.launch.py
myCobot 280 MoveIt2 RViz2 모션 플래닝
MoveIt2로 모션 플래닝 — RViz2에서 인터랙티브 마커로 목표 자세 설정

RViz2에서 인터랙티브 마커를 드래그 → Plan 클릭 → Execute로 실행.

MoveIt2로 경로 계획 후 실제 myCobot 280 로봇팔이 움직이는 모습

위 영상은 MoveIt2에서 Plan & Execute한 궤적을 실제 교육용 로봇팔에 전달해서 움직이는 모습이다. RViz2 화면의 스크린캐스트와 동시에 촬영한 거라 싱크가 맞는다.

실제 로봇에 적용하려면 별도 터미널에서 sync_plan 노드를 실행하면 MoveIt2 궤적이 실제 로봇에 전달된다.

Windows / macOS에서 실행하기

Docker는 크로스 플랫폼이라 Linux가 아니어도 동일하게 동작한다. GUI 표시 부분만 다르다.

Windows

  1. Docker Desktop 설치 (WSL2 백엔드)
  2. GUI: WSLg(Windows 11)면 자동 동작. Windows 10이면 VcXsrv 설치 후 DISPLAY 설정
  3. 시리얼: WSL2에서 usbipd로 USB 장치를 WSL에 연결 usbipd bind --busid <BUS-ID> usbipd attach --wsl --busid <BUS-ID>

macOS

  1. Docker Desktop 설치
  2. GUI: XQuartz 설치 후 xhost + 127.0.0.1
  3. 시리얼: macOS Docker에서 USB 시리얼 패스스루가 까다로움. socat으로 TCP 브릿지하거나, pymycobot의 WiFi 연결(MyCobot280Socket) 사용 추천

전체 Launch 파일 목록

Launch 파일포트 필요용도
test.launch.pyO연결 테스트
slider_control.launch.pyO슬라이더 GUI 관절 제어
simple_gui.launch.pyOTkinter GUI 좌표/관절 제어
teleop_keyboard.launch.pyO키보드 제어
test_gripper.launch.pyO그리퍼 테스트
demo.launch.py (moveit2)XMoveIt2 시뮬레이션

포트 필요한 파일 실행 시: ros2 launch <패키지> <파일> port:=/dev/ttyACM0

Docker 빌드 시간 최적화 팁

첫 빌드가 오래 걸리는 게 싫다면 몇 가지 팁이 있다:

  • BuildKit 캐시 활용: DOCKER_BUILDKIT=1 docker compose build로 빌드하면 레이어 캐싱이 더 효율적
  • 멀티스테이지 빌드: 빌드 도구와 런타임을 분리하면 최종 이미지 크기가 줄어듦
  • .dockerignore 활용: 불필요한 파일이 빌드 컨텍스트에 포함되지 않도록
  • 재빌드 시 변경 최소화: Dockerfile에서 자주 바뀌는 부분을 아래쪽에 배치하면 캐시 히트율이 올라감

참고로 docker compose build --no-cache로 캐시를 완전히 무시하고 빌드할 수도 있는데, 이건 정말 필요할 때만 쓰자. 시간 오래 걸린다.

Docker 컨테이너에서 pymycobot으로 직접 제어

ROS2 launch 파일 말고도, 컨테이너 안에서 Python으로 직접 로봇을 제어할 수 있다. 빠른 테스트나 커스텀 스크립트 작성할 때 유용하다.

# Docker 컨테이너 내부에서 실행
python3 -c "
from pymycobot.mycobot280 import MyCobot280
import time

mc = MyCobot280('/dev/ttyACM0', 115200)
time.sleep(2)

# 현재 관절 각도 확인
print('현재 각도:', mc.get_angles())

# 홈 포지션으로 이동
mc.send_angles([0, 0, 0, 0, 0, 0], 50)
time.sleep(3)

# LED 초록색으로 변경 (동작 확인)
mc.set_color(0, 255, 0)
print('완료!')
"

ROS2 토픽으로 상태 모니터링도 동시에 가능하다:

# 터미널 1: pymycobot으로 로봇 제어
# 터미널 2: ROS2 토픽 모니터링
ros2 topic list                    # 활성 토픽 목록
ros2 topic echo /joint_states      # 실시간 관절 상태

드래그 티칭 — 궤적 녹화 & 재생

교육용 로봇팔의 큰 장점 중 하나가 드래그 티칭이다. 사람이 직접 로봇팔을 손으로 움직여서 동작을 기록하고, 그대로 재생할 수 있다. M5Stack의 Record & Play 기능도 있지만, Python 코드로 하면 파일 저장, 반복 재생, 조건 분기 등 활용 범위가 훨씬 넓다.

궤적 녹화

from pymycobot.mycobot280 import MyCobot280
import json, time

mc = MyCobot280('/dev/ttyACM0', 115200)
time.sleep(2)

# 녹화 시작 — 이때 로봇 팔을 손으로 움직이세요!
print("녹화 시작! 로봇 팔을 자유롭게 움직이세요...")
mc.start_trajectory_recording()
time.sleep(10)  # 10초간 녹화

# 녹화 종료 & 데이터 추출
mc.end_trajectory_recording()
data = mc.get_trajectory_list()
print(f"녹화 포인트 수: {len(data)}")

# JSON으로 저장
with open('/ros2_ws/custom/my_trajectory.json', 'w') as f:
    json.dump(data, f)
print("저장 완료!")

궤적 재생

from pymycobot.mycobot280 import MyCobot280
import json, time

mc = MyCobot280('/dev/ttyACM0', 115200)
time.sleep(2)

# 저장된 궤적 불러와서 재생
with open('/ros2_ws/custom/my_trajectory.json', 'r') as f:
    data = json.load(f)

print("재생 시작...")
for point in data:
    mc.set_encoders_drag(point[0], point[1])
    time.sleep(point[2])
print("재생 완료!")

이 드래그 티칭 데이터는 나중에 LeRobot / 모방학습(Imitation Learning)의 학습 데이터로도 활용할 수 있다. 카메라 영상과 함께 수집하면 Vision-Language-Action 모델 훈련에도 쓸 수 있는데, 이건 다음 글에서 다룰 예정이다.

트러블슈팅

증상원인해결
GUI 창이 안 뜸X11 포워딩 미설정xhost +local:docker 실행
시리얼 포트 접근 불가권한 문제sudo chmod 666 /dev/ttyACM0
RViz2 렌더링 깨짐Intel GPU OpenGL 문제LIBGL_ALWAYS_SOFTWARE=1 환경변수 추가
simple_gui 글씨 깨짐 (□□)CJK 폰트 없음apt install fonts-noto-cjk
teleop_keyboard 키 안 먹힘키보드 노드 미실행별도 터미널에서 ros2 run mycobot_280 teleop_keyboard
tkinter import 에러python3-tk 미설치apt install python3-tk
실제 동작 데모 — RViz2 + 키보드로 교육용 로봇팔 제어

자주 묻는 질문 (FAQ)

myCobot 280에 ROS2를 반드시 써야 하나요?

아니다. pymycobot만으로도 Python에서 직접 제어할 수 있다 (1편 참고). ROS2는 MoveIt2 모션 플래닝, Gazebo 시뮬레이션, 다른 ROS2 노드와의 통합이 필요할 때 쓰면 된다. 교육용 로봇으로 ROS2를 배우기에는 myCobot 280이 가성비가 좋은 편이다.

Docker 없이 Ubuntu 24.04에서 ROS2 Humble을 쓸 수 있나요?

공식적으로는 안 된다. ROS2 Humble은 Ubuntu 22.04용이라 24.04에 직접 설치하면 의존성 충돌이 발생한다. Docker를 쓰거나, Ubuntu 22.04를 듀얼부팅/VM으로 설치하거나, ROS2 Jazzy를 기다리는 수밖에 없다. Docker가 가장 깔끔한 해결책이다.

Windows에서도 RViz2 GUI가 표시되나요?

된다. Windows 11이면 WSLg가 기본 내장이라 별도 X서버 없이 GUI가 뜬다. Windows 10이면 VcXsrv를 설치해야 한다. Docker Desktop + WSL2 백엔드 조합으로 RViz2, Gazebo 모두 정상 동작한다.

macOS에서 시리얼 포트(USB) 연결이 안 돼요

macOS Docker에서 USB 시리얼 패스스루가 네이티브로 지원되지 않는다. 해결 방법은 두 가지: (1) socat으로 TCP 브릿지를 만들거나, (2) pymycobot의 WiFi 연결(MyCobot280Socket)을 사용하면 케이블 없이도 로봇을 제어할 수 있다.

Docker 이미지 빌드가 너무 오래 걸려요

첫 빌드에 10~20분 정도 걸린다. ROS2 Humble 베이스 이미지 + MoveIt2 + Gazebo 패키지가 많아서 그렇다. 두 번째부터는 Docker 레이어 캐싱 덕분에 변경된 부분만 빌드되니까 훨씬 빠르다. 인터넷 속도가 느리면 더 걸릴 수 있다.

MoveIt2에서 계획한 궤적을 실제 로봇에 어떻게 보내나요?

별도 터미널에서 ros2 run mycobot_280_moveit2_control sync_plan을 실행하면 된다. 이 노드가 MoveIt2의 joint_states 토픽을 구독해서 pymycobot를 통해 실제 로봇에 전달한다. 라디안→도 변환도 자동으로 처리된다.

마무리 & 앞으로의 방향

이번 글에서는 Docker로 OS 제약 없이 교육용 로봇팔 myCobot 280을 ROS2 Humble 환경에서 제어하는 방법을 정리했다. CLI(docker-compose)와 VS Code Dev Container 두 가지 방법 모두 다뤘고, RViz2 시각화, 슬라이더/키보드 제어, MoveIt2 모션 플래닝까지 확인했다.

Docker 기반이라 Windows, macOS, Linux 어디서든 동일한 환경을 구축할 수 있다는 게 가장 큰 장점이다. 특히 ROS2는 설치가 까다로운 편인데, Docker로 한 방에 해결되니까 교육용 로봇 입문할 때 이 방법이 제일 깔끔한 것 같다.

여기서 더 확장할 수 있는 방향도 엄청 많다:

  • Gazebo 시뮬레이션 — 실제 로봇 없이 가상 환경에서 테스트
  • 카메라 + OpenCV — Docker에 카메라 디바이스 패스스루해서 비전 파이프라인
  • 커스텀 ROS2 패키지 — workspace/ 폴더에 자신만의 제어 노드 개발
  • 드래그 티칭 — pymycobot으로 궤적 녹화/재생
  • LeRobot 연동 — ROS2 rosbag 데이터 → LeRobot 데이터셋으로 변환 → 모방학습
  • 멀티 로봇 — ROS_DOMAIN_ID 분리해서 여러 로봇 동시 제어

다음 글에서 뭘 다룰지는 아직 정확히 안 정했는데, 하나씩 진행하면서 공유할 예정이다. 관심 있으면 지켜봐주세요!


myCobot 280 완전 정복 시리즈

#1 — USB, WiFi, Bluetooth 3가지 연결 방법 총정리

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다