ros的幾種通訊機制及程式碼

vrjiheid發表於2020-11-04

參考

  • 古月居
  • ROS機器人開發實踐

話題(topic)

釋出者(publisher)

/**
 * 該例程將釋出/person_info話題,自定義訊息型別learning_topic::Person
 */
 
#include <ros/ros.h>
#include "learning_topic/Person.h"

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

    // 建立節點控制程式碼
    ros::NodeHandle n;

    // 建立一個Publisher,釋出名為/person_info的topic,訊息型別為learning_topic::Person,佇列長度10
    ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);

    // 設定迴圈的頻率 1Hz
    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;

        // 釋出訊息
		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);

        // 按照迴圈頻率延時
        loop_rate.sleep();
    }

    return 0;
}

訂閱者(subscriber)

/**
 * 該例程將訂閱/person_info話題,自定義訊息型別learning_topic::Person
 */
 
#include <ros/ros.h>
#include "learning_topic/Person.h"

// 接收到訂閱的訊息後,會自動以訊息指標作為引數,進入訊息回撥函式,完成對訊息內容的處理
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節點
    ros::init(argc, argv, "person_subscriber");

    // 建立節點控制程式碼
    ros::NodeHandle n;

    // 建立一個Subscriber,訂閱名為/person_info的topic,10是接受訊息佇列的大小,註冊回撥函式personInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

    // 迴圈等待回撥函式
    ros::spin();

    return 0;
}

服務(service)

服務端(server)

/**
 * 該例程將執行/show_person服務,服務資料型別learning_service::Person
 */
 
#include <ros/ros.h>
#include "learning_service/Person.h"

// service回撥函式,輸入引數req,輸出引數res
bool personCallback(learning_service::Person::Request  &req,
         			learning_service::Person::Response &res)
{
    // 顯示請求資料
    ROS_INFO("Person: name:%s  age:%d  sex:%d", req.name.c_str(), req.age, req.sex);

	// 設定反饋資料
	res.result = "OK";

    return true;
}

int main(int argc, char **argv)
{
    // ROS節點初始化
    ros::init(argc, argv, "person_server");

    // 建立節點控制程式碼
    ros::NodeHandle n;

    // 建立一個名為/show_person的server,註冊回撥函式personCallback
    ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);

    // 迴圈等待回撥函式
    ROS_INFO("Ready to show person informtion.");
    ros::spin();

    return 0;
}


客戶端(client)

/**
 * 該例程將請求/show_person服務,服務資料型別learning_service::Person
 */

#include <ros/ros.h>
#include "learning_service/Person.h"

int main(int argc, char** argv)
{
    // 初始化ROS節點
	ros::init(argc, argv, "person_client");

    // 建立節點控制程式碼
	ros::NodeHandle node;

    // 發現/spawn服務後,建立一個服務客戶端,連線名為/spawn的service
	ros::service::waitForService("/show_person");
	ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");

    // 初始化learning_service::Person的請求資料
	learning_service::Person srv;
	srv.request.name = "Tom";
	srv.request.age  = 20;
	srv.request.sex  = learning_service::Person::Request::male;

    // 請求服務呼叫
	ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", 
			 srv.request.name.c_str(), srv.request.age, srv.request.sex);

	person_client.call(srv);

	// 顯示服務呼叫結果
	ROS_INFO("Show person result : %s", srv.response.result.c_str());

	return 0;
};


動作(action)

相關文章