ROS中控制机械臂抓取目标例程

2023-05-16

在上一个博文中介绍了一个简单的目标识别的例子,在这篇博客中,例如是别的结果,完成机械臂的抓取控制,主要进行程序的分析和学习。

包含的头文件:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <sensor_msgs/image_encodings.h>
#include <geometry_msgs/PoseStamped.h>
#include <moveit/move_group_interface/move_group_interface.h>
#include <moveit/planning_scene_interface/planning_scene_interface.h>
#include <moveit_msgs/DisplayRobotState.h>
#include <moveit_visual_tools/moveit_visual_tools.h>
#include <cv_bridge/cv_bridge.h>
#include <tf/transform_listener.h>

还是从主函数看起:

int main(int argc, char **argv)
{
  //初始化ROS节点,节点名为simple_grasping
  ros::init(argc, argv, "simple_grasping");

  float length, breadth, pregrasp_x, pregrasp_y, pregrasp_z;
  //节点句柄
  ros::NodeHandle n;

  //获取参数,首先是桌子的长
  if (!n.getParam("probot_grasping/table_length", length))
    length = 0.3;
  //桌子的宽
  if (!n.getParam("probot_grasping/table_breadth", breadth))
    breadth = 0.3;
   
  //机械臂的初始位置,不让机械臂挡着视野,影响拍照
  if (!n.getParam("probot_grasping/pregrasp_x", pregrasp_x))
    pregrasp_x = 0.20;
  if (!n.getParam("probot_grasping/pregrasp_y", pregrasp_y))
    pregrasp_y = -0.17;
  if (!n.getParam("probot_grasping/pregrasp_z", pregrasp_z))
    pregrasp_z = 0.28;

  //创建一个对象,将参数传递进去
  GraspingDemo simGrasp(n, pregrasp_x, pregrasp_y, pregrasp_z, length, breadth);
  ROS_INFO_STREAM("Waiting for five seconds..");

  ros::WallDuration(5.0).sleep();
 
  //不断查看图像队列,如果有识别到的图像,则进行抓取
  while (ros::ok())
  {
    // Process image callback
    ros::spinOnce();

    //控制机械臂运动
    simGrasp.initiateGrasping();
  }
  return 0;
}

 先看一下GraspingDemo类的内容:

首先看构造函数当中:

GraspingDemo::GraspingDemo(ros::NodeHandle n_, float pregrasp_x, float pregrasp_y, float pregrasp_z, float length, float breadth) :
    it_(n_), 
    armgroup("manipulator"), 
    grippergroup("gripper"), 
    vMng_(length, breadth)
{
  this->nh_ = n_;

  //获取base_link和camera_link之间的关系,也就是手眼标定的结果
  try
  {
    this->tf_camera_to_robot.waitForTransform("/base_link", "/camera_link", ros::Time(0), ros::Duration(50.0));
  }
  catch (tf::TransformException &ex)
  {
    ROS_ERROR("[adventure_tf]: (wait) %s", ex.what());
    ros::Duration(1.0).sleep();
  }

  //如果查询得到的话,就将结果保存到camera_to_robot_,保存x,y,z和四元数一共7个值
  try
  {
    this->tf_camera_to_robot.lookupTransform("/base_link", "/camera_link", ros::Time(0), (this->camera_to_robot_));
  }
  catch (tf::TransformException &ex)
  {
    ROS_ERROR("[adventure_tf]: (lookup) %s", ex.what());
  }

  grasp_running = false;
  
  this->pregrasp_x = pregrasp_x;
  this->pregrasp_y = pregrasp_y;
  this->pregrasp_z = pregrasp_z;

  //让机械臂运动到初始的位置
  ros::AsyncSpinner spinner(1);
  spinner.start();
  ros::WallDuration(5.0).sleep();
  ROS_INFO_STREAM("Getting into the Grasping Position....");
   //调用该函数控制机械臂运动到设定的位置
  attainPosition(pregrasp_x, pregrasp_y, pregrasp_z);

  // Subscribe to input video feed and publish object location
  //订阅图像话题,一旦收到图像信息,就会进入到callback当中
  image_sub_ = it_.subscribe("/probot_anno/camera/image_raw", 1, &GraspingDemo::imageCb, this);
}

 attainPosition函数:

void GraspingDemo::attainPosition(float x, float y, float z)
{
  // ROS_INFO("The attain position function called");

  // 获取当前位置
  geometry_msgs::PoseStamped currPose = armgroup.getCurrentPose();
  
  //初始化数据类型
  geometry_msgs::Pose target_pose1;
  target_pose1.orientation = currPose.pose.orientation;


  // 设置抓取前的机械臂位置
  target_pose1.position.x = x;
  target_pose1.position.y = y;
  target_pose1.position.z = z;
  armgroup.setPoseTarget(target_pose1);

  //机械臂运动
  armgroup.move();
}

看一下订阅图像的回调函数:

void GraspingDemo::imageCb(const sensor_msgs::ImageConstPtr &msg)
{
  if (!grasp_running)
  {
    ROS_INFO_STREAM("Processing the Image to locate the Object...");
    //将图像变换到opencv当中
    try
    {
      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    }
    catch (cv_bridge::Exception &e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }
 
    //调用vision_manager中的函数获取目标的位置,位置坐标是以摄像头中心点的位置作为0坐标
    // ROS_INFO("Image Message Received");
    float obj_x, obj_y;
    vMng_.get2DLocation(cv_ptr->image, obj_x, obj_y);

    // Temporary Debugging
    std::cout<< " X-Co-ordinate in Camera Frame :" << obj_x << std::endl;
    std::cout<< " Y-Co-ordinate in Camera Frame :" << obj_y << std::endl;

    //通过坐标变换,将二维坐标变换为相机坐标系下的三维坐标,在本程序中与URDF建模有关系
    obj_camera_frame.setZ(-obj_y);
    obj_camera_frame.setY(-obj_x);
    obj_camera_frame.setX(0.45);

    //关键的一行代码,将相机坐标系下的位置转化为base_link坐标系下的坐标
    obj_robot_frame = camera_to_robot_ * obj_camera_frame;
    grasp_running = true;

    // Temporary Debugging
    std::cout<< " X-Co-ordinate in Robot Frame :" << obj_robot_frame.getX() << std::endl;
    std::cout<< " Y-Co-ordinate in Robot Frame :" << obj_robot_frame.getY() << std::endl;
    std::cout<< " Z-Co-ordinate in Robot Frame :" << obj_robot_frame.getZ() << std::endl;
  }
}

然后机械臂开始根据这个目标位置进行运动:

void GraspingDemo::initiateGrasping()
{
  //开启新的线程
  ros::AsyncSpinner spinner(1);
  spinner.start();
  ros::WallDuration(3.0).sleep();

  //获取当前的位置
  homePose = armgroup.getCurrentPose();
  
  //调用attainObject()函数使机械臂靠近目标
  ROS_INFO_STREAM("Approaching the Object....");
  attainObject();

  //夹取物体
  ROS_INFO_STREAM("Attempting to Grasp the Object now..");
  grasp();

  //夹住物体做一个小范围移动
  ROS_INFO_STREAM("Lifting the Object....");
  lift();

  //机械臂返回到初始状态
  ROS_INFO_STREAM("Going back to home position....");
  goHome();

  grasp_running = false;
}

看一下涉及到的三个函数: 

靠近物体:

void GraspingDemo::attainObject()
{
  // ROS_INFO("The attain Object function called");
  attainPosition(obj_robot_frame.getX(), obj_robot_frame.getY(), obj_robot_frame.getZ() + 0.04);

  // Open Gripper
  ros::WallDuration(1.0).sleep();
  grippergroup.setNamedTarget("open");
  grippergroup.move();

  // Slide down the Object
  geometry_msgs::PoseStamped currPose = armgroup.getCurrentPose();
  geometry_msgs::Pose target_pose1;

  target_pose1.orientation = currPose.pose.orientation;
  target_pose1.position = currPose.pose.position;

  target_pose1.position.z = obj_robot_frame.getZ() - 0.02;
  armgroup.setPoseTarget(target_pose1);
  armgroup.move();
}

抓取:

void GraspingDemo::grasp()
{
  // ROS_INFO("The Grasping function called");

  ros::WallDuration(1.0).sleep();
  grippergroup.setNamedTarget("close");
  grippergroup.move();
}

夹爪离开:

void GraspingDemo::lift()
{
  // ROS_INFO("The lift function called");

  // For getting the pose
  geometry_msgs::PoseStamped currPose = armgroup.getCurrentPose();

  geometry_msgs::Pose target_pose1;
  target_pose1.orientation = currPose.pose.orientation;
  target_pose1.position = currPose.pose.position;

  // Starting Postion after picking
  //target_pose1.position.z = target_pose1.position.z + 0.06;

  if(rand() % 2)
  {
    target_pose1.position.y = target_pose1.position.y + 0.02;
  }
  else
  {
    target_pose1.position.y = target_pose1.position.y - 0.02;
  }
  
  armgroup.setPoseTarget(target_pose1);
  armgroup.move();

  // Open Gripper
  ros::WallDuration(1.0).sleep();
  grippergroup.setNamedTarget("open");
  grippergroup.move();

  target_pose1.position.z = target_pose1.position.z + 0.06;
  armgroup.setPoseTarget(target_pose1);
  armgroup.move();
}

参考博客:古月居

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS中控制机械臂抓取目标例程 的相关文章

  • 版本控制软件SVN

    SVN学习 1 版本控制软件定义及用途 版本控制软件是为适应软件配置管理的需要 xff0c 控制软件的修改 xff0c 减少混乱 xff0c 提高软件生产效率 xff0c 其是软件质量保证的重要环节软件配置管理是对软件修改进行标识 组织和控

随机推荐

  • 螺旋桨的制作图文教程

    一 螺旋桨的一些基础概念 当我们把螺旋桨看成是一个一面旋转一面前进的机翼时 xff0c 就能借助已知的空气动力学常识 xff0c 直观地理解螺旋桨的基本工作原理 1 xff0e 桨距 动力桨距和几何桨距 桨距 xff1a 从广义而言 xff
  • 自制2.4G ELRS接收机,不需要打板,容易制作

    制作难度 xff1a 中等 xff0c 主要是器件太小 xff0c 焊接需要耐心 一 硬件材料 1 LoRa射频模块 xff0c sx1280 xff1a E28 2G4M12S 2 MCU Wifi模块 xff1a ESP 01F 3 各
  • Qt学习笔记 【C++】(4)

    目录 一 Qt中的C 43 43 11标准二 Explicit Linking 和 Implicit Linking三 自动生成的ui xxx ui文件四 常用快捷键 一 Qt中的C 43 43 11标准 Qt 5 中开启C 43 43 1
  • 串口发送接收字符串的C语言代码参考

    通过串口把字符串数据从单片机U1发送到单片机U2 xff0c 通过U2的LCD602显示出来 LCD602显示代码是用的一个比较不错的现成的显示代码 单片机串口传字符串 xff0c 主要是利用字符串的格式的特点 xff0c 在传输中结束串口
  • HTTP协议解析

    HTTP概述 HTTP 全称为 34 超文本传输协议 34 是一种应用非常广泛的应用层协议 我们平时打开一个网站 就是通过 HTTP 协议来传输数据的 HTTP工作过程 xff1a 当我们在浏览器中输入一个 34 网址 34 xff0c 此
  • 《算法导论》学习心得

    第四章 分治策略 xff08 1 xff09 Master Method中case 3中 正则条件 的含义 xff1a 保证f n 在每次递归后都比上一层小 xff08 非递增 xff09 否则显然T n gt f n xff08 2 xf
  • 《算法导论》 第11章部分答案

    注 xff1a 以下答案均为自己思考 xff0c 难免有误 xff0c 欢迎指正 11 3 1 xff1a 将长度为n的链表进行排序 xff0c 将关键值的散列值相同的元素排为相邻 而散列表有点类似于链接法解决冲突的散列表 11 3 2 x
  • 算法刷题心得:动态规划 scramble-string

    牛客网 gt 在线编程 gt letcode gt scramble string Given a string s1 we may represent it as a binary tree by partitioning it to t
  • POJ 1635 Subway tree systems

    题目 xff1a Some major cities have subway systems in the form of a tree i e between any pair of stations there is one and o
  • Openwrt添加定制一个软件包

    我深知前路风雨 xff0c 但我依然微笑前行 Openwrt的Makefile流程异于一般常用的Makefile xff0c 阅读起来难度太大 但是我么可以先通过如何使用 修改Makefile开始 xff0c 从Makefile的某个局部开
  • 无人机通信(WiFI/3G/4GLTE)

    无人机通信 xff08 WiFI 3G 4GLTE xff09 DJI 大疆创新的无人机可实时操控执行各项任务 Phantom3 还内置了全新的 Lightbridge 高清图传系统 xff0c 使飞机所拍摄的实时图像可远距离传输到移动设备
  • realsense D430 python采集深度图像,并保存为txt及pcd点云,用于open3D后处理

    D430点云是x y z 将realsense D430保存的点云文件 pcd 需要对数据进行处理 废话不多说 直接上代码 span class token comment coding utf 8 span span class toke
  • 隐藏符号 __dso_handle 问题

    这几天要给项目做移植 xff0c 重写了下Makfile 项目原是使用autoconf配置的 xff0c 但在新环境下对autoconf的支持不好 Makefile编写基本按autoconf生成的Makefile来的 xff0c 编译选项等
  • 类模板成员函数

    模板类的头文件 span class token macro property span class token directive hash span span class token directive keyword ifndef s
  • C++ 在.h文件中包含头文件和在.cpp文件中包含头文件的原则

    1 第一个原则 xff1a 如果可以不包含头文件 xff0c 那就不要包含了 xff0c 这时候前置声明可以解决问题 如果使用的仅仅是一个类的指针 xff0c 没有使用这个类的具体对象 xff08 非指针 xff09 xff0c 也没有访问
  • NRF24L01数据通信C程序

    NRF24l01 产品性能 xff1a 1 xff09 2 4GHZ全球开放ISM频段免许可使用 2 xff09 最高工作速率2Mbps GFSK高效调制 3 xff09 125个频道满足多点通讯和跳频通讯需求 4 xff09 1 9 3
  • gazebo仿真之xacro文件

    span class token operator lt span span class token operator span xml version span class token operator 61 span span clas
  • c++ 释放内存 野指针

    在释放内存之时 xff0c 不仅仅是将该块内存进行释放 xff0c 还要将指向该块内存的指针置为NULL 如果不置为NULL xff0c 下次继续使用该指针时会出现问题 具体看示例 在下面的示例中 xff0c 如果没有处理野指针的那句话 x
  • 二维码识别 -- 基于ros平台下的仿真

    生活中的二维码 二维码是用某种特定的几何图形按一定规律在平面 xff08 二维方向上 xff09 分布的黑白相间的图形记录数据符号信息的 xff1b 在代码编制上巧妙地利用构成计算机内部逻辑基础的 0 1 比特流的概念 xff0c 使用若干
  • ROS中控制机械臂抓取目标例程

    在上一个博文中介绍了一个简单的目标识别的例子 xff0c 在这篇博客中 xff0c 例如是别的结果 xff0c 完成机械臂的抓取控制 xff0c 主要进行程序的分析和学习 包含的头文件 xff1a include lt ros ros h