NVIDIA Holoscan 5는 센서 처리에 쓰던 플랫폼에 로봇 제어를 더해, 로봇 팔의 상태를 읽고 토크를 계산해 모터로 보내는 과정을 하나의 실행 그래프로 구성하게 했다. NVIDIA가 공개한 튜토리얼은 사람이 팔을 움직일 때 무게는 모터가 받치고 손에는 부드럽게 반응하는 중력 보상 루프를 실제 팔에서 시연한다.
로봇 개발자는 이 예제를 출발점으로 삼아 제어와 센서 처리를 같은 프로그래밍 모델에서 조합할 수 있다. 공개된 측정은 코어 배치가 제어 지연에 어떤 영향을 주는지도 보여준다.
1. Holoscan 5가 제어 루프에 더한 것
Holoscan 5는 빠르게 반복하는 로봇 제어와 대량의 센서 데이터를 처리하는 작업에 같은 개발 방식을 제공한다. 개발자는 각 처리 단계를 오퍼레이터, 독립적으로 실행되는 처리 단위로 만들고, 데이터가 흐르는 순서를 그래프로 연결한다. 제어와 영상 분석을 서로 다른 주기로 실행하면서도 구성 방식을 따로 익힐 필요를 줄이는 설계다.
연속된 작업을 한 실행 묶음인 파티션에 두면 한 스레드가 차례로 처리한다. 단계마다 다른 스레드에 일을 넘기는 대신 한 담당자가 이어서 처리하는 셈이다. 컴파일러는 이 배치를 실행 계획에 기록하며, 개발자는 장비를 켜기 전에 작업 배치와 메모리 준비 계획을 살펴볼 수 있다.
2. 상태 읽기부터 모터 명령까지 세 단계
튜토리얼은 Seeed Studio reBot Arm B601-DM을 대상으로 한다. NVIDIA는 이 장비의 구동기가 위치 제어 위주인 저가 취미용 서보, 명령에 맞춰 움직임을 제어하는 모터와 달리 토크 제어와 센싱에 적합하다고 설명한다.
루프는 일정한 주기로 일곱 모터의 관절 상태를 읽는 단계, Pinocchio로 중력 토크를 계산하는 단계, 명령을 모터에 보내는 단계로 나뉜다. Pinocchio는 로봇 모델과 현재 자세를 바탕으로 관절마다 중력을 받치는 데 필요한 회전력을 구한다.
데모는 초당 400회 실행되며, 계산한 중력 토크에 약한 복원력, 팔을 기준 자세로 되돌리는 힘과 움직임을 진정시키는 감쇠를 더한다. 팔이 자기 무게를 지탱하면서도 사람이 미는 힘에는 부드럽게 움직이게 하는 구성이다.
원문은 세 오퍼레이터를 한 파티션에 넣고 큐 깊이를 1로 설정해 오래된 데이터를 버리는 예를 보인다. 따라서 계산이 늦어질 때 낡은 관절 상태가 줄줄이 쌓이는 상황을 피하도록 구성할 수 있다.
graph = hsdk.Graph("rebot-gravity", default_clock=hsdk.RealtimeClock)
source = graph.op(JointStateSourceOp, "joint_feedback")
gravity = graph.op(PinocchioGravityOp, "gravity", **controller.parameters.operator_kwargs())
sink = graph.op(MotorCommandSinkOp, "motor_commands")
graph.add_flow(source.state, gravity.state, queue_depth=1, queue_policy=hsdk.QueuePolicy.DROP_OLDEST)
graph.add_flow(gravity.command, sink.command, queue_depth=1, queue_policy=hsdk.QueuePolicy.DROP_OLDEST)
graph.partition("control").add(source).add(gravity).add(sink)3. 실행 계획과 안전 정지
애플리케이션은 그래프를 컴파일해 실행 계획을 만든 뒤 모터와 모델을 초기화하고 비동기 실행, 앞선 작업의 완료를 기다리지 않는 방식으로 들어간다. 계획이 비어 있으면 요약을 포함한 오류를 내도록 예시를 구성했다. NVIDIA는 이 순서가 실제 장비를 켜기 전에 그래프 설정 문제를 확인하도록 돕는다고 설명한다.
명령 완료 여부를 감시하는 워치독은 100밀리초 동안 완료된 모터 명령 묶음이 없으면 모터 비활성화를 시도하고 그래프를 멈춘다. 종료 콜백, 종료 때 자동 호출되는 함수도 모터를 비활성화한다.
예제는 Linux에서 Python 3.12 이상으로 실행한다.
같은 저장소에는 목표 위치와 방향을 지정하면서도 접촉에 유연하게 반응하는 두 번째 Python 예제가 있다. 손으로 이끄는 중력 보상에서 목표 자세를 유지하는 제어로 확장하는 출발점이다.
4. 코어 고정 여부에 따른 지연 시간
NVIDIA는 실행 분석 도구인 Nsight Systems로 오퍼레이터 실행을 측정했다. 아래 지연 시간은 첫 오퍼레이터 진입부터 마지막 오퍼레이터 진입까지이며 모터 명령 전송은 포함하지 않는다. 실행마다 백만 사이클 이상을 수집했고, 순차 측정의 첫 10초는 제외했으며 이상치는 유지했다.
표의 p50은 측정값의 절반이 그 이하인 중앙값이고, p99.99는 99.99%가 그 이하인 값이다. 중앙값이 평소 응답을 보여준다면 높은 백분위 값은 드물게 길어지는 지연을 살피는 지표다.
표: 중력 보상 루프의 구현별 지연 시간
조건: 회사 발표 기준, reBot Arm B601-DM 중력 보상 데모; 고정 실행은 코어 고정, 작업을 특정 CPU 코어에 묶는 설정과 코어 격리, 다른 작업이 해당 코어를 쓰지 못하게 하는 설정을 적용
단위: 마이크로초
| 구현 | p50 | p99.99 | p99.999 |
|---|---|---|---|
| HSDK C++ 고정 | 7.1 | 17.2 | 20.7 |
| HSDK C++ 비고정 | 15.3 | 86.6 | 133.4 |
| HSDK Python 고정 | 93.0 | 142.6 | 1,014.0 |
| HSDK Python 비고정 | 113.8 | 1,373.5 | 3,134.1 |
회사 발표 기준 코어 고정과 격리를 함께 적용한 경우 관측된 p99.99 지연은 C++에서 약 5배, Python에서 9.6배 감소했다. 반면 Python 고정 실행의 p99.999는 1,014.0마이크로초로 중앙값보다 여전히 크다. 평소 응답을 줄이는 일과 드문 지연을 관리하는 일을 함께 살펴야 한다는 결과다.
5. 지연을 줄이는 대신 운용을 정교하게
두 구현 모두 같은 C++ 기반 계산기를 쓰지만, NVIDIA는 Python의 실행과 객체 할당, 프로그램이 쓸 메모리를 확보하는 일 등에 추가 비용이 든다고 설명한다. 짧은 시간 안에 끝내야 하는 제어에서는 C++로 메모리 할당과 시스템 호출, 운영체제에 서비스를 요청하는 동작을 조절하는 이점이 커진다. 처리 단계가 CUDA로 구현되고 밀리초나 수십 밀리초가 걸리는 GPU 인식 작업에서는 Python도 실용적인 구성 수단이 된다는 것이 회사의 설명이다.
낮은 지연을 얻는 대신 코어를 제어용으로 배정하고 다른 작업의 간섭을 관리하는 운영 부담이 생긴다. 이번 측정은 제어용과 보조 작업용 물리 코어를 다른 애플리케이션이 쓰지 않도록 예약했지만, 인터럽트, CPU 처리를 잠시 중단시키는 신호와 일부 커널 작업, 운영체제 핵심부가 수행하는 작업까지 배제하지는 못했다.
Holoscan 5의 핵심은 로봇 제어를 센서 처리와 같은 실행 모델에 올리고, 그 실행 과정을 개발자가 사전에 살펴보고 측정할 수 있게 한 데 있다.
