ROS節點通信(一)消息發布和訂閱


1、說明

編寫完ROS的hello world程序后,基本可以了解ROS的功能包開發的流程,現在再編寫一個節點通信的測試代碼,使用 topic 模式,即發布-訂閱者模式,且傳遞的消息是自定義類型

上代碼

2、創建工作空間

該例不再創建新的工作空間,和hello world示例共用一個

3、創建功能包

cd src
catkin_create_pkg test_topic message_generation std_msgs roscpp

這里在創建功能包的時候,順帶把需要依賴的庫也加進去了,好處就是,會默認把依賴庫添加到 CMakeLists.txt 和 package.xml 中,而在 hello world 例子中,是手動添加的

message_generation 會根據自定義類型的描述文件生成代碼

std_msgs 是ROS的字符串類

這個功能包的名稱就是 test_topic

4、編寫自定義傳輸類型文件

cd test_topic
mkdir msg && cd msg
touch MessageDefine.msg

編輯 MessageDefine.msg 文件,內容如下:

time stamp
int32 data
string speak

這里有三種類型,time 會生成ROS的Time類,這里不做詳細說明

5、編寫源代碼

cd ../src

依照慣例,代碼還是放在src目錄下

5.1、編寫發布者代碼

新增文件 test_publisher.cpp,代碼如下:

#include <ros/ros.h>
#include <test_topic/MessageDefine.h>

int main(int argc, char **argv)
{
    //初始化發布者節點名稱
    ros::init(argc, argv, "topic_publisher");
    //聲明節點句柄與ROS系統進行通訊
    ros::NodeHandle nh;               
    //聲明發布者,創建一個使用test_topic功能包MessageDefine消息文件的發布者
    //ros_tutorial_pub,話題名稱是ros_message,消息發布者隊列設置為100,如果消息發送太快,緩沖區的消息大於100,則會丟棄隊列頭
    ros::Publisher ros_tutorial_pub = nh.advertise<test_topic::MessageDefine>("ros_message", 100);
    //設定循環周期0.25HZ,4秒,需要配合sleep方法使用
    ros::Rate loop_rate(0.25);
    test_topic::MessageDefine msg; //聲明一個消息
    int count = 0;
    std::stringstream talk;
    while (ros::ok())
    {
        //給MessageDefine.msg文件中的消息變量賦值
        msg.stamp = ros::Time::now();
        msg.data = count;
        msg.speak = "hello world, number: " + std::to_string(count);
        ROS_INFO("send stamp second = %d", msg.stamp.sec); //顯示消息
        ROS_INFO("send data = %d", msg.data);
        ROS_INFO("%s", msg.speak.c_str());
        ros_tutorial_pub.publish(msg); //發布顯示的消息
        ros::spinOnce();               //循環等待訂閱節點的所有回調函數
        loop_rate.sleep();             //按設定值循環
        ++count;
    }
    return 0;
}

這里的 ros_message 是topic名稱

5.2、編寫訂閱者代碼

ros_message新增 test_subscriber.cpp,代碼如下:

#include <ros/ros.h>
#include <test_topic/MessageDefine.h>

//回調函數
void messageCallback(const test_topic::MessageDefine::ConstPtr &msg)
{
    ROS_INFO("recieve stamp second = %d", msg->stamp.sec);
    ROS_INFO("recieve data = %d", msg->data);
    ROS_INFO("receive str:[%s]", msg->speak.c_str());
}
int main(int argc, char **argv)
{
    ros::init(argc, argv, "topic_subscriber"); //初始化訂閱者節點
    ros::NodeHandle nh;
    //聲明訂閱者,創建一個使用test_topic功能包MessageDefine消息文件的訂閱者
    //ros_tutorial_sub,訂閱的話題名稱是ros_message,消息接收者隊列設置為100,如果消息處理太慢,緩沖區的消息數量大於100,則丟棄隊列頭部的消息
    ros::Subscriber ros_tutorial_sub = nh.subscribe<test_topic::MessageDefine>("ros_message", 100, messageCallback);
    ros::spin(); //調用后台,等待接收消息
    return 0;
}

ros::spin() 讓程序進入自循環的掛起狀態,讓程序以最好的效率接收並執行回調

當有消息達到 ros_message 時,執行一次回調函數

6、編譯

修改編譯配置

因為創建功能包的時候,顯示地指定了依賴,這些依賴會自動寫進 CMakeLists.txt 和 package.xml 文件中,CMakeLists.txt 需要簡單修改,package.xml文件無需改動

CMakeLists.txt 文件如下

cmake_minimum_required(VERSION 3.0.2)
project(test_topic)

add_compile_options(-std=c++11)

#依賴庫,創建包的時候添加了依賴,這里自動生成
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  std_msgs
)

#添加自定義類型文件,這里自動生成的代碼中注釋說在msg文件夾下
## Generate messages in the 'msg' folder
add_message_files(
  FILES
  MessageDefine.msg
)
generate_messages(
  DEPENDENCIES
  std_msgs
)
catkin_package(
 LIBRARIES test_topic
 CATKIN_DEPENDS roscpp std_msgs
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

#以下內容需要手動添加修改
add_executable(${PROJECT_NAME}_publisher_node src/test_publisher.cpp)
target_link_libraries(${PROJECT_NAME}_publisher_node  ${catkin_LIBRARIES})

add_executable(${PROJECT_NAME}_subscriber_node src/test_subscriber.cpp)
target_link_libraries(${PROJECT_NAME}_subscriber_node  ${catkin_LIBRARIES})

編譯指定包

catkin_make -DCATKIN_WHITELIST_PACKAGES="test_topic"

7、啟動運行

該例的包名為 test_topic,連個節點名是 test_topic_publisher_nodetest_topic_subscriber_node

先啟動節點管理器

roscore

啟動發布者節點

cd ~/project/catkin_ws
source devel/setup.bash
rosrun test_topic test_topic_publisher_node

啟動訂閱者節點

cd ~/project/catkin_ws
source devel/setup.bash
rosrun test_topic test_topic_subscriber_node

查看效果,發布者每隔一段時間發送數據,訂閱者接收到數據,打印出來

8、查看ROS網絡結構圖

rqt_graph

結構圖如下:

img


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM