ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • _ROS1_package_pub&sub
    ROS/ROS1 2023. 10. 2. 14:50

    ROS package

    packageROS에서 개발되는 소프트웨어를 논리적 묶음으로 만듣 것이다.

    my_pkg 구성

    ROS에서 제공하는 명령어

    $ rospack list                   # ros package 나열
    $ rospack find [package_name]    # 이름으로 package 검색
    $ roscd [location_name[/subdir]] # ROS package dir로 이동
    $ rosls [location_name[/subdir]] # Linux ls와 유사
    $ rosed [file_name]              # (환경 설정에 따른) 에디터로 파일을 편집

    위에서 rospack listroscd는 정말 자주 사용된다.

     

    Package 만들기

    참고 사이트

    http://wiki.ros.org/ROS/Tutorials/CreatingPackage

     

    ROS/Tutorials/CreatingPackage - ROS Wiki

    Using roscreate Before we create a package, let's see how the roscreate-pkg command-line tool works. This creates a new ROS package. All ROS packages consist of the many similar files : manifests, CMakeLists.txt, mainpage.dox, and Makefiles. roscreate-pkg

    wiki.ros.org

    $ cd ~/catkin_ws/src # 패키지를 담을 디렉토리로 이동
    $ catkin_create_pkg my_pkg1 std_msgs rospy roscpp # 패키지 이름지정 및 해당 패키지가 의존하는 다른 패키지 나열

    패키지가 만들어지면 catkin_make로 빌드를 하자.

    제대로 빌드가 되었다면 다음과 같이 나온다.

    만들어진 패키지는 다음과 같이 확인한다.

    $ rospack find my_pkg1     # my_pkg1의 위치를 알려줌
    $ rospack depends1 my_pkg1 # my_pkg1의 종속성을 알려줌
    $ roscd my_pkg1            # my_pkg1으로 이동

     

    Publish & Subscribe

    이번에는 publishsubscribe 노드를 만들어서 데이터를 주고 받는지 확인을 해볼 것이다.

    코드는 내가 만든 pkg안의 src폴더에 넣으면 된다.

    이번 pub과 sub예제는 python으로 만들어졌다.

     

    1. Publish(Python)

    pub.py의 코드는 다음과 같다.

    #!/usr/bin/env python # 모든 ROS Python노드에 선언됨. 내 스크립트가 파이썬 스크립트로 실행되는 것을 확인
    
    import rospy
    from geometry_msgs.msg import Twist
    
    rospy.init_node('my_node', anonymous=True) # 내 노드 이름
    pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10) # Publish 객체 생성
    
    msg = Twist()
    msg.linear.x = 2.0
    msg.linear.y = 0.0
    msg.linear.z = 0.0
    msg.angular.x = 0.0
    msg.angular.y = 0.0
    msg.angular.z = 1.8
    
    rate = rospy.Rate(1) #Rate 개체 속도. 초당 1번 루트 통과
    
    while not rospy.is_shutdown(): # shutdown 되지 않으면 계속 반복
        pub.publish(msg)
        rate.sleep() #루프 호출 속도. 루프가 원하는 rate를 유지할 수 있게 해줌.

    작성한 Python 코드를 사용하려면  실행 권한을 줘야한다. 초기에는 실행권한이 없으므로 chmod 명령어로 권한을 부여해야한다.

    이전에 실습했던 turtle_teleop_key 대신 pub.py를 사용하면 다음의 결과를 볼 수 있다.

    my_node에서 turtlesim으로 데이터를 전송

    2. Subscribe(Python)

    이번에는 publish를 받는 subscribe노드를 만들어 볼 것이다.

    sub.py의 코드는 다음과 같다.

    #!/usr/bin/env python
    
    import rospy
    from turtlesim.msg import Pose
    
    def callback(data):
        s = "Location: %.2f, %.2f" % (data.x, data.y)
        rospy.loginfo(rospy.get_caller_id() + s)
    
    rospy.init_node("my_listener", anonymous=True) # 노드의 고유한 이름 부여
    rospy.Subscriber("/turtle1/pose", Pose, callback) # 메시지를 수신하고 콜백 호출
    rospy.spin() # while과 같은 역할. 반복

    마찬가지로 chmod +x를 사용하여 권한을 부여한다.

    실행하면 다음과 같이 sub.py에서 거북이 로봇의 위치를 가져오는 것을 볼 수 있다.

    turtlesim에서 pose를 subscribe하는 모습

     

    3. Publish & Subscribe(C++)

    이번에는 C++을 사용하여 예제를 실습해보려고 한다.

    참고 사이트

    http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

     

    ROS/Tutorials/WritingPublisherSubscriber(c++) - ROS Wiki

    Writing the Publisher Node "Node" is the ROS term for an executable that is connected to the ROS network. Here we'll create a publisher ("talker") node which will continually broadcast a message. Change directory into the beginner_tutorials package, you cr

    wiki.ros.org

    일단 talker와 listener라는 두 가지 패키지를 작성한다. 이는 main이 두번 정의되지 않게 하기 위함이다.

     

     talker 패키지에 작성하며 talker.cpp코드는 다음과 같다.

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    #include <sstream>
    
    int main(int argc, char **argv)
    {
      ros::init(argc, argv, "talker"); //노드 초기화 및 고유한 이름 부여
      ros::NodeHandle n; // 노드 핸들 생성. 노드 핸들은 노드의 초기화 수행 및 파괴시 리소스 정리
      //마스터에 chatter에 대한 std_msgs/String 유형의 메시지를 게시할 것이라고 전달. 최대 1000개의 메시지.
      ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
      // 루프를 수행할 주파수 지정. 마지막에 sleep 호출 후 올바른 시간동안 절전을 할 수 있게 해줌.
      ros::Rate loop_rate(10);
    
      int count = 0;
      while (ros::ok()) // false를 반환할 때까지 반복
      {
    
        std_msgs::String msg;
        std::stringstream ss;
        ss << "hello world " << count;
        msg.data = ss.str();
    
        ROS_INFO("%s", msg.data.c_str());
    
        chatter_pub.publish(msg); //연결된 노드에 메시지 전송
    
        ros::spinOnce();
    
        loop_rate.sleep(); // 메시지를 전달하고 남은 시간동안 절전.
        ++count;
      }
      return 0;
    }

     

    listener.cpp 코드는 다음과 같다.

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    // 새로운 메시지가 도착했을 때 호출되는 콜백함수
    void chatterCallback(const std_msgs::String::ConstPtr& msg)
    {
      ROS_INFO("I heard: [%s]", msg->data.c_str());
    }
    
    int main(int argc, char **argv)
    {
      ros::init(argc, argv, "listener"); // 노드 고유 이름 설정
      ros::NodeHandle n;
      //1000개의 메시지를 받음.(1000개에 도달하면 이전 메시지는 버림)
      ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
      ros::spin();
    
      return 0;
    }

     

    이번에는 빌드를 하기 위해서 package.xmlCMakeList.txt 파일을 조금 수정해야 한다.

    해당 파일 수정은 위의 사이트의 3. Building your nodes 부분을 참고하면 된다.

     

    - CMakeList.txt

    우리는 talker.cpplistener.cpp를 빌드해야 하므로 add_executable, target_link_libraries, add_dependencies에 다음 과 같이 내용을 추가해야 한다.(Ctrl + f로 찾아서 하거나 복붙을 추천)

    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)

    talker 부분 CMakeList.txt 수정부분

    cpp로 작성한 파일은 굳이 권한을 주지 않아도 작동한다.

    두 프로그램을 실행해보면 다음과 같은 모습을 볼 수 있다.

    명령어:

    # Terminal 1
    $ roscore
    
    # Terminal 2
    $ rosrun talker talker
    
    # Terminal 3
    $ rosrun listener listener

     

    'ROS > ROS1' 카테고리의 다른 글

    _ROS1_node_communication  (0) 2023.10.04
    _ROS1_roslaunch  (0) 2023.10.03
    _ROS1_설치_환경설정_기본실습  (0) 2023.10.01
    _ROS1_기본 내용  (1) 2023.10.01
    _ROS1_Robot Operating System  (0) 2023.09.27
Designed by Tistory.