ROS系統起源於2007年斯坦福大學人工智能實驗室的項目與機器人技術公司Willow Garage的我的機器人項目(Personal Robots Program)之間的合做,2008年以後就由Willow Garage來進行推進。node
ROS是開源的,是用於機器人的一種後操做系統,或者說次級操做系統。它提供相似操做系統所提供的功能,包含硬件抽象描述、底層驅動程序管理、共用功能的執行、程序間的消息傳遞、程序發行包管理,它也提供一些工具程序和庫用於獲取、創建、編寫和運行多機整合的程序。bash
瞭解ROS的幾個概念:工具
1. 功能包(Package):至關於一個C++工程,包含程序文件,編譯描述文件,配置文件等。oop
2. 功能包集(Stack):實現某種功能的多個功能包集合,例如導航功能包,是ROS軟件發佈的主要形式。網站
3. 節點(Node):可執行文件。位於功能包中,實現功能的最小單位,.cpp 和.py文件轉換爲可執行文件後才能夠變爲node。ui
4. 主題(Topic)和服務(Service):節點間通訊的兩種方式。主題實現節點之間的單向通訊,服務包括請求(Request)和響應(Response)的雙向通訊。人工智能
5. 消息(Msg):節點之間通訊的內容,至關於C語言中的結構體。spa
安裝ROS,不贅述,參考官方網站,目前主流使用的是Ubuntu14.04+ROS indigo版本。操作系統
ROS會有本身的功能包命令,相似於bash命令,經常使用的有ssr
rospack roscd rosls catkin_create_pkg catkin_make roscore rosrun rosnode rosmsg/rossrv rostopic/rosservice rosparam roslaunch rosbag
具體的操做參考官方文檔,這裏主要使用catkin建立一個簡單的主題發佈訂閱的功能包。節點之間的通訊關係以下圖所示:
目前ROS的官方編譯系統是catkin,功能包分配更加合理,支持交叉編譯,可移植性好。
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace cd ~/catkin_ws // 空的工程也能夠編譯 catkin_make // 更新環境變量,將當前工做空間加入$ROS_PACKAGE_PATH source devel/setup.bash catkin_create_pkg my_topic_test std_msgs roscpp rospy // 打開my_topic_test功能包,重要的是編譯描述文件CMakeLists.txt和配置文件package.xml // 建立完功能包後,須要編譯該功能包,能夠編譯整個空間中的功能包,也能夠只編譯指定的功能包 cd ~/catkin_ws catkin_make // catkin_make --pkg my_topic_test
具體實現node在src目錄下,新建兩個文件分別爲talker.cpp, listener.cpp。注意最後須要修改CMakeLists.txt文件。
// publisher: talker #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; ros::Publisher my_pub = n.advertise<std_msgs::String>("my_topic", 100); ros::Rate loop_rate(1); int cnt = 1; std_msgs::String msg; while(ros::ok()) { std::stringstream ss; if((cnt%2)==0) ss << "false " << cnt; else ss << "true"; msg.data = ss.str(); ROS_INFO("%s", msg.data.c_str()); my_pub.publish(msg); loop_rate.sleep(); cnt = cnt + 1; } return 0; }
// subscriber: listener #include "ros/ros.h" #include "std_msgs/String.h" void MyTopicCallback(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; ros::Subscriber my_sub = n.subscribe("my_topic", 100, MyTopicCallback); ros::spin(); return 0; }
因爲咱們沒有使用本身定義的消息類型,因此package.xml文件不須要更改,CMakeLists.txt文件也比較簡單:
cmake_minimum_required(VERSION 2.8.3) project(my_topic_test) ## 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 xx.msg) #add_service_files(FILES xx.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 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)
注意
其中find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)和include_directories(include ${catkin_INCLUDE_DIRS})的順序不能改變。否則會找不到ros系統的頭文件。
從新編譯功能包後,驗證結果
roscore
rosrun my_topic_test talker
rosrun my_topic_test listener
發佈節點talker向主題my_topic發送消息,同時訂閱my_topic主題的節點接收到消息