改进ur_modern_driver包,提供ur_driver/URScript_srv服务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yimiyangguang185/article/details/87804693

虽然ur_modern_driver包订阅了话题ur_driver/URScript(消息类型std_msgs/String),允许我们向该话题发布URScript脚本命令,但是由于ros话题“有去无回”,我们不知道ur_driver节点有没有接收到消息以及什么时候接收到的消息;为了保证机器人接收到运动指令,只能通过循环不断发送消息,这是十分不方便的。因此我们在ur_modern_driver包的基础上,创建一个ros服务。

  • 首先创建service

//在ur_msgs包中添加srv/urscript.srv,内容如下:

string script
---
bool success

//改写ur_msgs包的CMakeLists.txt文件,添加如下内容:

add_service_files(
   FILES   
   urscript.srv
)

//编译ur_msgs包

catkin_make -DCATKIN_WHITELIST_PACKAGES="ur_msgs"

//此时,在catkin_ws/devel/include目录下会生成urscript.h,在要用到这个服务的文件中添加如下头文件:

#include "ur_msgs/urscript.h"
  • 然后在ur_modern_driver包中添加服务器

//在ur_modern_driver包中的urscript_handler.h文件中添加头文件:

#include "ur_msgs/urscript.h"

//在URScriptHandler类中添加成员变量

ros::ServiceServer urscript_srv_;

//在类的实现文件urscript_handler.cpp中的构造函数中初始化

urscript_srv_ = nh_.advertiseService("ur_driver/URScript_srv", &URScriptHandler::urscriptInterface_srv,this);

//此处,“ur_driver/URScript_srv”为该服务的名称,URScriptHandler::urscriptInterface_srv为服务的回调函数。

//定义回调函数

bool URScriptHandler::urscriptInterface_srv(ur_msgs::urscript::Request &req, ur_msgs::urscript::Response &res){
  //robot_.rt_interface_->addCommandToQueue(req.script);
  std::string str = req.script;
  if (str.back() != '\n')
    str.append("\n");

  switch (state_)
  {
    case RobotState::Running:
      if (!commander_.uploadProg(str))
      {
        LOG_ERROR("Program upload failed!");
      }
      break;
    case RobotState::EmergencyStopped:
      LOG_ERROR("Robot is emergency stopped");
      break;
    case RobotState::ProtectiveStopped:
      LOG_ERROR("Robot is protective stopped");
      break;
    case RobotState::Error:
      LOG_ERROR("Robot is not ready, check robot_mode");
      break;
    default:
      LOG_ERROR("Robot is in undefined state");
      break;
  }
  res.success = true;
  return res.success;
}

//记得要在类的头文件urscript_handler.h中声明该成员函数。

  • 最后定义相应的客户端

//定义客户端并向服务器请求相应

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "ur_msgs/urscript.h"
#include "sensor_msgs/JointState.h"

//消息回调函数
void joint_state_callback(const sensor_msgs::JointState::ConstPtr& msg){
  std::cout<<msg->position[0]<<" "<<msg->position[1]<<" "<<msg->position[2]<<" "<<
             msg->position[3]<<" "<<msg->position[4]<<" "<<msg->position[5]<<std::endl;
}

//定义需要发送的URScript脚本
std::string movej_test(){
  std::string cmd_str_;
  //std::vector<float> target_q_(6);
  float target_q_[6] = {0, 0, 0, 0, 0, 0};
  std::string move_str_ = "\tmovej([" + 
          std::to_string(target_q_[0]) + "," + std::to_string(target_q_[1]) + "," + 
          std::to_string(target_q_[2]) + "," + std::to_string(target_q_[3]) + "," + 
          std::to_string(target_q_[4]) + "," + std::to_string(target_q_[5]) + "]," + 
          std::to_string(1.0) + "," + std::to_string(1.5) + ")\n";
  cmd_str_ = "def myProg():\n";
  cmd_str_ += "\tmovej([1,0,0,0,0,0],1.0,1.5)\n";
  cmd_str_ += "\tsleep(3)\n";
  cmd_str_ += "\tmovej([0,0,2.5,0,0,0],1.0,1.5)\n";
  cmd_str_ += "\tsleep(3)\n";
  cmd_str_ += move_str_;
  cmd_str_ += "end\n";
  return cmd_str_;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "URScript_talker"); //定义节点名称
  ros::NodeHandle nh_;
  //ros::Publisher script_pub_ = nh_.advertise<std_msgs::String>("ur_driver/URScript", 100);
  ros::ServiceClient script_client_ = nh_.serviceClient<ur_msgs::urscript>("ur_driver/URScript_srv");
  ros::Subscriber joint_state_sub_ = nh_.subscribe("/joint_states", 5, joint_state_callback);
  //ros::spin();
  //std_msgs::String temp_;
  ur_msgs::urscript srv_;
  std::string cmd_str_ = movej_test();
  srv_.request.script = cmd_str_;
  while(!script_client_.call(srv_));//成功调用服务后停止循环
  //sleep(5);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/yimiyangguang185/article/details/87804693