ros2_control 구조: 하드웨어 인터페이스와 컨트롤러 매니저를 연결하는 방법

ros2_control은 로봇 드라이버와 제어기를 state interface·command interface로 분리하고, Controller Manager가 자원 소유권과 read–update–write 주기를 관리하게 합니다. 연결 실패를 찾으려면 URDF 선언부터 실제 인터페이스 노출까지 같은 이름과 주기로 이어지는지 확인해야 합니다.

아래에서는 용어의 차이를 실제 시스템 경계, 실패 조건과 검증 순서로 나눠 살펴봅니다.

ros2_control은 제어기가 하드웨어 드라이버를 직접 알지 않게 만든다

ros2_control의 목적은 모터 버스와 센서 드라이버의 세부 구현을 제어기에서 떼어내는 것입니다. 기존의 ROS 2 실시간 제어 글이 실시간 루프와 비실시간 노드의 경계를 다뤘다면, 이 글은 그 루프 안에서 상태와 명령이 어떤 인터페이스를 거쳐 오가는지 설명합니다.

제어기는 joint/position 같은 이름의 상태를 읽고 joint/velocity 같은 이름의 명령을 씁니다. 실제 CAN·EtherCAT·시리얼 통신은 하드웨어 플러그인이 맡으므로, 같은 제어기를 실물·모의 하드웨어·시뮬레이터에 재사용할 수 있습니다.

전체 구조는 하드웨어 컴포넌트·Resource Manager·Controller Manager로 나뉜다

하드웨어 컴포넌트는 장치와 통신하며 state interface와 command interface를 내보냅니다. Resource Manager는 이 컴포넌트를 로드하고 수명주기와 인터페이스 목록을 관리하며, Controller Manager는 제어기를 로드해 필요한 인터페이스를 배정합니다.

따라서 연결 문제는 한 파일에서 끝나지 않습니다. URDF의 ros2_control 태그, pluginlib 클래스, 드라이버가 실제로 export한 이름, 제어기 YAML의 요청 이름, 활성화 순서를 이어서 봐야 어느 경계에서 끊겼는지 찾을 수 있습니다.

read–update–write가 한 제어 주기를 만든다

ros2_control 공식 아키텍처 문서는 Controller Manager의 update 경로를 하드웨어 읽기, 활성 제어기 갱신, 하드웨어 쓰기로 설명합니다. 이 순서가 일정한 주기로 반복돼야 입력 시점과 출력 적용 시점이 예측 가능합니다.

read가 늦으면 제어기는 오래된 상태를 사용하고, update가 길어지면 다음 주기를 침범하며, write가 실패하면 계산된 명령이 액추에이터에 도달하지 않습니다. 평균 주기뿐 아니라 각 단계의 최악 지연과 연속 실패 횟수를 따로 기록해야 합니다.

단계데이터 방향대표 실패
read하드웨어 → state통신 지연·오래된 값
updatestate → controller → command계산 초과·NaN
writecommand → 하드웨어버스 오류·장치 거부
진단루프 → 운영 로그오류 은폐·시간축 불일치

state interface와 command interface는 읽기·쓰기 권한이 다르다

공식 하드웨어 인터페이스 문서에서 joint의 state interface는 측정 상태를, command interface는 하드웨어에 줄 목표를 표현합니다. position·velocity·effort가 흔하지만 프레임워크는 장치에 맞는 이름도 선언할 수 있습니다.

같은 문자열을 쓴다고 의미가 자동으로 같아지는 것은 아닙니다. 라디안과 도, Nm와 전류, 모터축과 출력축처럼 단위·부호·기준축이 다를 수 있으므로 인터페이스 계약에 물리 의미와 유효 범위를 함께 적어야 합니다.

URDF의 ros2_control 태그는 실행 가능한 인터페이스 계약이다

URDF에는 하드웨어 컴포넌트 유형, 플러그인 클래스, joint·sensor·gpio 이름과 각 state·command interface를 선언합니다. 여기의 joint 이름은 로봇 모델에 존재해야 하고 제어기 설정이 요청하는 이름과도 일치해야 합니다.

URDF 파싱 성공만으로 연결을 완료했다고 볼 수 없습니다. 드라이버가 초기화 뒤 실제로 같은 인터페이스를 export했는지, 초기값과 제한이 적용됐는지, 전원이 없는 상태에서 읽기 값이 유효한지까지 런타임 목록으로 확인해야 합니다.

Controller Manager는 제어기 수명주기와 인터페이스 배정을 함께 관리한다

Controller Manager 공식 문서는 제어기 로드·구성·활성화와 하드웨어 인터페이스 접근을 핵심 역할로 둡니다. 구성 단계에서는 파라미터와 요청 인터페이스를 준비하고, 활성화 단계에서 실제 command interface를 차지합니다.

로드됐지만 inactive인 제어기는 명령을 내리지 않습니다. 반대로 active 표시는 있는데 출력이 없다면 요청 인터페이스, 제어기 update 반환값, command 값, write 결과를 순서대로 추적해야 상태 표시만 보고 원인을 오판하지 않습니다.

command interface는 동시에 두 제어기가 차지할 수 없다

위치·속도·토크 모드의 물리적 차이는 관절 제어 3중 루프 글에서 설명했습니다. ros2_control에서는 이 모드를 누가 계산하는가와 별개로 같은 command interface의 배타적 소유권이 충돌하지 않아야 합니다.

예를 들어 trajectory controller와 수동 velocity controller가 같은 joint/velocity를 동시에 요구하면 한쪽을 활성화할 수 없습니다. 안전한 전환은 새 제어기의 준비, 기존 제어기의 해제, 새 인터페이스 claim, 초기 명령 정렬을 하나의 전환 절차로 검증해야 합니다.

하드웨어 컴포넌트 유형은 Actuator·Sensor·System으로 구분한다

Actuator는 한 구동 장치, Sensor는 명령 없이 상태만 내는 장치, System은 여러 joint와 센서를 한 통신 단위로 묶는 경우에 적합합니다. 실제 구분은 부품 외형이 아니라 한 번에 초기화·읽기·쓰기·오류 처리해야 하는 경계로 정합니다.

여러 장치를 한 System에 묶으면 동기화와 버스 처리는 쉬워질 수 있지만 한 장치 오류가 전체를 멈출 수 있습니다. 반대로 지나치게 쪼개면 상태 일관성과 재시작 순서가 어려워지므로 ROS 2·DDS 보안 경계처럼 장애와 권한의 전파 범위도 함께 봐야 합니다.

주기 설정은 update_rate 숫자 하나로 보장되지 않는다

Controller Manager의 update_rate는 목표 반복 빈도입니다. 실제 주기는 드라이버 read·write 시간, 제어기 계산량, 운영체제 스케줄링, 메모리 할당과 통신 재시도 때문에 흔들릴 수 있습니다.

검증할 때는 목표 주기 대비 평균·최대·백분위 지연, missed cycle, read/write 오류와 장치별 timestamp를 함께 남깁니다. 느린 센서를 제어 루프와 같은 속도로 강제할지, 다른 갱신률이나 비동기 실행으로 분리할지도 데이터 신선도 요구에서 결정합니다.

연결 실패는 이름·상태·소유권·주기 순서로 좁힌다

첫째 URDF와 런타임 인터페이스 목록의 이름을 비교하고, 둘째 하드웨어 컴포넌트와 제어기의 수명주기 상태를 봅니다. 셋째 claimed 상태와 활성 제어기를 확인하고, 넷째 read–update–write 값과 시간을 추적합니다.

이 순서는 제어 알고리즘을 바꾸기 전에 구조적 오류를 제거합니다. 특히 joint 이름 오타, command interface 미노출, inactive 하드웨어, 기존 제어기의 소유권 잔류는 제어 게인을 조정해도 해결되지 않습니다.

하드웨어 컴포넌트와 Resource Manager, Controller Manager, 제어기가 상태와 명령 인터페이스로 연결되는 흐름
하드웨어는 상태를 내보내고 명령을 받아들입니다. Controller Manager는 두 인터페이스의 연결과 제어기 수명주기를 함께 관리합니다. 출처: 피지컬 AI Lab.

통합 시험은 모의 하드웨어에서 실물 부하까지 단계적으로 올린다

먼저 mock component로 인터페이스 이름과 제어기 상태 전이를 검증하고, 다음으로 전원 제한 상태에서 단일 joint의 read/write를 확인합니다. 이후 여러 축 동기 동작과 통신 장애, 마지막으로 실제 하중과 안전 정지를 넣습니다.

각 단계의 합격 기준은 활성화 성공만이 아닙니다. 상태 값 범위, command 제한, 오류 반환, 정지 뒤 재활성화, 로그 시간축과 인터페이스 소유권이 예상대로 복구되는지를 포함해야 반복 운용 가능한 통합이 됩니다.

단계시험 대상통과 기준
1. 모의이름·제어기 구성load·configure·activate
2. 단일축read/write·부호·단위명령과 측정 일치
3. 다축주기·자원 전환충돌·missed cycle 없음
4. 경계버스 오류·정지·재시작안전 상태와 복구 확인

운영 인수 기준은 제어 성능과 인터페이스 건전성을 분리한다

추종 오차가 작아도 인터페이스 오류가 간헐적으로 누락되거나 주기 지터가 커지면 현장 안정성은 낮습니다. 반대로 연결이 완전해도 제어기 설계와 게인이 작업 요구를 충족하지 못할 수 있으므로 두 층의 지표를 분리해야 합니다.

TF2 좌표계 점검과 함께 joint 이름·축 방향·timestamp를 인수 문서에 고정하고, 소프트웨어 업데이트 뒤 동일한 인터페이스 목록과 전환 시험을 재실행하면 드라이버 교체가 제어기까지 조용히 번지는 일을 줄일 수 있습니다.

ros2_control의 URDF 이름과 플러그인, 상태 명령 인터페이스, 제어기 활성화를 확인하는 표
제어기가 활성화되지 않을 때는 알고리즘보다 선언과 실제 노출 값의 일치부터 확인하는 편이 빠릅니다. 출처: 피지컬 AI Lab.

ros2_control 구조에서 자주 묻는 질문

ros2_control이 모터 드라이버인가요?

아닙니다. 하드웨어 드라이버와 제어기를 연결하는 프레임워크입니다. 실제 버스 통신은 하드웨어 플러그인이 담당합니다.

state interface와 command interface의 가장 큰 차이는 무엇인가요?

state는 측정 상태를 읽는 경로이고 command는 하드웨어에 적용할 목표를 쓰는 경로입니다. 이름뿐 아니라 단위와 기준축도 맞아야 합니다.

제어기가 loaded인데 로봇이 움직이지 않는 이유는 무엇인가요?

loaded·configured·active는 다른 상태입니다. 활성 상태, command interface claim, update 결과와 write 성공 여부를 차례로 확인해야 합니다.

여러 제어기를 동시에 활성화할 수 있나요?

서로 다른 command interface를 사용하거나 허용된 체인을 구성하면 가능합니다. 같은 command interface를 동시에 배타적으로 차지할 수는 없습니다.

update_rate만 맞추면 실시간 제어가 되나요?

아닙니다. read·update·write의 최악 지연과 지터, 운영체제 스케줄링, 메모리와 통신 실패까지 함께 관리해야 합니다.

이 글은 2026년 7월 공개된 ros2_control 공식 문서를 기준으로 구조와 진단 원리를 설명합니다. 배포판별 API와 파라미터 차이는 사용 중인 ROS 2 배포판 문서를 다시 확인해야 합니다.