ROS 학습 노트(一): ROS 프로그램을 직접 작성한다.

10175 단어 입문ROS
최근 사장은 ROS 프레임워크를 ARM+FPGA 플랫폼에서 실현하도록 임무를 안배했다.그러나 ROS를 사용하여 프로그램을 만드는 절차가 번거롭기 때문에 이번에는 공식 문서에 있는 데모를 간략하게 써서 나중에 보기 편리하게 하였다.
ROS 버전: Hydro
Linux 버전: Ubuntu12.04
첫 번째 ROS(Robot Operating System) 프로그램을 시작하기 전에 공식 튜토리얼(클릭 링크 열기)에 따라 ROS를 성공적으로 설치했는지 확인합니다.본고는 매우 간단한 게시 (Publisher), 구독 (Subscriber) 프로그램을 만들었다.
작업공간 만들기(workspace)
작업공간은 ROS 프로그램의 소스 파일, 컴파일 파일 및 실행 파일을 저장하는 독립된 프로젝트로 컴파일할 수 있습니다.작업공간을 만드는 방법은 다음과 같습니다.
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

비록 이때 작업 구역은 비어 있지만 우리는 여전히 번역을 진행할 수 있다.
$ cd ~/catkin_ws/
$ catkin_make

이 때 현재 폴더에서 devel,build 두 개의 하위 폴더를 생성하고 devel 폴더에서 몇 개의 setup을 볼 수 있습니다.*sh 파일.
다음은 bash에 작업 영역을 등록합니다
$ source devel/setup.bash

bash에 등록되었는지 확인하려면 다음 명령을 사용합니다.
$ echo $ROS_PACKAGE_PATH
/home/youruser/catkin_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks

자신의 작업 영역의 파일 경로를 볼 수 있다면 성공했다는 것을 의미합니다.
ROS 패키지(Package) 작성
한 작업공간에 여러 개의 ROS 패키지가 포함될 수 있습니다.가장 기본적인 ROS 패키지에는 CmakeLists가 포함됩니다.txt 및 Package.Package.xml에는 본 프로젝트 정보와 각종 의존 (depends) 이 포함되어 있으며, CmakeLists는txt에는 코드를 어떻게 컴파일하고 설치하는지 정보가 포함되어 있습니다.
먼저 작업공간으로 전환합니다.
$ cd ~/catkin_ws/src

이제 캣킨create_Pkg 명령으로 Beginnertutorials의 가방, 이 가방은 std 에 의존msgs、roscpp、rospy.
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

다음에 작업 영역에서 이 프로젝트 패키지를 컴파일합니다.
$ cd ~/catkin_ws
$ catkin_make

간단한 게시(Publisher), 구독(Subscriber) 프로그램
게시(Publisher) 노드를 작성합니다.
노드(node)는 ROS 네트워크에 연결하여 실행할 수 있는 기본 장치입니다.우리는 이 게시자 - "talker"노드를 만들고, 이 노드는 지속적으로 대외적으로 정보를 발표합니다.
우선 저희 비긴너로 디렉터리를 전환해야 돼요.tutorials 프로젝트 패키지 중
$ cd ~/catkin_ws/src/beginner_tutorials

우리는 이미 이 프로젝트 패키지를 컴파일했기 때문에beginnertutorials 폴더에 CmakeList가 있습니다.txt、package.xml 파일과include, src 두 디렉터리입니다.다음은 src 하위 디렉터리로 들어갑니다
$ cd src

src 디렉터리에talker를 만듭니다.cpp 파일의 내용은 다음과 같습니다.
#include "ros/ros.h"
#include "std_msgs/String.h"

#include <sstream>
int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line. For programmatic
   * remappings you can use a different version of init() which takes remappings
   * directly, but for most command-line programs, passing argc and argv is the easiest
   * way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  ros::init(argc, argv, "talker");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle n;

  /**
   * The advertise() function is how you tell ROS that you want to
   * publish on a given topic name. This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing. After this advertise() call is made, the master
   * node will notify anyone who is trying to subscribe to this topic name,
   * and they will in turn negotiate a peer-to-peer connection with this
   * node.  advertise() returns a Publisher object which allows you to
   * publish messages on that topic through a call to publish().  Once
   * all copies of the returned Publisher object are destroyed, the topic
   * will be automatically unadvertised.
   *
   * The second parameter to advertise() is the size of the message queue
   * used for publishing messages.  If messages are published more quickly
   * than we can send them, the number here specifies how many messages to
   * buffer up before throwing some away.
   */
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

  ros::Rate loop_rate(10);

  /**
   * A count of how many messages we have sent. This is used to create
   * a unique string for each message.
   */
  int count = 0;
  while (ros::ok())
  {
    /**
     * This is a message object. You stuff it with data, and then publish it.
     */
    std_msgs::String msg;

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

    ROS_INFO("%s", msg.data.c_str());

    /**
     * The publish() function is how you send messages. The parameter
     * is the message object. The type of this object must agree with the type
     * given as a template parameter to the advertise<>() call, as was done
     * in the constructor above.
     */
    chatter_pub.publish(msg);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }


  return 0;
}

구독 노드 쓰기
아니면 src 디렉터리에서listener를 만듭니까?cpp 파일.내용은 다음과 같습니다.
#include "ros/ros.h"
#include "std_msgs/String.h"

/**
 * This tutorial demonstrates simple receipt of messages over the ROS system.
 */
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line. For programmatic
   * remappings you can use a different version of init() which takes remappings
   * directly, but for most command-line programs, passing argc and argv is the easiest
   * way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  ros::init(argc, argv, "listener");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle n;

  /**
   * The subscribe() call is how you tell ROS that you want to receive messages
   * on a given topic.  This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing.  Messages are passed to a callback function, here
   * called chatterCallback.  subscribe() returns a Subscriber object that you
   * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
   * object go out of scope, this callback will automatically be unsubscribed from
   * this topic.
   *
   * The second parameter to the subscribe() function is the size of the message
   * queue.  If messages are arriving faster than they are being processed, this
   * is the number of messages that will be buffered up before beginning to throw
   * away the oldest ones.
   */
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  /**
   * ros::spin() will enter a loop, pumping callbacks.  With this version, all
   * callbacks will be called from within this thread (the main one).  ros::spin()
   * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
   */
  ros::spin();

  return 0;
}

만든 노드를 컴파일합니다. 우리가 만든 노드를 컴파일하기 전에 Cmakelist를 편집해야 합니다.txt 파일 (주의: beginner tutorials 프로젝트 패키지 아래의 CMakelist 파일) 은 편집기에 우리가 어떤 파일을 편집해야 하는지, 의존해야 하는지 알려 줍니다.
$ gedit CMakeLists.txt

파일 끝에 다음과 같은 문을 추가합니다.
include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

디렉토리를 작업공간 디렉토리로 전환하고catkinmake 실행 명령:
$ cd ~/catkin_ws
$ catkin_make

예기치 않은 경우 다음과 같은 인터페이스가 나타납니다.
이로써 프로그램이 완성되었습니다. 다음에 우리가 만든 프로그램이 정확한지 확인해야 합니다.
테스트 프로그램의 정확성
우선 ROS 핵심 프로그램인 roscore를 시작해야 합니다.
$ roscore

우리 프로그램을 사용하기 전에 먼저 프로그램을 등록해야 한다
$ cd ~/catkin_ws
$ source ./devel/setup.bash

talker 노드를 실행하려면 다음과 같이 하십시오.
$ rosrun beginner_tutorials talker 

이때 다음과 같은 메시지를 볼 수 있다.
[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
[INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
[INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
[INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
[INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
[INFO] [WallTime: 1314931836.788106] hello world 1314931836.79

게시(Publisher) 노드가 제대로 실행되었음을 나타냅니다.
다음에 listener 노드를 실행합니다.
$ rosrun beginner_tutorials listener

이때 다음과 같은 메시지를 볼 수 있다.
[INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I heard hello world 1314931969.26
[INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world 1314931970.26
[INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world 1314931971.26
[INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world 1314931972.27
[INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world 1314931973.27
[INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world 1314931974.28
[INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world 1314931975.28

이것은 구독 노드(listener)가 게시 노드(talker)가 발표한 정보를 성공적으로 받아들였다는 것을 설명한다.이로써 전체 프로그램이 종료되었습니다!

좋은 웹페이지 즐겨찾기