Main Content

ROS 2 Publisher 및 ROS 2 Subscriber를 사용해 데이터 교환하기

ROS 2 노드가 데이터를 교환하는 기본 메커니즘은 메시지를 주고받는 것입니다. 메시지는 토픽으로 전송되며 각 토픽은 ROS 2 네트워크에서 고유한 이름을 갖습니다. 정보를 공유하려는 노드는 publisher를 사용하여 데이터를 토픽으로 보내야 합니다. 해당 정보를 수신하려는 노드는 동일한 토픽에 대해 subscriber를 사용해야 합니다. 각 토픽은 고유한 이름을 가질 뿐만 아니라 해당 토픽에서 전송할 수 있는 메시지 유형을 결정하는 메시지 유형도 가집니다.

이러한 publisher-subscriber 통신에는 다음과 같은 특성이 있습니다.

  • 토픽은 다대다 통신에 사용됩니다. 여러 publisher가 메시지를 동일한 토픽에 보낼 수 있으며 여러 subscriber가 이를 수신할 수 있습니다.

  • publisher와 subscriber는 토픽을 사이에 두고 분리되어 있으며 임의의 순서로 생성되고 소멸될 수 있습니다. 활성 subscriber가 없더라도 메시지를 토픽에 퍼블리시할 수 있습니다.

이 예제에서는 ROS 2 네트워크에서 토픽을 퍼블리시하고 서브스크라이브하는 방법을 보여줍니다. 또한 다음을 위한 방법도 보여줍니다.

  • 새 메시지가 수신될 때까지 대기하기

  • 콜백을 사용하여 백그라운드에서 새 메시지 처리하기

선행 조건: Get Started with ROS 2, Connect to a ROS 2 Network

서브스크라이브하고 메시지 대기하기

여러 publisher 및 subscriber가 있는 샘플 ROS 2 네트워크를 만듭니다.

exampleHelperROS2CreateSampleNetwork

ros2 topic list를 사용하여 사용 가능한 토픽을 확인합니다.

ros2 topic list
/parameter_events
/pose
/rosout
/scan

/scan 토픽을 서브스크라이브하려 한다고 가정합니다. ros2subscriber를 사용하여 /scan 토픽을 서브스크라이브합니다. subscriber가 있는 노드의 이름을 지정합니다. 토픽이 이미 ROS 2 네트워크에 존재하는 경우 ros2subscriber가 해당 메시지 유형을 자동으로 감지하므로 지정할 필요가 없습니다.

detectNode = ros2node("/detection");
pause(5)
laserSub = ros2subscriber(detectNode,"/scan");
pause(5)

receive를 사용하여 새 메시지를 기다립니다. 제한 시간을 10초로 지정합니다. 출력 scanData에는 수신된 메시지 데이터가 포함됩니다. status는 메시지가 성공적으로 수신되었는지를 나타내고 statustextstatus에 대한 추가 정보를 제공합니다.

[scanData,status,statustext] = receive(laserSub,10);

이제 subscriber laserSub 및 여기에 연결된 노드를 제거할 수 있습니다.

clear laserSub
clear detectNode

콜백 함수를 사용하여 서브스크라이브하기

receive를 사용하여 데이터를 가져오는 대신 새 메시지가 수신될 때 호출될 함수를 지정할 수 있습니다. 이렇게 하면 subscriber가 새 메시지를 기다리는 동안 다른 MATLAB 코드를 실행할 수 있습니다. 여러 subscriber를 사용하려면 콜백이 필수입니다.

수신된 메시지를 입력으로 받는 콜백 함수 exampleHelperROS2PoseCallback을 사용하여 /pose 토픽을 서브스크라이브합니다. 기본 작업 공간과 콜백 함수 간에 데이터를 공유하는 한 가지 방법은 전역 변수를 사용하는 것입니다. 두 전역 변수, posorient를 정의합니다.

controlNode = ros2node("/base_station");
pause(5)
poseSub = ros2subscriber(controlNode,"/pose",@exampleHelperROS2PoseCallback);
global pos
global orient

새로운 메시지 데이터가 /pose 토픽에서 수신되면 전역 변수 posorientexampleHelperROS2PoseCallback 함수에 할당됩니다.

function exampleHelperROS2PoseCallback(message)    
    % Declare global variables to store position and orientation
    global pos
    global orient
    
    % Extract position and orientation from the ROS message and assign the
    % data to the global variables.
    pos = [message.linear.x message.linear.y message.linear.z];
    orient = [message.angular.x message.angular.y message.angular.z];
end

네트워크가 다른 /pose 메시지를 퍼블리시할 때까지 잠시 기다립니다. 업데이트된 값이 표시됩니다.

pause(3)
disp(pos)
   -0.0398   -0.0109   -0.0445
disp(orient)
    0.0001   -0.0068    0.0498

명령줄에 posorient를 몇 번 입력해 보면 해당 값이 계속 업데이트되는 것을 볼 수 있습니다.

subscriber 변수를 지워서 pose subscriber를 중지합니다.

clear poseSub
clear controlNode

참고: 전역 변수를 사용하는 것 외에, 콜백 함수에서 정보를 추출하는 다른 방법도 있습니다. 예를 들어 핸들 객체를 추가 인수로 콜백 함수에 전달할 수 있습니다. 콜백 함수 정의에 대한 자세한 내용은 Create Callbacks for Graphics Objects 문서를 참조하십시오.

메시지 퍼블리시하기

ROS 2 string형 메시지를 /chatter 토픽에 보내는 publisher를 만듭니다.

chatterPub = ros2publisher(node_1,"/chatter","std_msgs/String");

/chatter 토픽에 보낼 ROS 2 메시지를 만들고 채웁니다.

chatterMsg = ros2message(chatterPub);
chatterMsg.data = 'hello world';

ros2 topic list를 사용하여 /chatter 토픽을 ROS 2 네트워크에서 사용할 수 있는지 확인합니다.

ros2 topic list
/chatter
/parameter_events
/pose
/rosout
/scan

/chatter 토픽의 subscriber를 정의합니다. 새 메시지가 수신되면 exampleHelperROS2ChatterCallback이 호출되고 메시지의 문자열 내용이 표시됩니다.

chatterSub = ros2subscriber(node_2,"/chatter",@exampleHelperROS2ChatterCallback)
chatterSub = 
  ros2subscriber with properties:

        TopicName: '/chatter'
    LatestMessage: []
      MessageType: 'std_msgs/String'
    NewMessageFcn: @exampleHelperROS2ChatterCallback
          History: 'keeplast'
            Depth: 10
      Reliability: 'reliable'
       Durability: 'volatile'

/chatter 토픽에 메시지를 퍼블리시합니다. 해당 문자열이 subscriber 콜백에 의해 표시되는지 확인합니다.

send(chatterPub,chatterMsg)
pause(3)
ans = 
'hello world'

exampleHelperROS2ChatterCallback 함수는 subscriber가 string형 메시지를 수신했을 때 호출되었습니다.

ROS 2 네트워크와 연결 끊기

ROS 2 네트워크에서 샘플 노드, publisher, subscriber를 제거합니다. 또한 전역 변수 posorient를 지웁니다.

clear global pos orient
clear 

다음 단계