ROS Industrial教程(二)

  • 服务

上一个教程建立的ROS通讯是一种称为消息(message)的单向交互,该消息通过称为主题(topic)的渠道发送。 现在,我们将探索一种不同的通信类型,即通过一个节点到另一个节点的请求(request)以及该节点到第一个节点的响应(response)进行的双向交互。 在这个模块中,我们将创建一个服务服务器service server(等待请求并提供响应)和客户端client(请求信息,然后等待响应)。

创建Service定义

1. 在myworkcell_core程序包中创建一个名为srv的文件夹(与程序包的src文件夹处于同一级别)

cd ~/catkin_ws/src/myworkcell_core

mkdir srv

 

2. 在srv文件夹下创建文件 LocalizePart.srv

 

3.编辑LocalizePart.srv文件,添加:

#request

string base_frame

---

#response

geometry_msgs/Pose pose

 

4. 编辑程序包的CMakeLists.txt 和 package.xml:

message_generation 从上一步中创建的.srv文件构建C ++代码是必需的

message_runtime 提供新消息的运行时依赖性

geometry_msgs 提供我们的服务定义中使用的Pose消息类型

4.1 编辑程序包的CMakeLists.txt file 以增加构建依赖:

find_package(catkin REQUIRED COMPONENTS

  roscpp

  fake_ar_publisher

  geometry_msgs

  message_generation

)

 

4.2编辑程序包的CMakeLists.txt file 以增加运行依赖:

catkin_package(

#  INCLUDE_DIRS include

#  LIBRARIES myworkcell_node

  CATKIN_DEPENDS

    roscpp

    fake_ar_publisher

    message_runtime

    geometry_msgs

#  DEPENDS system_lib

)

4.3 编辑package.xml file以增加构建/运行依赖:

<build_depend>message_generation</build_depend>

<exec_depend>message_runtime</exec_depend>

<depend>geometry_msgs</depend>

 

5. 编辑程序包的CMakeLists.txt,添加规则以生成新的服务文件:

5.1 取消注释/编辑以下CMakeLists.txt规则以引用我们之前定义的LocalizePart服务:

## Generate services in the 'srv' folder

add_service_files(

   FILES

   LocalizePart.srv

)

 

5.2 取消注释/编辑以下CMakeLists.txt规则以启用消息和服务的生成:

## Generate added messages and services with any dependencies listed here

generate_messages(

   DEPENDENCIES

   geometry_msgs

)

 

服务服务器Server

编辑vision_node.cpp文件:

添加头文件:

#include <myworkcell_core/LocalizePart.h>

Localizer类里添加:

添加成员变量

ros::ServiceServer server_;

在Localizer类的构造函数中初始化此变量,将服务发布给ROS主服务器master:

server_ = nh.advertiseService("localize_part", &Localizer::localizePart, this);

       上面的advertiseService命令引用了名为localizePart的服务回调。 在Localizer类中使用此名称创建一个布尔函数。 请记住,您的请求和响应类型是在LocalizePart.srv文件中定义的。 布尔函数的参数是请求和响应类型,其一般结构为Package :: ServiceName :: Request或Package :: ServiceName :: Response。localizePart回调函数中的服务响应。 最终,此回调会将从fake_ar_publisher(在visionCallback中)收到的姿势转换为服务请求中指定的帧。 现在,我们将跳过帧转换,仅传递从fake_ar_publisher接收的数据。 将从fake_ar_publisher接收到的姿势测量值(保存到last_msg_)直接复制到服务响应中。

bool localizePart(myworkcell_core::LocalizePart::Request& req,

                  myworkcell_core::LocalizePart::Response& res)

{

  // Read last message

  fake_ar_publisher::ARMarkerConstPtr p = last_msg_; 

  if (!p) return false;

 

  res.pose = p->pose.pose;

  return true;

}

在visionCallback函数中注释掉ROS_INFO_STREAM调用,以避免不必要的信息使屏幕混乱。

服务客户端Client

在同一个myworkcell_core包中创建一个新节点,名为myworkcell_node.cpp。 这最终将是我们的主要“应用程序节点”,它控制“扫描与计划”任务中的操作顺序。 我们将执行的第一个操作是从我们在上面创建的视觉节点的LocalizePart服务中请求AR目标的位置。

添加头文件

#include <ros/ros.h>

#include <myworkcell_core/LocalizePart.h>

Main函数

int main(int argc, char **argv)

{

  ros::init(argc, argv, "myworkcell_node");

  ros::NodeHandle nh;

 

  ROS_INFO("ScanNPlan node has been initialized");

 

  ScanNPlan app(nh);

 

  ros::Duration(.5).sleep();  // wait for the class to initialize

  app.start();

 

  ros::spin();

}

添加类ScanNPlan,在新的ScanNPlan类中,将ROS ServiceClient定义为该类的私有成员变量。 使用与先前定义的相同的服务名称(“ localize_part”)在ScanNPlan构造函数中初始化ServiceClient 在名为startScanNPlan类内创建一个无参数的void函数。 这将包含我们大部分的应用程序工作流程。 现在,此函数将调用LocalizePart服务并打印响应。

class ScanNPlan

{

public:

  ScanNPlan(ros::NodeHandle& nh)

  {

    vision_client_ = nh.serviceClient<myworkcell_core::LocalizePart>("localize_part");

  }

 

  void start()

  {

    ROS_INFO("Attempting to localize part");

    // Localize the part

    myworkcell_core::LocalizePart srv;

    if (!vision_client_.call(srv))

    {

      ROS_ERROR("Could not localize part");

      return;

    }

    ROS_INFO_STREAM("part localized: " << srv.response);

  }

 

private:

  // Planning components

  ros::ServiceClient vision_client_;

};

编辑程序包的CMakeLists.txt,以构建新节点(可执行文件)及其相关的依存关系。 将以下规则直接添加到vision_node的匹配规则下的相应部分中:

add_executable(myworkcell_node src/myworkcell_node.cpp)

 

add_dependencies(myworkcell_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

 

target_link_libraries(myworkcell_node ${catkin_LIBRARIES})

重新构建工程

使用服务

roscore

rosrun fake_ar_publisher fake_ar_publisher_node

rosrun myworkcell_core vision_node

rosrun myworkcell_core myworkcell_node

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值