利用rosserial在windows和linux间实现话题的发布订阅可以参考roswiki
博主需要在windows上给linux上位机发送机器人的位置坐标,自动导航到目标点后由linux反馈给windows执行结果,按理应当是用actionlib的方式最为恰当,当时觉得比较麻烦,就准备采用service服务来实现。
不巧的是教程中也米有关于service的例子,只好摸黑前行。
第一个问题是,rosserial能不能实现service服务。参考rosserial issues【1】、【2】得出结论,理应支持。
第二个问题,生成需要的SRV头文件:GoalAndRespond.srv,参考【3】,博主需要发送的是一串坐标,接受布尔值是否成功。
geometry_msgs/PoseArray goals
---
bool success
然后利用rosserial_windows制成ros_lib打包到windows工程目录下以及相应的设置,【4】。
注:博主使用WIN7,VS2012,在编译过程中会出现找不到math.h中的round()函数,于是自己手动写了一个。
第三个问题,在linux编写service的server.cpp可以参考常规教程,【5】,那么如何在windows上编写service的client.cpp呢?
1、包含头文件
#include "simple_navigation_goals/GoalAndRespond.h"
其中simple_navigation_goals是srv文件所在包名,GoalAndRespond.h是上面ros_lib自动生成的头文件
2、创建client对象
在linux中,client对象的创建,send_goals表示service名
ros::ServiceClient client = n.serviceClient("send_goals");
然而在windows就不能这样定义,有没有参考案例,只能看ros::ServiceClient的头文件,位于ros_lib\ros\service_client.h,其中关于构造函数的原型如下:
template
class ServiceClient : public Subscriber_
{
public:
ServiceClient(const char* topic_name) :
pub(topic_name, &req, rosserial_msgs::TopicInfo::ID_SERVICE_CLIENT + rosserial_msgs::TopicInfo::ID_PUBLISHER)
{
this->topic_ = topic_name;
this->waiting = true;
}
初始化参数列表只要一个service的名字,注意要和linux里server.cpp中定义的service名一致,但这是个模版类,故而要加上service的类型。关于自定义srv头文件位于ros_lib\ros\simple_navigation_goals\GoalAndRespond.h,包括request和respond,原型如下:
class GoalAndRespondRequest : public ros::Msg
{
public:
typedef geometry_msgs::PoseArray _goals_type;
_goals_type goals;
GoalAndRespondRequest():
goals()
{
}
Request : public ros::Msg
{
public:
typedef geometry_msgs::PoseArray _goals_type;
_goals_type goals;
GoalAndRespondRequest():
goals()
{
}
class GoalAndRespondResponse : public ros::Msg
{
public:
typedef bool _success_type;
_success_type success;
GoalAndRespondResponse():
success(0)
{
}
class GoalAndRespond {
public:
typedef GoalAndRespondRequest Request;
typedef GoalAndRespondResponse Response;
};
首先初始化节点和linux所在上位机的IP
ros::NodeHandle nh;
char *ros_master = "192.168.1.112";
nh.initNode (ros_master);
然后分别定义request和respond对象:
simple_navigation_goals::GoalAndRespond::Request req;
simple_navigation_goals::GoalAndRespond::Response res;
最后定义ServiceClient对象,并且将其赋予节点句柄:
ros::ServiceClient client("send_goals");
nh.serviceClient(client)
这样,初始化工作就完成了。
3、发布service
--未完待续