ROS Pub/Sub

홍성민·2024년 1월 26일
0

Camera Calibration & ROS

목록 보기
3/3
post-thumbnail

ROS Topic

ROS Topic이란, ROS에서 Node와 Node 사이에 연속적으로 데이터를 주고 받을 수 있는 방법 중 한개로, 특정 Node에서 Topic형태로 데이터를 뿌리게 되면, 다른 여러 개의 Node에서 그 데이터를 받아서 처리하는 것이 가능합니다.

즉 Publisher와 Subscriber의 데이터를 주고 받을 수 있는 "매개체"라고 생각해주시면 편합니다.

ROS Topic 명령어

ROS는 terminal을 이용해야해서 Linux명령어와 ROS자체에서 사용하는 명령어들을 잘 알고 있으셔야 합니다.

  • Topic list 보기 : rostopic list

  • Topic 정보 보기 : rostopic info [토픽_이름]

  • Topic 데이터 확인 : rostopic echo [토픽_이름]

실습을 통해 알아보겠습니다.
먼저 3개의 terminal창을 열어야합니다.

[1]

rosrun # 첫번째 terminal

rosrun turtlesim turtlesim_node # 두번째 terminal로 거북이 Node를 실행합니다.

rosrun turtlesim turtle_teleop_key # 세번째 terminal로 방향키를 조작하면 거북이가 움직이게 됩니다.

위의 3개의 terminal을 실행합니다.

rosnode list # Node들 살펴봄

rosnode list를 실행하게 되면 teleop_turtle, turtlesim의 Node가 생기게 되는데, 이 두 Node는 topic을 통해 데이터를 주고 받아 움직이게 됩니다.

[2]

rostopic list # Topic list를 살펴봅니다.

이후, rostopic list를 통해 Topic list를 살펴보면 turtle을 움직이게 하는 topic은 /turtle1/cmd_vel topic이게 됩니다.

[3]

rostopic info # topic의 정보 살펴보기

rostopic info를 통해 topic의 정보를 보면 pub/sub이 누구인지 살펴볼 수 있으며 이때 publisher는 방향키를 입력하는 teleop_turtle이고, subscriber는 그 방향키의 정보를 입력받는 turtlesim입니다.

또한 topic의 type을 알 수 있는데 geometry_msg/Twist는 ROS에서 기본으로 제공하는 Message type이라고 합니다.


ROS Publisher Node 생성

Publisher Node란, ROS에서 Topic을 발신하는 Node를 의미합니다.

앞에서 실습한 것처럼 계속해서 실습을 통해 진행해보겠습니다.

catkin_create_pkg basic_publish_tutorial roscpp # package이름은 basic_publish_tutorial이고 종속성 package는 roscpp입니다.

위의 명령어를 통해 ROS패키지를 먼저 생성해주면 됩니다.

먼저 Publisher Node를 작성하기 위해서 순서는 다음과 같습니다.

  1. CMakeLists.txt의 find_package 수정
  2. package.xml 수정
  3. Publisher Node 소스코드 작성
  4. CMakeLists.txt의 add_executable, target_link_libraries 추가

[1]

CMakeLists.txt를 text editor로 열어서 find_package에 Topic 사용을 위한 종속성 package를 추가해야합니다.

find_package에 "geometry_msgs"를 추가해주시면 됩니다.

[2]

package.xml의 editor를 열어서 CMakeLists.txt의 find_package에 추가한 package 이름을 밑의 3개의 항목에 대해서 추가해주면 됩니다. (위의 img에서 아래의 img로 바꾸어 주시면 됩니다.)

[3]

이제 Publisher Node 소스코드를 작성하겠습니다.

소스코드를 뜯어 보겠습니다.

  • geometry_msgs package의 Twist Message type을 사용합니다. 그에 대한 header file을 추가했습니다.

  • Node 이름을 basic_publish_node로 수정했습니다.

  • geometry_msgs::Twists를 cmd_vel 이름으로 선언합니다.

이제 Publsiher를 선언하는 내용입니다.

  • NodeHandle n의 advertise를 통해 정의할 수 있으며, < >은 어떤 Message type을 사용할 것인지를 정의해야합니다.

  • cmd_vel은 rostopic list를 입력할 때 나오는 topic이름을 정의하는 것으로 cmd_vel로 정의합니다.

  • 1000은 Message 대기열의 크기입니다.

이제 ros::Publisher의 publish를 호출하게 되면 ROS의 Topic이 publish 됩니다.
이때 주의할 점은 인자에 전달된 message의 값 (cmd_vel)의 값을 publish하며 type의 publisher에 정의된 message type과 같아야합니다. (Header file의 정의된 Message type과 같아야합니다.)

[4]

이제 마지막으로 CMakeLists.txt의 add_executable과 target_link_libraries를 추가합니다.

위의 2가지는 소스 코드 컴파일 및 실행파일을 만들기 위한 것으로 생각하시면 됩니다.

이제 마지막으로 Publish Node를 생성하였으니 Node가 생성되었는지 확인해보겠습니다.

먼저 publish Node를 먼저 rosrun으로 실행해주시고 rostopic list를 통해 publish node의 이름인 cmd_vel이 있는지 확인해보겠씁니다.


ROS Subscriber Node 생성

Subscriber Node란, Publisher가 Topic을 보내면 Subscriber Node가 Topic을 수신하는 Node를 의미합니다.

앞에서 생성한 Publish Node에서 Topic의 정보를 받는 Subscriber를 생성해보겠습니다.

먼저 Subscriber Node package를 생성합니다.

catkin_crate_pkg basic_subscribe_tutorial roscpp

Subscriber Node를 생성하는 순서는 Publisher Node를 생성하는 것과 같습니다.

  1. CMakeLists.txt의 find_package 수정
  2. package.xml 수정
  3. Subscriber Node 소스코드 작성
  4. CMakeLists.txt의 add_executable, target_link_libraries 추가

위의 과정에서 1번, 2번, 4번
은 publish node를 생성할 때와 같으므로 생략하겠습니다.

[3]

Subscriber Node 작성입니다.

코드 뜯어보겠습니다.

  1. 헤더파일 추가 & node이름을 basic_subscribe_node로 수정

  2. ros::Subscriber subscriber_cmd_vel을 통해 Subscriber를 선언합니다.

  3. 이제 Subscriber Node를 정의합니다.

  • 첫번째 인자는 수신할 Topic 이름

  • 두번째 인자는 Message 대기열의 크기

  • 세번째 인자는 Topic이 수신되었을 때 호출할 함수

  1. 호출할 함수 작성 (CmdVelCallback)
  • Topic이 수신되었을 때 호출되는 함수는 일반적으로 void type으로 정의되며, 인자로는 const geometry_msgs::Twists::ConstPtr&cmd_vel로 정의합니다 (포인터 사용)

  • topic의 값을 ROS_INFO를 통해 출력하는 부분을 작성합니다.

주의할 점은 Subscriber를 정의를 했지만, Topic을 수신하고 함수가 실행되는 것이 아니고 SpinOnce가 실행되는 순간에 topic이 수신되고 함수가 실행됩니다.

마지막으로 4번까지 마무리하고 rosrun을 통해 publish와 subscriber node를 실행해주시면 다음과 같은 결과가 나옵니다.

profile
할거면 똑바로 하고 아님 말자

0개의 댓글