Part II: 로봇 소프트웨어 스택을 이해한다

Chapter 4: ROS 2는 어떻게 움직임이 되는가 — 노드에서 실제 컨트롤러까지

집필일: 2026-07-14 최종수정일: 2026-07-14

개요

ROS 2를 처음 설치하면 화면에는 node, topic, service, action이 보인다. 하지만 로봇은 topic이 있다고 움직이지 않는다. 계획 프로그램이 trajectory goal을 만들고, controller가 이를 시간에 따라 보간하며, hardware interface 또는 vendor driver가 명령을 제조사 프로토콜로 바꾸고, robot controller가 한계와 안전 상태를 검사한 뒤 drive에 전달해야 한다. 반대 방향에서는 encoder와 controller state가 network를 거쳐 joint state와 diagnostics로 올라온다. 이 왕복 경로의 어느 한 시점이라도 frame, unit, timestamp, command owner가 틀리면 “ROS는 연결됐는데 로봇은 안 움직이는” 상태가 된다.

ROS 2의 가치는 이 경로를 분리하고 관찰 가능하게 만드는 데 있다. 카메라, planner, gripper, arm driver가 서로 다른 process와 computer에 있어도 typed interface로 결합하고, command line과 visualization으로 state를 검사하며, bag으로 기록하고 재생할 수 있다. 반대로 한 대의 robot에 vendor 고유 기능 하나만 빠르게 시험한다면 direct SDK가 더 단순할 수 있다. 중요한 것은 ROS 2 사용 여부가 아니라 누가 frame, time, limit, watchdog, logging과 safety contract를 책임지는지 빠짐없이 정하는 것이다.

이 장은 raw code를 복사하지 않는다. 대신 새 arm이 들어왔을 때 packet이 지나가는 정확한 경로를 그리고, drive를 켜기 전에 discovery·QoS·TF·time·driver·controller를 검증하는 순서를 제공한다. motion planning과 IK, trajectory 생성은 (Chapter 5), simulator와 fake hardware에서 실제 순서를 연습하는 방법은 (Chapter 6–7)에서 이어진다. 제품과 배포판 상태는 2026-07-14 기준이다.

이 장을 읽고 나면... - node, DDS, topic, service, action, executor, QoS가 한 motion request에서 맡는 역할을 설명할 수 있다. - TF와 timestamp가 맞지 않을 때 Cartesian 명령이 왜 위험하거나 실패하는지 진단할 수 있다. - planner→MoveIt→trajectory controller→hardware interface→vendor controller→drive 경로를 그릴 수 있다. - ROS 2 stack과 direct vendor SDK architecture 중 과제에 맞는 것을 고르고 빠진 책임을 비교할 수 있다. - drive-disabled network test부터 작은 joint motion까지 단계별 bring-up gate와 stop condition을 작성할 수 있다.

1. ROS 2를 “운영체제”가 아니라 책임을 나누는 graph로 본다

ROS 2는 Linux를 대신하는 operating system도, physics simulator도, robot의 certified safety controller도 아니다. 여러 software component가 typed message와 discovery를 통해 통신하는 middleware 중심 framework다. node는 publisher, subscriber, service, action과 parameter를 가진 논리적 participant다. node 하나가 process 하나일 수도 있고, 여러 node를 같은 process에 composition할 수도 있다. executor는 callback을 언제 실행할지 결정한다. 따라서 topic frequency가 500 Hz로 보인다고 callback과 downstream control이 반드시 같은 deadline을 지킨다고 결론 내릴 수 없다 [2] [4].

ROS 1의 central master와 달리 ROS 2는 DDS 계열 middleware를 사용해 participant를 발견하고 data를 전달한다. application은 보통 rclcpprclpy를 보고, 그 아래 rcl과 RMW abstraction, DDS implementation, UDP/IP 또는 shared memory가 있다. 이 계층화 덕분에 type, tooling과 distributed graph를 공유할 수 있지만, middleware implementation과 QoS, operating system scheduling, network configuration이 behavior에 영향을 준다 [2].

새 robot을 받으면 먼저 graph를 문장으로 적는다. 예를 들어 “camera node가 image와 camera info를 publish하고, perception node가 object pose를 만들며, planner가 TF로 pose를 base frame에 바꾸고, MoveIt move_group이 trajectory를 만들어 joint trajectory controller action server에 보낸다. controller manager가 hardware interface를 통해 vendor driver에 joint command를 쓰고, robot controller가 drive에 적용한다.” 이 문장에 명시되지 않은 clock, limit, watchdog과 stop authority가 바로 audit 대상이다.

계층 주된 책임 이 계층이 보장하지 않는 것 확인할 artifact
Task/planner 목표 pose, grasp, sequence 결정 motor current, safety stop goal log, planning result, failure reason
ROS graph typed data, discovery, introspection, orchestration hard deadline, physical safety node/topic/action graph, QoS report
Controller layer trajectory interpolation, command/state interface vendor safety function, correct payload controller state, tolerance, update diagnostics
Hardware/driver ROS command를 vendor protocol로 변환 application risk assessment version tuple, interface list, watchdog behavior
Robot controller servo, limit, protective state, drive command 외부 fixture·tool hazard 전체 safety state, fault code, vendor log
Physical cell mount, guard, E-stop, human procedure software correctness 자동 보증 risk assessment, acceptance record
그림 4.1. Object pose가 timestamped TF, motion plan, 외부 action server, active controller, hardware interface, vendor controller를 거쳐 drive로 가고 state·diagnostic·action feedback이 되돌아오는 책임 경로. Cell stop과 vendor safety limit은 software goal path와 분리된다.

그림 4.1 — Object pose에서 drive까지의 왕복 packet flow와 독립 safety boundary. 원본 개념도.

2. Topic, service, action을 motion의 시간 규모에 맞춘다

ROS 2 topic은 stream을, service는 범위가 분명한 request–response interaction을, action은 feedback과 cancel을 가진 long-running goal을 담당한다 [1] [2]. Camera image, joint state, tactile packet은 topic에 자연스럽다. “현재 payload parameter를 읽어라”처럼 짧고 끝이 분명한 질의는 service가 맞다. 몇 초 동안 trajectory를 실행하며 progress를 받고 cancel해야 하는 motion은 action이 맞다. service call을 긴 motion에 쓰면 caller가 timeout과 partial execution을 어떻게 처리할지 불명확해진다.

Topic은 상태를 계속 흘려보내지만 delivery contract가 모두 같지 않다. QoS는 reliability, durability, history, depth, deadline, lifespan, liveliness 같은 policy를 조합한다. Camera와 같은 high-bandwidth sensor는 최신 frame이 중요한 경우 best-effort와 small queue가 맞을 수 있다. sparse configuration이나 command는 reliable이 자연스러울 수 있다. 그러나 publisher와 subscriber policy가 incompatible이면 graph에 이름이 보여도 data가 오지 않는다. “topic exists”와 “compatible sample arrives with acceptable age”를 별도 gate로 둔다.

Action도 한 겹이 아니다. 목표를 accept했는지, 실행 중 feedback이 오는지, cancel request를 controller가 언제 적용하는지, tolerance violation에서 어떤 result를 내는지 확인한다. ros2_control Joint Trajectory Controller는 action interface로 completion과 tolerance를 표현하고, 조건을 위반하면 abort와 hold behavior를 가진다. topic command mode는 action-level 완료와 tolerance result가 없으므로 첫 bring-up에는 action path가 더 관찰 가능하다 [9].

DDS discovery와 QoS만으로 hard real-time deadline이나 functional safety가 보장되지는 않는다 [2] [3] [4]. Determinism에는 bounded callback chain, executor behavior, memory allocation, kernel scheduling, CPU interference, NIC와 vendor controller timing이 함께 들어간다. 연구 논문의 response-time bound도 해당 scheduler와 reservation assumption이 배치 system에서 성립할 때 의미가 있다. QoS의 deadline policy는 missed-deadline event를 관찰하는 contract이지 motor deadline을 magically enforce하는 safety function이 아니다.

Interface 선택표

원하는 interaction 기본 interface 성공 증거 흔한 오용
30 Hz camera/state stream topic sample age, drop, queue가 KPI 안에 있음 reliable queue가 쌓여 오래된 frame 처리
one-shot parameter/query service bounded response와 명시적 error 몇 초 motion을 blocking service로 실행
trajectory/gripper sequence action accepted→feedback→result/cancel trace goal ID와 cancel 확인 없이 새 goal 겹침
hard servo loop vendor controller 또는 qualified real-time component measured worst-case timing과 fault behavior Python topic loop frequency를 servo guarantee로 해석

3. TF는 frame 이름 목록이 아니라 시간축을 가진 좌표 graph다

로봇 manipulation에는 적어도 world, base, arm links, flange, tool0/TCP, camera, object와 fixture frame이 있다. TF tree가 연결돼 있어도 axis convention, parent–child 방향, meter/radian unit, optical frame과 calibration version이 틀릴 수 있다. base→cameracamera→object를 조합해 base→object를 얻을 때 두 transform이 같은 유효 시간에 존재해야 한다.

TF는 time-indexed transform graph이므로 valid timestamp가 없는 frame name만으로는 Cartesian motion에 충분하지 않다 [5]. Camera frame이 시각적으로 맞아 보여도 image timestamp보다 늦은 joint state로 lookup하면 moving wrist camera에서 object pose가 흔들린다. “latest transform”을 편의상 요청하는 것은 sync error를 숨길 수 있다. command를 만들 때 사용한 image, robot state, transform stamp와 calibration ID를 episode에 함께 저장한다.

Static transform은 움직이지 않는다고 영원히 정확한 값이라는 뜻이 아니다. Camera mount가 충격을 받거나 tool을 교체하면 static publisher 값도 calibration revision과 함께 갱신해야 한다. 같은 frame name 아래 서로 다른 calibration을 silently 덮어쓰지 않는다. 개발 중에는 camera_v3 같은 이름보다 configuration hash와 기록을 쓰고, deployed graph에서는 single authority가 canonical frame을 publish하도록 한다.

ROS time에는 system time, monotonic/steady timing, simulation time이 섞일 수 있다. Simulation에서 /clockuse_sim_time을 쓰는 node와 wall clock node가 섞이면 timeout, TF extrapolation, bag replay가 이상해진다. Real cell에서는 computer clocks를 동기화하고 camera hardware timestamp가 어느 clock domain인지 문서화한다. Network time sync가 돼도 sensor exposure delay, driver buffering과 transport latency는 남는다. 따라서 timestamp agreement와 observation age를 둘 다 측정한다.

TF·시간 acceptance gate

  1. 모든 dynamic frame에 publisher가 하나인지 확인한다. 같은 child frame을 둘이 publish하면 즉시 blocker다.
  2. Home pose에서 base axes, tool approach axis, camera optical axes를 물리 표식과 비교한다.
  3. Known fixture point 세 개 이상을 camera와 robot으로 관측해 transform chain의 방향과 scale을 검증한다.
  4. 10분간 TF buffer의 oldest/latest stamp, joint state age, camera age와 lookup failure를 기록한다.
  5. Clock step 또는 bag replay에서 time jump가 발생할 때 controller와 timeout이 fail closed하는지 simulator에서 확인한다.
  6. Calibration file, TF publisher version과 URDF hash를 하나의 configuration ID로 저장한다.
그림 4.2. World–base–flange–TCP와 base–camera–object frame tree를 transform history와 함께 본다. Image·joint state·TF를 observation time t0에서 맞춘 경우와 image t0에 latest TF t1을 섞은 경우를 대비한다.

그림 4.2 — TF는 frame 이름 모음이 아니라 시간 history를 가진 graph다. 원본 개념도.

4. 배포판 선택은 최신 이름이 아니라 vendor matrix로 결정한다

Ubuntu와 ROS 2 distribution은 한 쌍으로 생각하되, robot driver가 그 조합을 실제 지원하는지 다시 본다. LTS가 길다고 모든 vendor package가 binary로 준비된 것은 아니다. README의 “ROS 2 supported” 한 줄 대신 hardware revision, controller firmware, Ubuntu, kernel, ROS distribution, RMW, driver tag, SDK/library, description package를 version tuple로 고정한다.

Jazzy는 Ubuntu 24.04를 대상으로 2029년 5월까지, Lyrical은 2031년 5월까지 지원을 목표로 하지만 실제 사용 가능한 ROS distribution은 vendor matrix가 결정한다 [6] [7] [12] [16]. 이 날짜와 matrix는 2026-07-14 기준이다. UR build-status page가 여러 branch를 보여도 exact firmware 조합을 모두 시험했다는 뜻은 아니다. Franka의 documented ROS 2 branch와 libfranka requirement가 다르면 최신 Ubuntu를 설치한 것이 오히려 integration blocker가 된다.

초심자에게는 “OS부터 설치하고 driver가 맞기를 바라는” 순서가 가장 비싸다. 먼저 vendor matrix와 repository release를 보고, container 또는 clean image에서 build와 mock hardware를 확인한 뒤 workstation image를 확정한다. 연구실 전체가 하나의 distribution을 써야 할 필요는 없지만, 한 physical cell의 production path에는 pinned golden image를 둔다. 새로운 distribution은 separate test machine에서 qualification한다.

결정 좋은 증거 부족한 증거 기록 위치
OS/ROS 조합 vendor release/CI와 공식 install 문서가 exact branch를 명시 forum 글 하나, 오래된 README cell manifest
SDK/driver changelog에 minimum version과 breaking change 있음 “latest” dependency lockfile/container digest
robot firmware driver docs가 호환 범위를 명시하고 vendor가 확인 robot model 이름만 일치 acceptance record
middleware RMW와 QoS profile을 test log에 기록 default라서 모름 launch configuration
rollback previous image와 config hash로 재현 가능 manual reinstall deployment SOP

5. DDS discovery와 robot network를 drive 없이 검증한다

ROS 2 graph가 보이지 않을 때 application code부터 고치지 않는다. 먼저 두 host가 같은 physical/logical network에 있고 IP, subnet, route, firewall, multicast/unicast discovery, ROS_DOMAIN_ID, localhost-only setting과 RMW implementation이 맞는지 확인한다. VPN, Wi-Fi isolation, corporate firewall, Docker network가 discovery traffic을 막을 수 있다. 서로 다른 domain은 같은 LAN의 실험 셀을 격리하는 좋은 수단이지만, 잘못 설정하면 silent partition이 된다.

Robot controller와 workstation은 가능한 경우 vendor 권고에 따라 dedicated wired link 또는 controlled switch를 쓴다. UR driver 설치 문서는 low-latency 또는 PREEMPT_RT kernel과 PC–controller direct Ethernet을 권고하지만, 이는 measured latency guarantee가 아니다 [13]. Camera traffic, bag upload와 internet package download를 robot control NIC에 섞지 않는다. 두 NIC를 쓸 때 route와 source address가 예상과 다른 interface로 나가지 않는지 확인한다.

Discovery 성공 후에는 data plane을 검증한다. Topic endpoint가 matched인지, type hash가 같은지, QoS compatible인지, 실제 sample이 갱신되는지, timestamp age와 loss가 얼마인지 본다. “ping works”는 DDS와 application message가 맞다는 뜻이 아니다. 반대로 DDS discovery가 되는 것도 robot-side external control program이나 drive enable이 준비됐다는 뜻은 아니다.

Network/discovery/time gate

단계 drive 상태 시험 PASS 즉시 중단 조건
L1 물리 off cable, link speed, fixed IP, route expected NIC와 subnet duplicate IP, unstable link
L2 robot API disabled vendor dashboard/state read only serial, firmware, safety state 확인 unexpected remote-control state
L3 DDS discovery disabled domain/RMW가 같은 talker state 확인 endpoint가 한 번만 발견 unknown command publisher 발견
L4 topic/QoS disabled state sample age, loss, type, QoS KPI 범위 내 fresh state stale state를 fresh로 표시
L5 time/TF disabled clock offset, transform age, frame authority lookup와 calibration ID 일치 time jump, duplicate TF authority
L6 command path drive off/mock action goal을 mock controller에 전송 owner, cancel, tolerance trace command가 real interface로 route

각 cell은 domain ID만으로 command authority를 보호하지 않는다. Namespace와 domain은 accidental collision을 줄일 뿐 authentication과 safety boundary를 대신하지 않는다. 누가 command topic/action을 publish할 수 있는지 network ACL, process launch ownership, physical mode selection과 robot controller state로 제한한다.

6. Lifecycle, launch와 parameter는 bring-up을 재현 가능하게 한다

Launch file은 여러 node와 parameter, namespace, remapping, process order를 repeatable하게 시작한다. 하지만 “driver 다음 controller 다음 planner”를 순서대로 spawn했다고 ready가 된 것은 아니다. 각 component가 required state, interface와 transform을 실제로 제공하는지 health check가 필요하다. Parameter file에는 robot IP, joint prefix, controller name, update rate와 frame을 명시하되 secret과 environment-specific value를 분리한다.

Lifecycle node는 auditable state transition을 노출하지만 robot controller의 safety state machine을 대신하지 않는다 [8] [20]. unconfigured→inactive→active transition은 resource allocation, connection과 publisher 활성화를 관리하기 좋다. 그러나 node가 active라고 protective stop이 해제됐거나 tool hazard가 안전하다는 뜻은 아니다. Third-party driver가 lifecycle을 부분적으로만 구현할 수도 있으므로 transition side effect를 test한다.

권장 bring-up mental model은 discover → configure → observe → claim → enable → move다. 먼저 hardware identity와 version을 발견하고, driver를 configure하되 command interface를 claim하지 않는다. State와 TF를 관찰하고 freshness를 통과시킨 뒤 controller ownership을 claim한다. Physical area와 stop path를 사람이 확인한 다음 vendor 절차로 enable한다. 마지막에 reduced envelope의 작은 motion을 보낸다. 실패하면 어디까지 성공했는지 state transition과 artifact로 남긴다.

Launch가 process를 자동 재시작하는 기능도 조심한다. Perception node 재시작과 robot driver 재시작은 의미가 다르다. Driver가 fault 후 자동 reconnect하면서 이전 command를 재적용하지 않는지, controller가 inactive로 돌아가는지, operator acknowledgment가 필요한지 명시한다. Safety-critical component에는 “항상 restart” 대신 named recovery state와 human approval을 둔다.

7. ros2_control은 controller와 hardware interface 사이의 소유권 경계다

ros2_control의 핵심은 robot-specific read/write를 hardware component로 감추고, trajectory, velocity, effort 같은 controller를 교체 가능하게 만드는 것이다. Controller Manager는 configured update loop에서 hardware read, controller update, hardware write를 호출한다. State interface는 joint position/velocity/effort를 노출하고 command interface는 controller가 쓸 수 있는 position/velocity/effort 등을 노출한다 [10].

ros2_control은 hardware interface와 controller를 분리하고 controller가 activate되거나 switch될 때 command-interface ownership을 grant 또는 release한다. 이후 update loop는 hardware를 read하고 active controller를 update한 뒤 command를 write한다 [10] [11]. 두 controller가 같은 joint position interface를 동시에 command하지 못하도록 claim을 관리하는 것이 중요하다. 그러나 이 ownership은 software resource arbitration이며 certified safe motion authority가 아니다. Hardware plugin이 unit, sign 또는 limit를 잘못 구현하면 framework가 자동으로 현실을 바로잡지 못한다.

Controller switching은 motion 중 즉흥적으로 하지 않는다. 어떤 interface가 release되고 claim되는지, transition 동안 last command와 hold behavior가 무엇인지 fake hardware와 simulator에서 시험한다. joint_state_broadcaster, trajectory controller와 vendor-specific controller 이름이 launch에 보인다고 실제 joint set이 맞는지 보장되지 않는다. Controller Manager list에서 state, claimed interface와 required joint를 모두 비교한다.

Joint Trajectory Controller는 trajectory point의 position/velocity/acceleration/effort 조합과 tolerance를 처리할 수 있지만 available command/state interface가 configuration을 제한한다 [9]. Planner가 보낸 trajectory 시간과 robot speed scaling이 실제 execution progress에 어떻게 반영되는지도 platform마다 다르다. UR의 speed-scaling controller semantics를 다른 arm에 복사하지 않는다 [14].

그림 4.3. Enable·activate·switch event에서 required/provided interface를 맞추고 command interface를 claim한다. 그 뒤 반복 loop는 hardware read, state interface, active controller update, command interface, hardware write 순서로 돈다. Vendor safety controller는 별도 경계에서 drive를 gate한다.

그림 4.3 — Controller ownership event와 recurring update loop를 분리한 corrected architecture. 원본 개념도.

8. UR와 Franka에서 같은 trajectory가 다른 계약을 만난다

UR ROS 2와 libfranka 또는 franka_ros2는 서로 다른 command contract, timing requirement와 version matrix를 노출한다 [12] [16] [17]. UR driver는 robot-side External Control, RTDE state, scaled trajectory controller와 pendant/remote mode를 포함한 ecosystem을 가진다. Franka는 libfranka와 FCI의 real-time 조건, robot system image와 library compatibility, torque/impedance controller semantics가 중심이다. 둘 다 ROS action 이름이 비슷하다고 low-level behavior가 같은 것은 아니다.

UR bring-up에서는 exact ur_type, robot IP, robot-side program, remote/headless mode, speed slider와 safety state를 확인한다. Mock hardware option은 interface와 launch를 검증하지만 dynamics, network jitter, speed scaling과 protective stop을 검증하지 않는다 [15]. 실제 trajectory 시간이 plan보다 길어지면 planner bug라고 단정하기 전에 speed scaling과 target-speed fraction을 본다 [14].

Franka bring-up에서는 robot firmware/system image, libfranka, franka_ros2와 description package의 version tuple을 고정한다. 2026 changelog의 minimum dependency를 만족해도 host real-time configuration과 network가 부적절하면 control loop가 실패할 수 있다 [16] [17]. Torque controller example은 연구 시작점이지 arbitrary generated controller를 real robot에 올리는 허가가 아니다.

질문 UR path Franka path 공통 artifact
command 시작 External Control/driver와 controller mode FCI/libfranka와 selected controller exact state diagram
timing RTDE/driver와 scaled execution 의미 1 kHz-class FCI host constraint rate, jitter, missed-cycle log
safety state pendant/controller가 authoritative robot controller가 authoritative enable/stop/recovery SOP
version firmware–ROS driver–UR packages system image–libfranka–franka_ros2 immutable version tuple
mock 범위 interface와 launch description/controller interface mock이 못 검증하는 목록

Kinova Kortex나 OpenArm CAN stack도 같은 방법으로 읽는다. 공식 ROS support가 있으면 command/state semantics와 supported distribution을 확인하고, custom description에서는 namespace, fake hardware flag와 CAN interface가 exact hardware revision에 맞는지 본다 [21] [22]. “ROS 2 compatible”은 시작점이지 acceptance 결과가 아니다.

9. Direct SDK는 ROS 2의 반대가 아니라 책임을 직접 떠안는 architecture다

Direct SDK가 좋은 경우가 있다. 한 대의 robot에서 vendor-specific torque/state API를 가장 얇게 사용하고, process가 하나이며, 외부 sensor integration과 distributed logging이 작고, vendor가 direct path를 primary support로 제공하는 경우다. Prototype latency path를 측정하거나 ROS wrapper에 아직 노출되지 않은 기능을 시험할 때도 유용하다. Dependency와 discovery surface가 줄어 failure를 단순화할 수 있다.

Direct SDK는 dependency surface를 줄일 수 있지만 frame, timing, logging, watchdog, command ownership과 vendor safety contract를 여전히 구현해야 한다 [12] [17] [19]. 검토된 근거 어디에도 direct SDK가 항상 더 빠르거나 안전하다는 보장은 없다. ROS 2를 제거하면 TF, rosbag, introspection, lifecycle과 standardized action을 잃을 수 있고, 그 책임은 application code와 운영 절차로 이동한다.

반대로 여러 camera, gripper, planner, visualization, remote operator와 dataset recorder가 함께 움직이면 ROS 2 graph의 typed interface와 tooling이 이점이 된다. Team이 component를 독립 교체해야 하거나 simulation과 hardware가 같은 high-level interface를 공유해야 할 때도 그렇다. 다만 hard servo는 vendor controller 또는 qualified real-time process에 남기고 ROS 2는 목표와 state를 전달하는 hybrid architecture가 흔히 가장 이해하기 쉽다.

책임 ROS 2 stack Direct SDK Hybrid 권장 위치
Discovery/type graph와 interface definition application config sensor/task는 ROS 2
Frame TF와 stamped message custom transform library canonical TF는 한 곳
Time/log ROS clock, bag, diagnostics custom logger low-level raw + synchronized ROS episode
Command ownership controller manager/action server mutex/state machine 직접 구현 one authoritative gateway
Servo deadline 자동 보장 아님 자동 보장 아님 vendor/qualified RT loop
Safety robot/cell controller가 별도 authoritative 동일 software 밖 independent stop path

Direct path를 택하더라도 adapter boundary를 만든다. 내부 vendor struct를 application 전체에 퍼뜨리지 말고 timestamped joint state, explicit units와 bounded command를 가진 작은 interface로 감싼다. 그러면 나중에 ROS bridge를 추가하거나 simulator backend를 교체할 수 있다. OROCOS의 오래된 교훈도 real-time component와 communication/toolchain 책임을 분리하자는 데 있다 [19].

10. MoveIt goal이 실제 joint command가 되는 경로

초심자는 MoveIt이 motor controller라고 생각하기 쉽다. 실제로 move_group은 robot model, planning scene, current joint state와 TF를 사용해 plan을 만들고, controller action interface로 trajectory를 보낸다. Collision geometry나 state가 틀리면 plan이 잘못되고, action server나 controller가 없으면 좋은 plan도 실행되지 않는다.

MoveIt move_group은 joint state와 TF를 소비하고 motor torque가 아니라 FollowJointTrajectory를 통해 trajectory를 보낸다 [18]. 그 아래 Joint Trajectory Controller 또는 vendor-compatible action server가 time-parameterized points를 받아 command interface로 변환한다. Torque control은 별도 controller와 safety analysis가 필요한 다른 contract다.

한 packet walkthrough를 적어 보자.

  1. Perception이 camera frame의 object pose와 image timestamp를 낸다.
  2. Task node가 그 시점의 TF를 사용해 pose를 base frame으로 변환하고 goal을 기록한다.
  3. MoveIt이 current joint state, URDF/SRDF, collision world와 constraints로 trajectory를 계획한다.
  4. Human-reviewed application이 trajectory bounds와 planning result를 확인하고 action goal을 보낸다.
  5. Trajectory controller가 goal을 accept하고 controller update마다 reference를 계산한다.
  6. Hardware interface/vendor driver가 reference를 platform protocol로 바꾼다.
  7. Robot controller가 mode, limit와 safety state 안에서 drive command를 적용한다.
  8. Joint state, action feedback, speed scaling, fault와 result가 위로 돌아오며 하나의 attempt ID로 저장된다.

각 단계에는 stop condition이 있다. TF lookup failure, stale joint state, planning failure, goal rejection, tolerance violation, missed control cycle, protective stop은 모두 서로 다른 failure다. “move failed” 한 줄로 합치면 학습도 운영도 개선할 수 없다.

11. 최초 연결과 작은 motion의 safe bring-up runbook

실물 bring-up은 simulator와 mock path를 통과한 configuration만 사용한다. Workstation이 E-stop authority를 대체하지 않으며, launch success가 physical clearance를 확인하지 않는다. ISO 10218-2의 application/cell scope와 기관 절차에 따라 qualified safety review를 별도로 수행한다 [20].

단계별 gate

Gate robot 상태 실행할 확인 저장할 증거 다음 단계 금지 조건
G0 manifest 전원 off model/serial/firmware/tool/version tuple signed inventory unknown revision
G1 static model offline joint axis/limit, TCP, collision, frame screenshots + hash sign/scale 불일치
G2 mock no hardware launch, controller claim, action cancel log + graph snapshot duplicate owner
G3 network drives disabled IP/discovery/state/time/TF 10분 freshness report stale/duplicate state
G4 connected idle drives disabled/robot idle vendor state, lifecycle, fault read state-transition trace unexpected remote mode
G5 enabled no motion reduced mode area/E-stop/observer/tool load 확인 checklist sign-off stop path 미검증
G6 one joint reduced speed/range 한 joint 작은 양·음 motion command/state/error plot wrong direction/overshoot
G7 trajectory reduced envelope 짧은 action, feedback/cancel attempt record cancel/hold 불명확

G6에서 여러 joint를 한꺼번에 움직이지 않는다. Physical observer가 E-stop에 접근하고, commanded joint, expected sign, maximum delta, speed, timeout과 stop reason을 소리 내어 확인한다. Motion 뒤에는 controller state와 physical pose가 일치하는지 본다. 이 순서의 자세한 실행은 (Chapter 7)에서 이어진다.

증상에서 계층을 찾는 troubleshooting 표

증상 먼저 볼 계층 확인 흔한 원인 위험한 임시방편
node가 서로 안 보임 network/DDS domain, RMW, multicast, firewall 다른 domain, VPN, container network firewall 전체 해제
topic 이름은 보이나 data 없음 endpoint/QoS type, QoS compatibility, publisher count reliable/best-effort mismatch 무조건 queue depth 증가
TF extrapolation time/TF source stamps, clock domain, buffer sim/wall time 혼합, stale camera 항상 latest TF 사용
plan 성공, execute 실패 action/controller server, claimed interface, goal result controller inactive, wrong joint list controller를 강제 switch
trajectory가 예상보다 느림 vendor semantics speed scaling, safety mode, timestamps slider/target fraction trajectory time만 무작정 줄임
주기적으로 protective stop tool/model/cell payload, CoM, cable, collision, log wrong load, cable snag, threshold safety limit 상향
reconnect 뒤 갑자기 움직임 ownership/recovery last command, auto restart, mode stale goal 재적용 watchdog 비활성화
RViz는 맞지만 real TCP가 어긋남 calibration TCP/base/camera revision stale static TF, wrong tool software offset 덧붙이기

12. Codex에 요청할 것은 “움직여 줘”가 아니라 검증 가능한 integration artifact다

Codex는 package tree, official API와 launch/config를 읽고 adapter, tests와 documentation을 만드는 데 유용하다. 하지만 real-time torque loop, safety limit 또는 E-stop authority를 맡기지 않는다. Generated change는 simulator/fake hardware test, diff review와 named human approval을 통과해야 한다.

Codex-generated robot code는 explicit frame, unit, rate, failure behavior, simulator test와 human-reviewed done condition으로 제한해야 한다 [23] [24]. CaP 계열 연구는 documented perception/control API가 명확하면 language model이 유용한 behavior를 compose할 수 있음을 보여 주지만, 잘못된 API output과 긴 program의 brittleness도 남는다 [24]. 관련 Terry 글은 한국어영어에서 볼 수 있다.

Prompt A — read-only ROS graph와 version 감사


당신은 robot integration auditor다. real robot에 접속하거나 파일을 수정하지 말라.
이 workspace, package manifests, launch/config, 그리고 내가 제공한 공식 vendor 문서만 읽어라.

Exact tuple을 표로 만들라: robot revision, controller firmware, Ubuntu/kernel,
ROS 2 distribution, RMW, vendor SDK, driver tag/commit, robot description,
ros2_control/controllers, MoveIt config. 각 행에 source URL/file과 verified/unknown을 표시하라.

예상 graph를 node, topic, service, action, TF publisher, parameter, command owner로 그려라.
각 command path에 frame, unit, nominal rate, timestamp source, QoS, watchdog,
failure behavior를 적어라. 근거 없는 호환성은 UNKNOWN으로 두고, real motion이나
safety bypass를 제안하지 말라. 완료 조건은 blocker와 supplier 질문이 포함된 audit report다.

Prompt B — fake-hardware integration task


목표: existing repository conventions를 따라 한 개의 fake-hardware bring-up과
검증 test만 제안하라. 먼저 AGENTS/README/package tree와 exact interfaces를 조사하라.

Constraints: real IP와 real hardware plugin을 사용하지 말 것; joint names/units/frame을
URDF에서 가져올 것; command interface owner는 하나일 것; stale state, missing TF,
goal rejection, cancel, tolerance violation을 test할 것; parameter를 숨은 상수로 쓰지 말 것.

Done when: launch가 fake hardware에서만 실행되고, FollowJointTrajectory goal의
accept→feedback→cancel/result가 test로 확인되며, 변경 파일과 실행 명령, 예상 output,
미검증 항목을 human reviewer가 확인할 수 있다. 실제 robot enable 단계는 작성하지 말라.

Prompt C — 증상 기반 진단 계획


증상과 logs를 바탕으로 원인을 network/discovery, QoS/type, time/TF, lifecycle,
controller ownership, vendor mode, tool/load, safety state로 나눠라. 가능성이 아니라
각 hypothesis를 반증할 read-only observation을 우선순위로 제시하라.

명령은 graph/state를 읽거나 offline log를 분석하는 범위로 제한하라. firewall 해제,
limit 완화, watchdog 비활성화, controller 강제 claim, 자동 reconnect motion을 금지하라.
결과에는 observed evidence, remaining unknown, safe next test, required human owner를 넣어라.

좋은 prompt는 goal, context, constraint와 done condition을 갖고 있다 [23]. “UR5e를 ROS 2로 움직여 줘”에는 exact version, controller, frame, limit와 test boundary가 없다. Codex가 질문을 되돌려 주거나 UNKNOWN을 남기는 것이 실패가 아니라 safe integration의 일부다.

13. 근거 등급, 논쟁점과 한계

이 장의 ROS interface, lifecycle, ros2_control, MoveIt과 vendor version 정보는 공식 documentation과 changelog라는 1차 software 근거다. 특정 revision의 interface와 support matrix를 설명하지만 실제 cell latency나 safety를 독립 검증하지 않는다. ROS 2 architecture, TF, response-time analysis, executor와 ros_control 논문은 학술 근거다. 일부는 초기 ROS 2 또는 ROS 1 lineage이므로 current implementation detail은 2026 documentation으로 다시 확인했다 [2] [11].

ROS 2 대 direct SDK 논쟁은 조건부다. ROS 2가 항상 느리고 SDK가 항상 빠르다는 주장은 근거가 없다. Serialization과 executor overhead가 중요한 loop도 있지만, vendor controller가 deadline을 소유하고 ROS 2가 goal만 전달하는 architecture에서는 integration visibility가 더 큰 이익일 수 있다. 반대로 single-process low-level experiment는 DDS graph가 불필요할 수 있다. 동일 hardware, command semantics와 measured worst-case latency 없이 headline average만 비교하지 않는다.

DDS QoS와 hard real time도 다른 문제다. Reliable delivery는 deadline 안의 delivery와 같지 않고, missed-deadline notification은 deterministic execution과 같지 않다. Functional safety는 network policy가 아니라 hazard analysis, certified/validated functions, physical stop와 operating procedure를 포함한다. Lifecycle state와 controller ownership도 auditability를 높이지만 safety rating을 만들지 않는다.

한계는 네 가지다. 첫째, distribution과 vendor matrix는 2026-07-14 이후 변한다. 둘째, official docs의 recommended kernel/network는 installed system의 measured timing guarantee가 아니다. 셋째, simulator/mock hardware는 packet contract를 검증해도 backlash, payload, protective stop과 cable hazard를 재현하지 않는다. 넷째, ISO public page는 표준 범위를 알려 주지만 normative text와 현지 법규, qualified review를 대신하지 않는다 [20].

제조 셀 적용 체크포인트

Configuration B의 UR5e+2F 셀을 예로 complete motion path를 승인해 보자. Task owner는 fixture_A의 object pose를 base로 변환해 pre-grasp를 계획하고, scaled_joint_trajectory_controller 계열 action path로 실행한다고 명시한다. Software owner는 camera, joint state, TF, MoveIt, action server, hardware interface와 UR driver의 node/namespace를 그린다. Network owner는 robot NIC와 camera/data NIC를 분리하고 domain, RMW, IP와 clock sync를 기록한다.

데이터 log는 attempt_id, version_tuple, calibration_id, goal_frame, goal_stamp, joint_state_age, tf_lookup_age, plan_result, controller_name, action_goal_id, speed_scaling, safety_state, fault_code, cancel/result, operator_intervention을 포함한다. KPI는 단순 성공률 외에 stale-state rejection, plan-to-execute latency, cancel latency, missed update, protective stop, recovery time와 wrong-owner event다.

승인 영역 질문 PASS artifact owner
Graph command publisher와 action server가 하나인가? graph snapshot + interface inventory integration engineer
Time/TF pose가 어느 stamp/calibration으로 base에 왔는가? 10분 age/lookup report perception owner
Controller joint/interface/tolerance/hold가 명시됐는가? controller config + fake test controls owner
Vendor firmware/driver/mode/speed scaling 의미가 pinned됐는가? version tuple + vendor test robot owner
Network discovery와 data가 controlled path를 쓰는가? NIC/route/domain/QoS report network owner
Safety stop/recovery와 physical observer가 독립적인가? signed SOP + injected-stop result safety owner
Data failure가 layer별로 재생·분류되는가? episode + logs + configuration hash data owner

한 gate가 UNKNOWN이면 motion을 시도해서 알아내지 않는다. Drive disabled, mock, offline log 또는 supplier confirmation으로 uncertainty를 닫는다. Robot이 움직이지 않는 것이 첫날의 failure가 아니다. 어느 layer에서 왜 막았는지 설명할 수 없는 것이 failure다.

다음에 배울 것

이제 ROS 2 message가 실제 controller까지 도달하는 책임 경계를 알았다. 다음 Chapter 5에서는 joint goal과 Cartesian goal이 IK, collision checking, time parameterization을 거쳐 trajectory가 되고, MoveIt 2와 ros2_control이 이를 실행하는 과정을 구체적으로 다룬다. 이 장의 TF/time/controller contract가 틀리면 좋은 planner도 안전한 motion을 만들 수 없다.

Chapter 5로 넘어가기 전에 자신의 cell을 한 장에 그려 보라. 모든 arrow에 message/action type, frame, unit, rate, time source, owner와 failure behavior를 적고, vendor controller와 physical safety boundary를 굵게 분리한다. 그 그림이 Chapter 7의 first-motion checklist와 Chapter 8의 teleoperation watchdog 설계의 기준이 된다.

주석이 있는 연구 경로

아래 자료는 middleware, orchestration과 executable validation를 더 깊이 확인하기 위한 경로다. 성공률을 빌려오는 목록이 아니라, 어떤 가정·interface·실험을 원문에서 비교해야 하는지에 따라 묶었다. 각 결과는 해당 platform과 protocol에 한정해 읽는다.

참고문헌

  1. Open Robotics (2026a). ROS 2 Jazzy Interfaces: Topics, Services, and Actions. ROS 2 official documentation.
  2. Maruyama, Y., Kato, S., & Azumi, T. (2016). The Robot Operating System 2: Design, Architecture, and Uses in the Wild. IEEE/SICE SII. DOI: 10.1109/SII.2016.7847304. [Maruyama et al., 2016]
  3. Casini, D., et al. (2019). Response-Time Analysis of ROS 2 Processing Chains under Reservation-Based Scheduling. ECRTS. DOI: 10.4230/LIPIcs.ECRTS.2019.6.
  4. Picas, J. M., et al. (2019). ROS 2 Executor: How to Make It Efficient, Real-Time and Deterministic?. ROSCon 2019.
  5. Foote, T. (2013). tf: The Transform Library. IEEE TePRA. DOI: 10.1109/TePRA.2013.6556373.
  6. Open Robotics (2024). REP-2000 ROS 2 Jazzy Platform and Support Matrix. ROS Enhancement Proposal 2000.
  7. Open Robotics (2026b). ROS 2 Lyrical Luth Release. ROS 2 official release documentation.
  8. Open Robotics (2026c). ROS 2 Jazzy Managed Node Lifecycle. ROS 2 official package documentation.
  9. ros-controls (2026a). Joint Trajectory Controller — Jazzy. ros2_control official documentation.
  10. ros-controls (2026b). ros2_control Jazzy Architecture and Getting Started. ros2_control official documentation.
  11. Chitta, S., et al. (2017). ros_control: A Generic and Simple Control Framework for ROS. Journal of Open Source Software. DOI: 10.21105/joss.00456.
  12. Universal Robots (2026a). Universal Robots ROS 2 Driver Documentation. Official documentation.
  13. Universal Robots (2026b). UR ROS 2 Driver Installation and Real-Time Guidance. Official documentation.
  14. Universal Robots (2026c). UR ROS 2 Controllers and Speed Scaling. Official documentation.
  15. Universal Robots (2026d). UR ROS 2 Driver Startup and Mock Hardware. Official documentation.
  16. Franka Robotics (2026a). franka_ros2 Changelog through v2.4.0. Official release history.
  17. Franka Robotics (2026b). libfranka Changelog and Packaging through 0.20.x. Official release history.
  18. MoveIt (2025). MoveIt 2 move_group Architecture. MoveIt official documentation.
  19. Bruyninckx, H. (2001). The OROCOS Project: Flexible Toolchain for Robot Control. IEEE ICRA. DOI: 10.1109/ROBOT.2001.932879.
  20. ISO (2025). ISO 10218-2:2025 Robotics — Safety Requirements — Part 2: Industrial Robot Applications and Robot Cells. International Standard, edition 3.
  21. Kinova Robotics (2024). KINOVA Gen3 Ultra Lightweight Robot One-Pager 2024. Official product documentation.
  22. OpenArm (2026). OpenArm v2.0 Robot Description and ROS Namespacing. Official documentation.
  23. OpenAI (2026). Codex Best Practices and Prompting. Official Codex guidance.
  24. Liang, J., et al. (2023). Code as Policies: Language Model Programs for Embodied Control. IEEE ICRA. arXiv:2209.07753.