1. 程式人生 > >ROS學習之cpp教程

ROS學習之cpp教程

官方連結:
    http://wiki.ros.org/roscpp_tutorials

一、編寫簡單的訊息釋出器和訂閱器

    1、編寫一個釋出器節點

        節點(node)是ROS中值代連線到ros網路中的可執行檔案。接下來,將會建立一個釋出器節點(talker),
        他將不斷在ROS網路中廣播訊息。
        轉移到~目錄下建立一個catkin工作空間,在src目錄下建立一個包,在包目錄下建立一個src目錄,建立*.cpp檔案,編寫程式碼
        
        常用的 ros/ros.h 引用ros系統中大部分常用的標頭檔案
        std_msgs/String.h 引用標準訊息包下的String訊息
        ros::init(argc,argv,"node_name");//初始化ROS,允許ROS通過命令列進行名稱重對映。這裡指定唯一的節點名稱
        ros::NodeHandle n; //為這個程序的節點建立一個控制代碼,第一個被建立的控制代碼會為節點進行初始化,最後一個被銷燬的控制代碼會清理節點使用的所有資源
        ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter",1000);
        //告訴master節點我們將要在名為chatter的話題上釋出一個std_msgs/String型別的訊息.這樣master就會告知所有訂閱了chatter話題的節點,將要有資料訊息被髮布.第二個引數1000指釋出序列的大小.如果緩衝區中的訊息數目大於1000,就會丟棄之前的訊息.
        NodeHandle::advertise()函式會返回一個ros::Publisher物件,它的publish(msg)成員函式可以讓你在topic話題上釋出訊息,如果訊息型別與advertise<msgs_type>("topic_name",num);中的型別不對應,那麼將會拒絕釋出訊息.
        ros::Rate 物件可以允許制定子迴圈的頻率,它會追蹤記錄自上一次呼叫Rate::sleep()之後的時間流逝,並休眠直到一個頻率週期的時間.
        ros::ok()函式會返回false當下述情況出現時:SIGINT(^C) 被另一個同名節點踢出ROS網路 ros::shutdown()函式被該程式的另一部分呼叫  
        std_msgs::String msg; 定義訊息物件,
        msg.data = ss.str(); 填充訊息物件成員,
        chatter_pub.publish(msg); 釋出訊息
        ROS_INFO("%s",string);用於代替printf/cout向控制檯介面釋出顯示資訊
        ros::spinOnce()函式,允許接受回撥函式,spin是旋轉,停留的意思

        總結一下: 1.初始化ROS系統  
             2.在ROS網路內廣播我們將在chatter topic上釋出std_msgs/String訊息
             3.以每秒10次的頻率在chatter上釋出訊息


    2、編寫一個訂閱器節點

        chatterCallback()回撥函式會處理訂閱的主題的訊息.
        NodeHandle物件的subscribe()函式設定訂閱的主題名,佇列的大小,設定訊息到來時的回撥函式,返回一個ros::Subscriber物件
        當ros::Subscriber物件被銷燬時,將自動退訂主題上面的訊息
        還有不同的NodeHandle::subscribe()函式,允許指定類的成員函式,具體檢視roscpp overview(http://wiki.ros.org/roscpp/Overview)
        ros::spin()函式進入自迴圈,可以儘可能快的呼叫訊息回撥函式.

        總結一下: 1.初始化ROS系統  
              2.訂閱chatter topic主題   
              3.進入自迴圈,等待訊息的到達
              4.當訊息到達時,呼叫chatterCallback()函式

    3.編譯工作空間,對修改過的程式包進行編譯

        1)修改程式包目錄下的CMakeLists.txt檔案,大體上類似下面
            cmake_minimum_required(VERSION 2.8.3)      #需要的cmake的最小版本號
            project(m_pkg)                   #程式包名

            ## Find catkin and any catkin packages     #需要的其他包
            find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)

            ## Declare ROS messages and services       #新增訊息檔案
            add_message_files(FILES String.msg)
            #add_service_files(FILES AddTwoInts.srv)

            ## Generate added messages and services    #生成訊息檔案
            generate_messages(DEPENDENCIES std_msgs)

            ## Declare a catkin package
            catkin_package()

            ## Build talker and listener
            include_directories(include ${catkin_INCLUDE_DIRS})

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

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


        2)進入工作空間目錄,執行catkin_make編譯,顯示如下:
            Base path: /home/sl/m_ros_ws             #工作空間目錄
            Source space: /home/sl/m_ros_ws/src        #原始碼src目錄
            Build space: /home/sl/m_ros_ws/build        #build目錄
            Devel space: /home/sl/m_ros_ws/devel        #devel目錄
            Install space: /home/sl/m_ros_ws/install    #install目錄(如果有的話)
            ####
            #### Running command: "make cmake_check_build_system" in "/home/sl/m_ros_ws/build"
            ####
            -- Using CATKIN_DEVEL_PREFIX: /home/sl/m_ros_ws/devel
            -- Using CMAKE_PREFIX_PATH: /home/sl/m_ros_ws/devel;/opt/ros/jade
            -- This workspace overlays: /home/sl/m_ros_ws/devel;/opt/ros/jade
            -- Using PYTHON_EXECUTABLE: /usr/bin/python
            -- Using Debian Python package layout
            -- Using empy: /usr/bin/empy
            -- Using CATKIN_ENABLE_TESTING: ON
            -- Call enable_testing()
            -- Using CATKIN_TEST_RESULTS_DIR: /home/sl/m_ros_ws/build/test_results
            -- Found gtest sources under '/usr/src/gtest': gtests will be built
            -- Using Python nosetests: /usr/bin/nosetests-2.7
            -- catkin 0.6.16
            -- BUILD_SHARED_LIBS is on
            -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            -- ~~  traversing 1 packages in topological order:    #只定位到1個程式包
            -- ~~  - m_pkg
            -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            -- +++ processing catkin package: 'm_pkg'           #處理這個catkin程式包
            -- ==> add_subdirectory(m_pkg)
            -- Using these message generators: gencpp;geneus;genlisp;genpy
            -- m_pkg: 1 messages, 0 services              #顯示只有1個訊息,0個服務
            -- Configuring done                    #配置完成
            -- Generating done                    #生成完成
            -- Build files have been written to: /home/sl/m_ros_ws/build #編譯檔案寫入工作空間build目錄
            ####
            #### Running command: "make -j4 -l4" in "/home/sl/m_ros_ws/build"  #開始編譯
            ####
            [  0%] Built target std_msgs_generate_messages_eus
            [  0%] [  0%] Built target std_msgs_generate_messages_cpp
            Built target std_msgs_generate_messages_py
            [  0%] Built target std_msgs_generate_messages_lisp
            [  0%] Built target _m_pkg_generate_messages_check_deps_String
            [ 62%] [ 62%] [ 62%] Built target m_pkg_generate_messages_lisp
            Built target m_pkg_generate_messages_py
            Built target m_pkg_generate_messages_eus
            [ 75%] Built target m_pkg_generate_messages_cpp
            [ 75%] Built target m_pkg_generate_messages
            [ 87%] [100%] Built target listener
            Built target talker
        這會產生兩個可執行檔案talker和listener預設儲存在devel目錄下(具體在~/m_ros_ws/devel/lib/<pkg name>中)

    4.執行節點

        1)啟動節點命名管理器master節點(主節點)
            開啟一個terminal,輸入roscore   如果有錯誤,執行 source /opt/ros/<ros-distr>/setup.bash定位一下
        2)執行listener節點
            開啟一個終端,定位下工作空間(如果寫入~/.bashrc,可省略此步) 執行source ~/m_ros_ws/devel/setup.bash
            然後,執行 rosrun m_pkg listener 執行節點
        3)執行talker節點
            開啟另一個終端,定位下工作空間(如果寫入~/.bashrc,可省略此步) 執行source ~/m_ros_ws/devel/setup.bash
            然後,執行 rosrun m_pkg talker 執行節點

                Talker將會輸出如下類似文字:

                [ INFO] I published [Hello there! This is message [0]]
                [ INFO] I published [Hello there! This is message [1]]
                [ INFO] I published [Hello there! This is message [2]]
                ...

                同時listener也會開始輸出類似的文字資訊:

                [ INFO] Received [Hello there! This is message [20]]
                [ INFO] Received [Hello there! This is message [21]]
                [ INFO] Received [Hello there! This is message [22]]
                ...
    

二、編寫簡單的Service和Client

    1.編寫簡單的Service節點

        在程式包中的srv目錄下建立服務檔案*.srv  具體參見:http://wiki.ros.org/ROS/Tutorials/CreatingMsgAndSrv#Creating_a_srv
        在程式包中的src目錄下建立add_two_ints_server.cpp,編寫程式碼

    2.編寫簡單的client節點

        在程式包的src目錄下建立add_two_ints_client.cpp,編寫程式碼

    3.編譯節點

        開啟程式包的CMakeLists.txt檔案,在後面新增如下幾行:
            add_executable(add_two_ints_server src/add_two_ints_server.cpp)
            target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
            add_dependencies(add_two_ints_server m_pkg_gencpp)

            add_executable(add_two_ints_client src/add_two_ints_client.cpp)
            target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
            add_dependencies(add_two_ints_client m_pkg_gencpp)
        這幾行將控制生成兩個可執行程式add_two_ints_server和add_two_ints_client,這兩個可執行程式被放在devel/lib/share/m_pkg下
            
        在工作空間執行catkin_make,顯示
            Scanning dependencies of target add_two_ints_client
            [ 52%] [ 78%] Built target m_pkg_generate_messages_eus
            Built target m_pkg_generate_messages_py
            Scanning dependencies of target add_two_ints_server
            [ 84%] [ 89%] Built target listener
            Built target talker
            [ 89%] Built target m_pkg_generate_messages
            [100%] [100%] Building CXX object m_pkg/CMakeFiles/add_two_ints_server.dir/src/add_two_ints_server.cpp.o
            Building CXX object m_pkg/CMakeFiles/add_two_ints_client.dir/src/add_two_ints_client.cpp.o
            Linking CXX executable /home/sl/m_ros_ws/devel/lib/m_pkg/add_two_ints_client
            Linking CXX executable /home/sl/m_ros_ws/devel/lib/m_pkg/add_two_ints_server
            [100%] Built target add_two_ints_client
            [100%] Built target add_two_ints_server

三、使用引數  

wiki: http://wiki.ros.org/cn/roscpp_tutorials/Tutorials/Parameters

    1.提取引數

        使用NodeHandle有兩種方法提取引數。在下面的例子中,n代表一個節點控制代碼物件。
        1)getParam()函式   std::string s;
                    n.getParam("my_param", s);    //key+value  類似鍵值對
        2)param()函式        int i;
                      n.param("my_num", i, 42);  //如果不成功,對變數i賦預設值42

    2.設定引數

        使用setparam()函式  n.setParam("my_param", "hello there");

    3.刪除引數

        使用deleteParam()函式 n.deleteParam("my_param");

    4.判斷引數存在

        使用hasParam()函式 hasParam("my_param"),存在返回ture,不存在返回false

    5.尋找引數

        引數伺服器使你能夠查詢引數從你的名稱空間開始,通過你的父名稱空間向上找。類似於樹搜尋

        searchParam("search_name",param_name)函式

四、從節點控制代碼獲取私有名字

wiki: http://wiki.ros.org/cn/roscpp_tutorials/Tutorials/AccessingPrivateNamesWithNodeHandle

    如果直接使用節點控制代碼自己的名字空間,可能會引起混亂。
    在建立節點控制代碼時,應使用私有名稱引數傳遞。
        例如:
            ros::init(argc, argv, "my_node_name");
            ros::NodeHandle nh1("~");        //nh1的名字空間是/my_node_name
            ros::NodeHandle nh2("~foo");        //nh2的名字空間是/my_node_name/foo
    

五、使用類成員方法做回撥函式

wiki : http://wiki.ros.org/cn/roscpp_tutorials/Tutorials/UsingClassMethodsAsCallbacks

    除了使用自己定義的函式作為回撥函式之外,ROS支援使用類的成員方法作為回撥函式

    1.訂閱者回調


    使用一般的自定義函式chatterCallback作回撥:
        ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

    使用類的成員方法作回撥:
        class Listener
        {
        public:
          void callback(const std_msgs::String::ConstPtr& msg);
        };

        Listener listener;  //例項化類物件
        ros::Subscriber sub = n.subscribe("chatter", 1000, &Listener::callback, &listener);

    2.服務伺服器(Service Servers)

        
    使用自定義的回撥函式:

    ros::ServiceServer service = n.advertiseService("add_two_ints", add);

    使用類的成員方法:

    class AddTwo
    {
    public:
      bool add(roscpp_tutorials::TwoInts::Request& req,
           roscpp_tutorials::TwoInts::Response& res);
    };

    AddTwo a;
    ros::ServiceServer ss = n.advertiseService("add_two_ints", &AddTwo::add, &a);

六、定時器的使用

wiki: http://wiki.ros.org/roscpp_tutorials/Tutorials/Timers

    描述:定時器Timer允許週期性地呼叫一個回撥函式。它們比ros::Rate類更加靈活有用。

    注意,定時器Timer類不是實時執行緒/核心代替,對於精度沒有保障。會因系統負載/容量發生很大變化。

    1.使用定時器基礎知識


    例項化定時器物件與Subscriber物件類似: ros::Timer timer = n.createTimer(ros::Duration(0.1),timerCallback);

    定時器回撥的形式:void timerCallback(const ros::TimerEvent& e);
    
    時間事件結構體: ros::TimerEvent
    

    2.多定時器例子

        建立兩個定時器
            ros::Timer timer1 = n.createTimer(ros::Duration(0.1), callback1);   //100 ms
            ros::Timer timer2 = n.createTimer(ros::Duration(1.0), callback2);   //1 second

        [email protected]:~/m_ros_ws$ rosrun m_pkg timer_test
        [ INFO] [1468647866.507138304]: Callback 1 triggered
        [ INFO] [1468647866.607406741]: Callback 1 triggered
        [ INFO] [1468647866.707729591]: Callback 1 triggered
        [ INFO] [1468647866.806902543]: Callback 1 triggered
        [ INFO] [1468647866.907178881]: Callback 1 triggered
        [ INFO] [1468647867.007414974]: Callback 1 triggered
        [ INFO] [1468647867.107685959]: Callback 1 triggered
        [ INFO] [1468647867.206911026]: Callback 1 triggered
        [ INFO] [1468647867.307240687]: Callback 1 triggered
        [ INFO] [1468647867.407530667]: Callback 1 triggered
        [ INFO] [1468647867.407588676]: Callback 2 triggered
        [ INFO] [1468647867.507788676]: Callback 1 triggered
        [ INFO] [1468647867.607068827]: Callback 1 triggered
        [ INFO] [1468647867.707315687]: Callback 1 triggered
        [ INFO] [1468647867.807539675]: Callback 1 triggered
        [ INFO] [1468647867.907822600]: Callback 1 triggered
        [ INFO] [1468647868.007130929]: Callback 1 triggered
        [ INFO] [1468647868.107539634]: Callback 1 triggered
        [ INFO] [1468647868.207966415]: Callback 1 triggered


相關推薦

ROS學習cpp教程

官方連結:     http://wiki.ros.org/roscpp_tutorials 一、編寫簡單的訊息釋出器和訂閱器     1、編寫一個釋出器節點         節點(node)是ROS中值代連線到ros網路中的可執行檔案。接下來,將會建立一個釋出器節點(

ROS學習 cpp時間

wiki連結: http://wiki.ros.org/roscpp/Overview/Time    1.時刻和時間間隔         ROS有內建的時間和時間間隔原始型別,rsolib程式包提供了ros::Time和ros::Duration類         tim

ROS學習 cpp回撥函式和輪轉(spin)

wiki連結: http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning 資料(雲飛機器人實驗室的一篇小文): http://www.yfworld.com/?p=2318 這篇文章會幫助理解ros::s

ROS學習 cpp訊息釋出者和訊息訂閱者

wiki連結: http://wiki.ros.org/roscpp/Overview/Publishers%20and%20Subscribers一、釋出一個話題     其它相關連結:         ros::NodeHandle,ros::NodeHandle::

ROS學習編譯一個包

cti ges begin -s 包名 code start ner 一個 catkin_make -DCATKIN_WHITELIST_PACKAGES= "包名" $ catkin_make -DCATKIN_WHITELIST_PACKAGES="begin

ros學習kobuki

key con core sta -i fig other del mini sudo apt-get install ros-indigo-kobuki ros-indigo-kobuki-corerosrun kobuki_ftdi create_udev_rules#

輕松學習Linux教程四 神器vi程序編輯器攻略

分享 內置 snippet 2014年 答案 程序 ice 界面 fff 本系列文章由@超人愛因斯坦出品,轉載請註明出處。 文章鏈接: http://hpw123.net/a/Linux/Linuxjichu/2014

1.深度學習安裝教程

步驟 install sta tensor lib64 libc 鏈接 lib flow 在centos5下安裝TensorFlow。 步驟: 1.安裝python3.5 2.安裝pip3,同時建立軟鏈接。 3.安裝TensorFlow,pip install --upgr

ROS學習路的整理

        ROS是基於linux系統的一個次級作業系統,目前被看做是機器人界的一套標準平臺,可以類比手機的安卓作業系統或者是電腦的windows作業系統。ROS最大的優點在於靈活、低耦合、分散式、開源以及功能強大而豐富的

ROS學習路(二)檔案系統

    在ROS的檔案包裡面,有純粹的程式碼,也有編譯後的二進位制檔案。如何將這些檔案有條不紊的整理起來呢?於是就有了下面這種檔案系統: 對於每一個特定的功能,用一個資料夾包起來,就是所謂的功能包: (1)config:放置功能包中的配置檔案,由使用者建立,檔名可以不同

ros學習camera calibration 單目攝像頭標定

環境:ubuntu16.04 ros版本 kinetic 標定筆記本單目攝像頭 需要的準備:1、標定圖:下面這張列印到a4紙上。 2、攝像機驅動,我使用的是usb_cam,下載地址:https://github.com/ros-drivers/usb_c

ros學習apriltags2_ros

apriltags2的執行很簡單,主要就是幾個引數的設定問題記錄一下。 一、準備 1、apriltags2可以在 https://github.com/dmalyuta/apriltags2_ros.git 下載,下載後放到catkin_ws工作目錄下。 編譯:

ROS學習認識

本人準備做一個ROS學習系列文章,目的是對自己的學習經歷做一個總結,同時,也是希望能夠幫助到想要學習ROS的人。 一.ROS是什麼 提到ROS,大家應該都清楚,它是機器人作業系統英文的首寫字母縮寫(Robot Operation System),這是它的名字,那麼從它

ROS學習launch檔案編寫

1.一個簡單的launch檔案//在catkin_ws/src/下建立一個包,單獨存放launch 檔案 cd catkin_ws/src catkin_create_pkg my_launch //回到catkin_ws目錄下 catkin_make在包 my_launch

我的ROS學習路——ROS安裝

1.進入ubuntu的‘軟體與更新’(soft and update)介面,選中以下四個 main universe  restricted multiverse 如圖: 2,。在linux終端輸入 

ROS學習tf基本用法

主要細節參見wiki,這裡我寫一下它的broadcaster和listener做個記錄: tf_broadcaster.cpp: #include<ros/ros.h> #include<tf/transform_broadcaster.h> in

ROS學習 roscpp內部架構概況

wiki連結:http://wiki.ros.org/roscpp/Internals     這部分包括一個對roscpp內部架構組織高度概括的審視,從最底層開始。    1.通用哲學     roscpp的哲學是僅僅使一部分API對外可見。這意味著公共的標頭檔案不允許

ROS學習釋出訊息——Publisher_程式碼分析

//一個非常詳細的版本: //本檔名字為: publisher.cpp #include "ros/ros.h" #include "std_msgs/String.h" #include <i

ROS學習CMakelists.txt和package.xml

package.xml 當你的package裡已經包含配置檔案(package.xml),ROS能夠找到它。執行:rospack find [包名稱]。應該注意到我們剛才所建立的package.xml依賴於 roscpp 和 std_msgs.而catkin恰

ROS學習tf.2.編寫一個TF廣播器(C++)

ROS.tf2.編寫一個tf廣播器(C++)宣告:本教程來自於ROS.WIKI,本人在整理過程中可能出現一些錯誤和問題,有問題可以去檢視官網版本也可以諮詢本人1.1在接下來的兩篇教程中,我們將編寫程式碼來重現tf入門教程中的演示。之後,以下教程將重點介紹使用更高階的tf功能擴