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功能擴