목차

ROS STUDY #7

1. ROS 스터디 전반 복습

1.1. ROS, 노드의 집합체

1.1.1 노드

1.1.2 Topic

1.1.3 Service

1.1.4 Action

1.1.5. 노드 사이의 통신

1.2. ROS 노드 실행과 관리

1.3. ROS 프로그래밍 절차

1.4. 예제분석

ROS STUDY #6 : Topic 퍼블리시 실습에서 작성했던 코드 다시 한 번 깊게 분석하기

1.4.1. ROS 환경 준비

오랫동안 Ubuntu 환경을 사용하지 않았다면 각종 업데이트가 밀려있을 것이다. 우선 밀린 업데이트를 설치해주도록 하자.

$ sudo apt update
$ sudo apt upgrade
$ au

1.4.2. 프로젝트 생성

ROS STUDY #6에서 했던 내용과 동일한 코드입니다. 다만 프로젝트 생성 방법과 구조가 확실하게 기억나지 않는다면 다시 한 번 연습해보시기 바랍니다.

$ catkin_create_pkg cmd_vel_pub message_generation roscpp geometry_msgs message_runtime
cmd_vel_pub는 패키지 이름이다. 만약 기존 패키지 이름과 겹치다면 새로 만들어보고, 이후 설정에서도 반영해 보도록 하자. 이번 실습에서는 터미널 창보다 VSCode 상에서 한 번에 프로그래밍할 예정이다. 방금 만든 패키지를 폴더 째로 열자.
$ code cmd_vel_pub
마찬가지로, 패키지명이 cmd_vel_pub이 아니라면 폴더명도 다를 것이므로 알맞게 수정하도록 하자. 또는, 여러 패키지를 동시에 작업하고 싶다면, VSCode에서 폴더열기 (Ctrl+K Ctrl+O)를 아예 ~/catkin_ws/src로 지정하거나 터미널에서
$ code ~/catkin_ws/src

VSCode 폴더가 제대로 열렸는지 확인한다.

1.4.3. 메시지 파일 추가

geometry_msgs/Twist cmd_vel
cmd_vel_msg.msg라는 파일은 임의로 지정해도 상관 없다. 다만, 내용 중 cmd_vel은 다른 패키지에서도 참조할 이름이므로 다른 이름을 사용하면 작동하지 않는다. cmd_vel_msg.msg 외에 다른 이름을 사용해보고, 이후 CMakeLists.txt 파일과 노드 소스코드에서도 해당 변경사항을 반영해보자.

1.4.4. Publisher 노드 추가

#include "ros/ros.h"
#include "cmd_vel_pub/cmd_vel_msg.h"
 
#define PUB_NODE_NAME "cmd_vel"      // name of node
#define SUB_NODE_NAME "cmd_vel_sub"  // name of node
#define TOPIC_NAME "cmd_vel_topic"   // name of topic : cmd_vel_pub

float vel_x, vel_y;
 
int main(int argc, char **argv){
  ros::init(argc, argv, PUB_NODE_NAME);
  ros::NodeHandle nh;
  geometry_msgs::Twist cmd_vel; // variable to publish
 
  ros::Publisher cmd_vel_publisher = nh.advertise<geometry_msgs::Twist>(TOPIC_NAME, 100, true);
  ros::Rate loop_rate(0.3);
 
  cmd_vel.linear.x = 0;
  cmd_vel.linear.y = 0;
 
  while (ros::ok()){
    std::cout << "Input velocity: " << std::endl;
    std::cin >> vel_x >> vel_y;
 
    float current_x = cmd_vel.linear.x;
    float current_y = cmd_vel.linear.y;

    loop_rate.sleep();// Goes to sleep according to the loop rate defined above.
  }
  return 0;
}

1.4.5. Subscriber 노드 추가

#include "ros/ros.h"
#include "cmd_vel_pub/cmd_vel_msg.h"
 
#define PUB_NODE_NAME "cmd_vel"     // name of node
#define SUB_NODE_NAME "cmd_vel_sub" // name of node
#define TOPIC_NAME "cmd_vel_topic"  // name of topic : cmd_vel_pub
 
void messageCb(const geometry_msgs::Twist& cmd_vel){
    ROS_INFO("linear.x : %f\n", cmd_vel.linear.x);
    ROS_INFO("linear.y : %f\n", cmd_vel.linear.y);
    ROS_INFO("linear.z : %f\n", cmd_vel.linear.z);
    ROS_INFO("angular.x : %f\n", cmd_vel.angular.x);
    ROS_INFO("angular.y : %f\n", cmd_vel.angular.y);
    ROS_INFO("angular.z : %f\n", cmd_vel.angular.z);
}
 
int main(int argc, char **argv){
    ros::init(argc, argv, SUB_NODE_NAME);
    ros::NodeHandle nh;

    ros::Subscriber cmd_vel_subscriber = nh.subscribe(TOPIC_NAME, 10, messageCb);
     
    ros::spin();
 
    return 0;
}

1.4.6. CMakeLists.txt 수정

cmake_minimum_required(VERSION 3.0.2)
project(cmd_vel_pub)           # 패키지 이름과 동일, 이름과 다르면 빌드가 안된다.

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  message_generation
  message_runtime
  roscpp
)

## Generate messages in the 'msg' folder
add_message_files(
  FILES
  cmd_vel_msg.msg           # 새로 만들 메세지 이름
)

## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
generate_messages(            # 의존성
  DEPENDENCIES
  geometry_msgs
)

##캐킨 패키지 옵션으로 라이브러리, 캐킨 빌드 위존성, 시스템 의존 패키지를 기술한다
catkin_package( 
 INCLUDE_DIRS include
 LIBRARIES cmd_vel_pub
 CATKIN_DEPENDS geometry_msgs message_generation message_runtime roscpp
 DEPENDS system_lib
)


include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

##실행파일

add_executable(cmd_vel_pub src/cmd_vel_pub.cpp)           # cmd_vel_pub:노드, cmd_vel_pub.cpp: 노드를 만들 때 참고해야할 소스코드
add_dependencies(cmd_vel_pub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(cmd_vel_pub ${catkin_LIBRARIES})
  
add_executable(topic_subscriber src/topic_subscriber.cpp)           # topic_subscriber:노드, topic_subscriber.cpp: 노드를 만들 때 참고해야할 소스코드
add_dependencies(topic_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(topic_subscriber ${catkin_LIBRARIES})

1.4.7. package.xml 수정

<?xml version="1.0"?>
<package format="2">
  <name>cmd_vel_pub</name>
  <version>1.0.0</version>
  <description>The cmd_vel_pub package</description>
  <maintainer email="TODO">TODO</maintainer>
  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  <depend>geometry_msgs</depend>
  <depend>message_generation</depend>
  <depend>roscpp</depend>
  <depend>message_runtime</depend>

  <export>
  </export>
</package>

1.4.8. 실행 준비: 빌드

우선, 작업한 파일 모두 저장되었는지 확인하고 빌드를 진행한다. 터미널은 VSCode에서 단축키 CTRL+`로 띄워 이용하자.

$ cd ~/catkin_ws
$ catkin_make
$ makeros
위의 일반 명령어와 축약명령어는 완전히 동일하다. 축약명령어를 사용하면 ~/catkin_ws로 매번 이동한 후에 명령을 입력할 필요가 없어 편리하다.

1.4.9. 실행

1.4.9.1. Subscriber 노드 실행

$ rosrun cmd_vel_pub topic_subscriber
토픽이 Publish될때까지 아무런 출력이 없는 것이 정상이다.

1.4.9.1. Subscriber 노드 실행

$ rosrun cmd_vel_pub cmd_vel_pub
Input velocity: 
차례대로 x 병진속도와 y 병진속도를 입력하면 해당 값대로 cmd_vel이 Publish되는 것을 subscriber 노드를 통해 확인할 수 있다.

1.4.10. 응용