ROS学习篇第(四)篇:话题编程、服务编程、参数编程详解

一、话题编程

代码理解

发布者:talker

/*
 *  发布chatter话题,消息类型String
 */
#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"

using namespace ros;
int main(int argc,char **argv)
{
	init(argc,argv,"talker");    //节点初始化,起个名字

	NodeHandle n;                //节点句柄

	Publisher chatter_pub = n.advertise<std_msgs::String>("chatter",100);//创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String

	Rate loop_rate(10); // 设置循环的频率
/* 向 Topic: chatter 发送消息, 发送频率为10Hz(1秒发10次);消息池最大容量100。 */
/* 它将会记录从上次调用Rate::sleep()到现在为止的时间,并且休眠正确的时间。在这个例子中,设置的频率为10hz */
	
	int count=0;
	
	while(ok())
	{
		// 初始化std_msgs::String类型的消息
    		std_msgs::String msg;
    		std::stringstream ss;
    		ss << "hello world " << count;
    		msg.data = ss.str();
 
		// 发布消息
   		 ROS_INFO("%s", msg.data.c_str());
   		 chatter_pub.publish(msg);
	
		// 按照循环频率延时  休眠一下,使程序满足前面所设置的10hz的要求
   		 loop_rate.sleep();
  		  ++count;
	}
	return 0;
}

订阅者:listener

/**
 * 该例程将订阅chatter话题,消息类型String
 */
 
#include "ros/ros.h"
#include "std_msgs/String.h"
 
// 接收到订阅的消息后,会进入消息回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  // 将接收到的消息打印出来
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}
 
int main(int argc, char **argv)
{
  // 初始化ROS节点
  ros::init(argc, argv, "listener");
 
  // 创建节点句柄
  ros::NodeHandle n;
 
  // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
 
  // 循环等待回调函数  这里一定要加  不然他就不会在这里等待回调函数,而是直接结束函数
  ros::spin();
 
  return 0;
}

①ros::spin() 或 ros::spinOnce(),两者区别在于前者调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而后者在调用后还可以继续执行之后的程序,程序写了相关的消息订阅函数,那千万千万千万不要忘了在相应位置加上ros::spin()或者ros::spinOnce()函数

简单测试

在这里插入图片描述

二、服务编程

代码理解

service

/**
 * 该例程执行/turtle_command服务,服务数据类型std_srvs/Trigger
 */

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Trigger.h>

using namespace ros;

Publisher turtle_vel_pub;
bool pubCommand = false;

//service回调函数,输入参数rep,输出参数res
bool commandCallback(std_srvs::Trigger::Request &rep,
			std_srvs::Trigger::Response &res)
{
	pubCommand = !pubCommand;

	//显示请求数据
	ROS_INFO("Publish turtle velocity command[%s]",pubCommand == true?"YES":"NO");
	
	//设置反馈数据
	res.success = true;
	res.message = "Change turtle command state!";

	return true;
}


int main(int argc,char** argv)
{
	init(argc,argv,"turtle_command_server");

	NodeHandle n;
	
	//创建一个名为/turtle_command的server,注册回调函数commandCallback
	ServiceServer command_service = n.advertiseService("/turtle_command",commandCallback);

	//创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度为10
	turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);

	//循环等待回调函数
	ROS_INFO("Ready to receive turtle command.");

	//设置循环的频率
	Rate loop_rate(10);

	while(ok())
	{
	spinOnce();
	
	//如果标志为true,则发布速度指令
	if(pubCommand)	
	{
		geometry_msgs::Twist vel_msg;
		vel_msg.linear.x = 0.5;
		vel_msg.angular.z = 0.2;
		turtle_vel_pub.publish(vel_msg);	
	}	
	//按照循环频率延时
	loop_rate.sleep();
	}
	
}

geometry_msgs 给了我们很多的数据类型包,以后拿来用就好
在这里插入图片描述在这里插入图片描述在这里插入图片描述

client

/**
 * 该例程将请求/spawn服务,服务数据类型turtlesim::Spawn
 */

#include <ros/ros.h>
#include <turtlesim/Spawn.h>
using namespace ros;
int main(int argc,char** argv)
{
	//初始化ros节点
	init(argc,argv,"turtle_spawn");
	//创建节点句柄
	NodeHandle node;
	//发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
	service::waitForService("/spawn");
	ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");

	//初始化turtlesim::Spawn的请求数据
	turtlesim::Spawn srv;
	srv.request.x = 2.0;
	srv.request.y = 2.0;
	srv.request.name = "turtle2";
	//请求服务调用
	ROS_INFO("Call service to spawn turtle[x:%0.6f,y:%0.6f,name:%s]",srv.request.x,srv.request.y,srv.request.name);
	
	//调用call ①发出请求②把数据srv发送出去③在这里等待回复
	add_turtle.call(srv);
	
	//显示服务调用结果
	ROS_INFO("Spawn turtle successfully [name:%s]",srv.response.name.c_str());
	return 0;
}

这里的Spawn:
在这里插入图片描述
rosservice: rosservice call [服务] -----> 相当于发命令的人(我)是 client

add_turtle.call([数据类型]);

[服务]
①自己创建

ros::ServiceServer service = n.advertiseService("name",callback );

②等待,发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service

ros::service::waitForService("/spawn");
ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");

简单测试

在这里插入图片描述在这里插入图片描述

三、参数编程

代码理解

简单测试

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值