关于如何利用rosserial在windows和linux间实现service服务

    利用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

    --未完待续

你可能感兴趣的:(ROS相关)