跟古月居學(xué)ros:話題消息的定義與使用

前面我們已經(jīng)學(xué)習(xí)了publisher如何向ros發(fā)布消息传透,subscriber如何從ros接收消息晓殊。那publisher和subscriber之間能由什么聯(lián)系呢塞椎?這節(jié)課我們來學(xué)習(xí)publisher向subscriber發(fā)送自定義的信息裹赴。

定義msg文件

首先在文件夾learning_topic中新建一個(gè)命名為msg的文件夾尔许,這個(gè)文件夾用來存放后續(xù)的消息類文件

進(jìn)入該文件夾下并在該文件夾下打開命令行么鹤,使用touch指令新建Person.msg文件

打開該文件,輸入以下信息后保存

string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male = 1
uint8 female = 2

這里寫的并不是cpp母债,也不是python午磁。但他在編譯過程中會(huì)由ros自動(dòng)編譯成cpp或python

在package.xml中添加功能包依賴

打開文件夾learning_topic,打開package.xml毡们。如果你的電腦安裝了瀏覽器迅皇,xml文件可能會(huì)由瀏覽器默認(rèn)打開,不能編輯衙熔〉峭牵可以在這個(gè)目錄下打開命令行,可以輸入以下指令打開

gedit package.xml

滾動(dòng)到最下方红氯,在如圖所示位置添加以下語(yǔ)句框咙,保存

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

<build_depend>用于添加編譯依賴咕痛,這里添加message_generation功能包
<exec_depend<用于添加執(zhí)行依賴,這里添加message_runtime功能包

在CMakeLists.txt添加編譯選項(xiàng)

打開文件夾learning_topic喇嘱,打開CMakeLists.txt茉贡。

  1. 在最上方的find_package中添加message_generation
sendpix17.jpg
  1. 找到Declare ROS dynamic reconfigure parameters的位置,在上方添加如下語(yǔ)句
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
  • 第一句話者铜,告訴編譯器Person.msg是我們定義的消息接口
  • 第二句話腔丧,告訴編譯器在編譯Person.msg文件的時(shí)候,需要依賴哪些庫(kù)/包作烟。這里我們需要依賴std_msgs愉粤,剛剛我們寫的如stringuint8拿撩,就是在std_msgs中定義的衣厘。
  1. 找到catkin specific configuration(即Build上方),在圖示位置添加以下語(yǔ)句(我這里比較特殊压恒,正上方的注釋掉的語(yǔ)句與要添加的語(yǔ)句一模一樣影暴,這種情況可以不添加新語(yǔ)句而是直接把那句話的注釋解除掉)
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim

做完以上三步,保存退出涎显。

回到工作空間的根目錄catkin_ws下坤检,打開命令行兴猩,嘗試進(jìn)行編譯期吓。輸入指令

catkin_make

編譯成功,可以在圖示的路徑下倾芝,找到剛剛編寫的Person.msg文件已經(jīng)被編譯成為Person.h文件

編寫cpp程序

在圖示路徑下建立兩個(gè)cpp文件讨勤。代碼如下


person_publisher.cpp

/**
 * 該例程將發(fā)布/person_info話題,自定義消息類型learning_topic::Person
 */
 
#include <ros/ros.h>
//3苛怼L肚А!=枘颉刨晴!關(guān)鍵!B贩1否!茂契!
#include "learning_topic/Person.h"

int main(int argc, char **argv)
{
    // ROS節(jié)點(diǎn)初始化
    ros::init(argc, argv, "person_publisher");

    // 創(chuàng)建節(jié)點(diǎn)句柄
    ros::NodeHandle n;

    // 創(chuàng)建一個(gè)Publisher蝶桶,發(fā)布名為/person_info的topic,消息類型為learning_topic::Person掉冶,隊(duì)列長(zhǎng)度10
    //U媸F暄!;止病战秋!關(guān)鍵!L志隆;裱!拐袜!
    ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);

    // 設(shè)置循環(huán)的頻率
    ros::Rate loop_rate(1);

    int count = 0;
    while (ros::ok())
    {
        // 初始化learning_topic::Person類型的消息
        learning_topic::Person person_msg;
        person_msg.name = "Tom";
        person_msg.age  = 18;
        person_msg.sex  = learning_topic::Person::male;

        // 發(fā)布消息
        person_info_pub.publish(person_msg);

        ROS_INFO("Publish Person Info: name:%s  age:%d  sex:%d", 
                  person_msg.name.c_str(), person_msg.age, person_msg.sex);

        // 按照循環(huán)頻率延時(shí)
        loop_rate.sleep();
    }

    return 0;
}

person_subscriber.cpp

/**
 * 該例程將訂閱/person_info話題吉嚣,自定義消息類型learning_topic::Person
 */
 
#include <ros/ros.h>
//!5牌獭3⒍摺!甜攀!關(guān)鍵G镄埂!9娣А:阈颉!
#include "learning_topic/Person.h"

// 接收到訂閱的消息后谁撼,會(huì)進(jìn)入消息回調(diào)函數(shù)
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
    // 將接收到的消息打印出來
    ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", 
             msg->name.c_str(), msg->age, msg->sex);
}

int main(int argc, char **argv)
{
    // 初始化ROS節(jié)點(diǎn)
    ros::init(argc, argv, "person_subscriber");

    // 創(chuàng)建節(jié)點(diǎn)句柄
    ros::NodeHandle n;

    // 創(chuàng)建一個(gè)Subscriber歧胁,訂閱名為/person_info的topic,注冊(cè)回調(diào)函數(shù)personInfoCallback
    //@鞯:拔 !9抗摹崭参!關(guān)鍵!?羁А:文骸!铐殃!
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

    // 循環(huán)等待回調(diào)函數(shù)
    ros::spin();

    return 0;
}

cpp文件編寫好后海洼,編寫圖示路徑下的CMakeLists.txt文件,對(duì)剛剛編寫的內(nèi)容進(jìn)行配置背稼。

找到Install位置的上方贰军,添加以下語(yǔ)句。保存
說明:這里相比之前配置CMakeLists.txt,多了add_dependencies的語(yǔ)句目的是讓可執(zhí)行文件(前兩句做的工作)和動(dòng)態(tài)生成的文件產(chǎn)生依賴關(guān)系

add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)

add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)

編譯词疼、運(yùn)行

步驟和之前的完全一樣俯树。

  1. 回到工作空間根目錄catkin_ws,運(yùn)行
catkin_make
  1. 新開一個(gè)終端贰盗,執(zhí)行
roscore
  1. 新開一個(gè)終端许饿,執(zhí)行
rosrun learning_topic person_subscriber
  1. 新開一個(gè)終端,執(zhí)行
rosrun learning_topic person_publisher

消息發(fā)送者publisher和消息接收者subscriber已經(jīng)構(gòu)建聯(lián)系

概念:ROS Master是幫助節(jié)點(diǎn)的創(chuàng)建和鏈接的舵盈。節(jié)點(diǎn)一旦創(chuàng)建和鏈接后陋率,就不受ROS Master影響

此時(shí),在執(zhí)行命令roscore的終端按ctrl+c退出roscore(即退出ROS Master)秽晚,會(huì)發(fā)現(xiàn)subscriber和publisher還在收發(fā)數(shù)據(jù)瓦糟。

除非是需要再訪問ROS Master介入的參數(shù)

python代碼實(shí)現(xiàn)

在圖示路徑下建立python文件,代碼如下

右鍵你的python文件赴蝇,選擇properties菩浙,務(wù)必確保Allow executing files as program選項(xiàng)是打鉤的

person_publisher.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 該例程將發(fā)布/person_info話題,自定義消息類型learning_topic::Person

import rospy
from learning_topic.msg import Person

def velocity_publisher():
    # ROS節(jié)點(diǎn)初始化
    rospy.init_node('person_publisher', anonymous=True)

    # 創(chuàng)建一個(gè)Publisher句伶,發(fā)布名為/person_info的topic劲蜻,消息類型為learning_topic::Person,隊(duì)列長(zhǎng)度10
    person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)

    #設(shè)置循環(huán)的頻率
    rate = rospy.Rate(10) 

    while not rospy.is_shutdown():
        # 初始化learning_topic::Person類型的消息
        person_msg = Person()
        person_msg.name = "Tom";
        person_msg.age  = 18;
        person_msg.sex  = Person.male;

        # 發(fā)布消息
        person_info_pub.publish(person_msg)
        rospy.loginfo("Publsh person message[%s, %d, %d]", 
                person_msg.name, person_msg.age, person_msg.sex)

        # 按照循環(huán)頻率延時(shí)
        rate.sleep()

if __name__ == '__main__':
    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass

person_subscriber.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 該例程將訂閱/person_info話題考余,自定義消息類型learning_topic::Person

import rospy
from learning_topic.msg import Person

def personInfoCallback(msg):
    rospy.loginfo("Subcribe Person Info: name:%s  age:%d  sex:%d", 
             msg.name, msg.age, msg.sex)

def person_subscriber():
    # ROS節(jié)點(diǎn)初始化
    rospy.init_node('person_subscriber', anonymous=True)

    # 創(chuàng)建一個(gè)Subscriber先嬉,訂閱名為/person_info的topic,注冊(cè)回調(diào)函數(shù)personInfoCallback
    rospy.Subscriber("/person_info", Person, personInfoCallback)

    # 循環(huán)等待回調(diào)函數(shù)
    rospy.spin()

if __name__ == '__main__':
    person_subscriber()
  1. 新開一個(gè)終端楚堤,執(zhí)行
roscore
  1. 新開一個(gè)終端疫蔓,執(zhí)行
rosrun learning_topic person_subscriber.py
  1. 新開一個(gè)終端,執(zhí)行
rosrun learning_topic person_publisher.py
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钾军,一起剝皮案震驚了整個(gè)濱河市鳄袍,隨后出現(xiàn)的幾起案子绢要,更是在濱河造成了極大的恐慌吏恭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件重罪,死亡現(xiàn)場(chǎng)離奇詭異樱哼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剿配,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門搅幅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呼胚,你說我怎么就攤上這事茄唐。” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵沪编,是天一觀的道長(zhǎng)呼盆。 經(jīng)常有香客問我,道長(zhǎng)蚁廓,這世上最難降的妖魔是什么访圃? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮相嵌,結(jié)果婚禮上腿时,老公的妹妹穿的比我還像新娘。我一直安慰自己饭宾,他們只是感情好批糟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著看铆,像睡著了一般跃赚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上性湿,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天纬傲,我揣著相機(jī)與錄音,去河邊找鬼肤频。 笑死叹括,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宵荒。 我是一名探鬼主播汁雷,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼报咳!你這毒婦竟也來了侠讯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤暑刃,失蹤者是張志新(化名)和其女友劉穎厢漩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岩臣,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溜嗜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了架谎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炸宵。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谷扣,靈堂內(nèi)的尸體忽然破棺而出土全,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布裹匙,位于F島的核電站野哭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏幻件。R本人自食惡果不足惜拨黔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绰沥。 院中可真熱鬧篱蝇,春花似錦、人聲如沸徽曲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)秃臣。三九已至涧衙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奥此,已是汗流浹背弧哎。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稚虎,地道東北人撤嫩。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蠢终,于是被迫代替她去往敵國(guó)和親序攘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容