ROS話題通信案例(三)——自定義消息msg(c++和python)


參考視頻:【奧特學園】ROS機器人入門課程《ROS理論與實踐》零基礎教程_嗶哩嗶哩_bilibili

參考文檔:http://www.autolabor.com.cn/book/ROSTutorials/

需求:

  創建自定義消息,該消息包含人的信息:姓名、身高、年齡等。

流程:

  1. 按照固定格式創建 msg 文件
  2. 編輯配置文件
  3. 編譯生成可以被 Python 或 C++ 調用的中間文件

1.定義msg文件

功能包下新建 msg 目錄,添加文件 Person.msg

string name
uint16 age
float64 height

2.編輯配置文件

package.xml中添加編譯依賴與執行依賴

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前對應的是 run_depend 現在非法
  -->

CMakeLists.txt編輯 msg 相關配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必須有 std_msgs

## 配置 msg 源文件
add_message_files(
  FILES
  Person.msg
)

# 生成消息時依賴於 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)

#執行時依賴
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

 

 

3.編譯

編譯后的中間文件查看:

C++ 需要調用的中間文件(.../工作空間/devel/include/包名/xxx.h)

Python 需要調用的中間文件(.../工作空間/devel/lib/python3/dist-packages/包名/msg)


 

C++實現

需求:

編寫發布訂閱實現,要求發布方以10HZ(每秒10次)的頻率發布自定義消息,訂閱方訂閱自定義消息並將消息內容打印輸出。

分析:

在模型實現中,ROS master 不需要實現,而連接的建立也已經被封裝了,需要關注的關鍵點有三個:

  1. 發布方
  2. 接收方
  3. 數據(此處為自定義消息)

流程:

  1. 編寫發布方實現;
  2. 編寫訂閱方實現;
  3. 編輯配置文件;
  4. 編譯並執行

0.vscode 配置

為了方便代碼提示以及避免誤拋異常,需要先配置 vscode,將前面生成的 head 文件路徑配置進 c_cpp_properties.json 的 includepath屬性

"/xxx/yyy工作空間/devel/include/**" //配置 head 文件的路徑 

1.發布方

#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
/*
    發布者:發布人的消息
        1.包含頭文件;
        2.初始化ROS節點
        3.創建節點句柄
        4.創建發布者對象
        5.編寫發布者邏輯,發布數據。
*/
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ROS_INFO("這是消息發布方");
    // 2.初始化ROS節點
    ros::init(argc,argv,"banZhuanRen");
    // 3.創建節點句柄
    ros::NodeHandle nh;
    // 4.創建發布者對象
    ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("Chat",10);
    // 5.編寫發布者邏輯,發布數據。
    //5.1.被發布的數據
    plumbing_pub_sub::Person person;
    person.name = "張三";
    person.age = 1;
    person.height = 1.73;
    //5.2.設置發布的頻率
    ros::Rate rate(1);
    //5.3.循環發布數據
    while (ros::ok())
    {
        //修改數據
        person.age += 1;
        //核心:數據發布
        pub.publish(person);
        ROS_INFO("發布的消息:%s,%d,%.2f",person.name.c_str(),person.age,person.height);
        //休眠
        rate.sleep();
        //建議
        ros::spinOnce();

    }
    return 0;
}
    

配置

執行

2.訂閱方

#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"

/*
    訂閱方:訂閱消息
        1.包含頭文件;
            #include "plumbing_pub_sub/Person.h"
        2.初始化ROS節點
        3.創建節點句柄
        4.創建訂閱者對象
        5.處理訂閱的數據
        6.調用spin()函數
*/
void doPerson (const plumbing_pub_sub::Person::ConstPtr& person){
    ROS_INFO("訂閱人的信息:%s,%d,%.2f",person->name.c_str(),person->age,person->height);
}
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ROS_INFO("訂閱方實現");
    // 2.初始化ROS節點
    ros::init(argc,argv,"jiaZhang");
    // 3.創建節點句柄
    ros::NodeHandle nh;
    // 4.創建訂閱者對象
    ros::Subscriber sub = nh.subscribe("Chat",10,doPerson);
    // 5.處理訂閱的數據
    // 6.調用spin()函數
    ros::spin();
    return 0;
}

配置

執行

 


python 實現

0.vscode配置

將自定義 msg 所在的文件夾配置進 settings.json

1.發布方

在 scripts 下新建 demo03_pub_person_p.py

#! /usr/bin/env python

import rospy
from plumbing_pub_sub.msg import Person
'''
    發布方:發布人的消息
        1.導包;
        2.初始化ROS節點;
        3.創建發布者對象;
        4.組織發布邏輯並發布數據。

'''

if __name__ == "__main__":
    # 2.初始化ROS節點;
    rospy.init_node("daMa")
    # 3.創建發布者對象;
    pub = rospy.Publisher("jiaoSheTou",Person,queue_size=10)
    # 4.組織發布邏輯並發布數據。
    # 4.1.創建 Person 數據
    p = Person()
    p.name = "奧特曼"
    p.age = 8
    p.height = 1.85
    # 4.2.創建 Rate 對象
    rate = rospy.Rate(1)
    # 4.3.循環發布數據
    while not rospy.is_shutdown():
        pub.publish(p)
        rospy.loginfo("發布的消息:%s,%d,%.2f",p.name,p.age,p.height)
        rate.sleep()

2.權限設置

給 py 文件增加可執行權限

cys@ubuntu:~/demo03_ws/src/plumbing_pub_sub/scripts$ chmod +x *.py

3.配置 CMakeLists.txt

更改 CMakeLists.txt 中的配置

 4.命令行測試

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rosrun plumbing_pub_sub demo03_pub_person_p.py

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rostopic echo jiaoSheTou

5.訂閱方

 在 scripts 下新建 demo04_sub_person_p.py

#! /usr/bin/env python

import rospy
from plumbing_pub_sub.msg import Person
'''
    訂閱方:訂閱人的消息
        1.導包;
        2.初始化ROS節點;
        3.創建訂閱者對象;
        4.處理訂閱的數據;
        5.spin()。

'''
def doPerson(p):
    rospy.loginfo("小伙子的數據:%s,%d,%.2f",p.name,p.age,p.height)

if __name__ == "__main__":
    # 2.初始化ROS節點;
    rospy.init_node("daYe")
    # 3.創建訂閱者對象;
    sub = rospy.Subscriber("jiaoSheTou",Person,doPerson)
    # 4.處理訂閱的數據;
    # 5.spin()。
    rospy.spin()

修改權限和配置

 6.運行

啟動發布方

啟動訂閱方

cys@ubuntu:~/demo03_ws$ source ./devel/setup.bash
cys@ubuntu:~/demo03_ws$ rosrun plumbing_pub_sub demo04_sub_person_p.py 

 7.繪制計算圖

cys@ubuntu:~$ rqt_graph 

 


免責聲明!

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



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