ROS Industrial教程(五)

一、通过C++进行运动规划

更改myworkcell_core节点,使之根据service call的vision node的发布,将机器人的工具框移动到零件位置的中心。

1. 修改myworkcell_node.cpp文件

1.1. 添加#include <tf/tf.h>以允许访问tf库(用于框架转换/应用)。

·之前已经添加了对tf包的依赖。

1.2. 在ScanNPlan类的start方法中,使用LocalizePart服务的响应来初始化新的move_目标变量:在scannplan类的start方法中,使用localizepart服务的响应来初始化新的move_target变量:

geometry_msgs::Pose move_target = srv.response.pose;

·确保在调用vision_node服务后放置此代码。

2. 使用MoveGroupInterface计划/执行到move_target位置的移动:

2.1. 为了使用MoveGroupInterface类,有必要添加moveit_ros_planning_interface程序包作为myworkcell_core程序包的依赖项。通过修改程序包的CMakeLists.txt(2行)和package.xml(1行)来添加moveit_ros_planning_interface依赖项。

 

2.2. 添加适当的“ include”引用以允许使用MoveGroupInterface

#include <moveit/move_group_interface/move_group_interface.h>

 

2.3. 在ScanNPlan类的start()方法中创建一个moveit::planning_interface::MoveGroupInterface对象。 它具有单个构造函数,该构造函数采用您在创建工作单元moveit程序包时定义的计划组的名称(“manipulator”)。

 

2.4. 使用move_group对象的setPoseTarget函数设置所需的笛卡尔目标位置。 调用对象的move()函数以计划并执行向目标位置的移动。

// Plan for robot to move to part

move_group.setPoseReferenceFrame(base_frame);

move_group.setPoseTarget(move_target);

move_group.move();

 

2.5. move_group.move()命令要求使用“异步”微调器,以允许在阻塞move()命令期间处理ROS消息。 在ros::init(argc, argv, "myworkcell_node")之后在main()例程的开始附近初始化微调器,并用ros::waitForShutdown()替换现有的ros::spin()命令,如下所示:

ros::AsyncSpinner async_spinner(1);

async_spinner.start();

...

ros::waitForShutdown();

 

3. 测试运行

catkin build

roslaunch myworkcell_moveit_config myworkcell_planning_execution.launch

roslaunch myworkcell_support workcell.launch

 

4. 更多

·在RViz中,添加主题“ / ar_pose_visual”的“标记Marker显示,以确认机器人的最终位置与fake_ar_publisher发布的位置匹配

·尝试更新workcell_nodestart方法,使其在移至AR_target位置后自动移回allZeros位置。 有关move group可用方法的列表,请参见此处

可使用bool setNamedTarget (const std::string &name)方法,将当前关节值设置为RememberJointValues()先前记住的值,或者,如果找不到,则设置为在SRDF中以名称name命名的组状态(此例中为“allZeros”,组状态可在创建moveIt包时添加)。在start函数中添加如下代码:

    if(move_group.setNamedTarget ("allZeros"))

      {

        ROS_INFO("setNamedTarget Success!");

        move_group.move();

      }

    else

      ROS_INFO("setNamedTarget failed!");

 

·在最终移动到目标之前,尝试移动到距离目标位置几英寸远的“接近位置approach position”

       可通过直接设置目标姿态的坐标和指向实现。

    move_target.orientation.x = 0;

    move_target.orientation.y = 1;

    move_target.orientation.z = 0;

    move_target.orientation.w = 0;

    move_target.position.x = 0.35;

    move_target.position.y = -0.3;

    move_target.position.z = 0.8;

    move_group.setPoseTarget(move_target);

    move_group.move();

 

 

 

二、笛卡尔Descartes路径规划简介

MoveIt!是一个主要用于执行“自由空间”运动的框架,该框架的目标是将机器人从A点移动到B点。 这些类型的问题只是频繁执行任务的一部分,例如焊接、喷漆、激光切割。这些过程中十分重视工具在机器人整个工作期间所指向的位置。

接下来将介绍笛卡尔,一种“直角坐标”运动规划器,用于沿某个过程路径移动机器人。其具有以下特性:

·可获得全局最优解(对于特定的搜索分辨率而言)。

·可以搜索问题中的多余自由度(例如有7个机器人关节,或者过程中工具的Z轴旋转无关紧要)。

接下来将建立一个新的节点,功能为:

(1). 通过ROS服务将标记的名义姿态作为输入。

(2). 产生一条关节轨迹,该轨迹命令机器人跟踪标记物的周边(就像它正在喷漆一样)。

 

为了节省时间,文件descartes_node.cpp已定义,该文件:

(1). 为笛卡尔路径规划定义一个新的节点和伴随类。

(2). 定义实际服务并初始化笛卡尔库。

(3). 提供高级工作流程(请参阅planPath函数)。

剩下需要完成的是:

(1). 定义一系列构成机器人“路径”的笛卡尔姿势。

(2). 将这些路径转化为笛卡尔可以理解的东西。

 

配置工作空间

1. 将笛卡尔库拷贝到工作区中

cd ~/catkin_ws/src

git clone -b melodic-devel https://github.com/ros-industrial-consortium/descartes.git

 

2. 将ur5_demo_descartes包复制到工作区中

cp -r ~/industrial_training/exercises/4.1/src/ur5_demo_descartes .

 

3. 将descartes_node_unfinished.cpp复制到核心软件包的src /文件夹中,并将其重命名为descartes_node.cpp

cp ~/industrial_training/exercises/4.1/src/descartes_node_unfinished.cpp myworkcell_core/src/descartes_node.cpp

 

4.在CMakeLists.txt & package.xml文件中添加依赖

  • ur5_demo_descartes
  • descartes_trajectory
  • descartes_planner
  • descartes_utilities
  • eigen_conversions

5. 在myworkcell_core程序包的CMakeLists.txt中创建规则,以建立一个名为descartes_node的新节点。

add_executable(descartes_node src/descartes_node.cpp)

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

target_link_libraries(descartes_node ${catkin_LIBRARIES})

 

完成Descartes节点

       需要创建一个服务接口来执行笛卡尔计划算法。

1. 在myworkcell_core软件包的srv/目录中定义一个名为PlanCartesianPath.srv的新服务。 该服务获取目标中心位置并计算关节轨迹以跟踪目标边缘。

# request

geometry_msgs/Pose pose

 

---

 

# response

trajectory_msgs/JointTrajectory trajectory

 

2. 将新创建的服务文件添加到程序包CMakeLists.txt中的add_service_file()规则中。

 

3. 由于新服务引用了另一个包中的消息类型,因此我们需要将该另一个包(trajectory_msgs)作为依赖项添加到myworkcell_core CMakeLists.txt(3行)和package.xml(1行)文件中。

 

4. 查看descartes_node.cpp以了解代码结构。 特别是,planPath方法概述了步骤的主要顺序。

 

  1.   

·在makeToolPoses中,生成跟踪“ AR标记”目标零件外部的路径的其余3边。

我们在makeToolPoses()中定义的路径是相对于您正在使用的零件上某个已知参考点的。 因此,(0,0,0)的刀具姿态将完全位于参考点,而不是世界坐标系的原点。

 

     

·在makeDescartesTrajectory中,将您创建的路径转换为“笛卡尔轨迹”,一次转换一个点。(不要忘记通过指定的参考姿势来变换每个标称点:ref * point

makeDescartesTrajectorty(...)中,我们需要使用“ ref”姿势将相对工具姿势转换为世界坐标。

      

·在makeTolerancedCartesianPoint中,根据给定的姿势创建一个new AxialSymmetricPt。(有关此点类型的更多文档,请参见此处。允许点绕Z轴对称(AxialSymmetricPt::Z_AXIS),增量为90度(PI / 2弧度) )

makeTolerancedCartesianPoint(...)中,考虑此文档以了解常见的关节轨迹点的具体实现:

 

6.Build & Debug

 

更新Workcell节点

完成笛卡尔节点后,我们现在想通过向主工作单元节点添加新的ServiceClient来调用其逻辑。 该服务的结果是我们必须在机器人上执行的关节轨迹。 这可以通过许多方式来完成。 在这里,我们将直接调用JointTrajectoryAction

1. 在myworkcell_node.cpp中,添加头文件include语句:

#include <actionlib/client/simple_action_client.h>

#include <control_msgs/FollowJointTrajectoryAction.h>

#include <myworkcell_core/PlanCartesianPath.h>

无需为这些库/消息添加新的依赖项,因为它们是从moveit传递而来的。

 

2. 在ScanNPlan类中,添加新的私有成员变量:PlanCartesianPath服务的ServiceClient和FollowJointTrajectoryAction的操作客户端:

ros::ServiceClient cartesian_client_;

actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction> ac_;

 

3. 在构造函数中初始化这些新对象。 注意,动作客户端必须在所谓的构造函数初始化列表中初始化。

ScanNPlan(ros::NodeHandle& nh) : ac_("joint_trajectory_action", true)

{

  // ... code

  cartesian_client_ = nh.serviceClient<myworkcell_core::PlanCartesianPath>("plan_path");

}

 

4. 在start()函数的结尾,创建一个新的笛卡尔服务并发出服务请求:

// Plan cartesian path

myworkcell_core::PlanCartesianPath cartesian_srv;

cartesian_srv.request.pose = move_target;

if (!cartesian_client_.call(cartesian_srv))

{

  ROS_ERROR("Could not plan for path");

  return;

}

 

5. 继续添加以下行,以通过直接将动作发送到动作服务器(绕过MoveIt)来执行该路径:

// Execute descartes-planned path directly (bypassing MoveIt)

ROS_INFO("Got cart path, executing");

control_msgs::FollowJointTrajectoryGoal goal;

goal.trajectory = cartesian_srv.response.trajectory;

ac_.sendGoal(goal);

ac_.waitForResult();

ROS_INFO("Done");

 

6.Build & Debug

 

 

测试

1. 创建一个新的setup.launch文件(在workcell_support程序包中),该文件会打开除workcell_node之外的所有内容:

<include file="$(find myworkcell_moveit_config)/launch/myworkcell_planning_execution.launch"/>

<node name="fake_ar_publisher" pkg="fake_ar_publisher" type="fake_ar_publisher_node" />

<node name="vision_node" type="vision_node" pkg="myworkcell_core" output="screen"/>

<node name="descartes_node" type="descartes_node" pkg="myworkcell_core" output="screen"/>

 

2.运行setup文件,然后运行workcell节点

roslaunch myworkcell_support setup.launch

rosrun myworkcell_core myworkcell_node

(为了看清运动过程,在rviz中禁用循环动画)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值