主要内容

使用ROS在Unity 3D中选择和放置工作流

本示例展示了如何为KINOVA®Gen3这样的机器人机械手设置端到端拾取和放置工作流,并在Unity中模拟机器人®游戏引擎。

概述

本示例使用KINOVA Gen3操作器标识对象并将对象放入bin中。这个例子使用了三个工具箱中的工具:

  • 机器人系统工具箱™-对机械手进行建模和仿真。

  • Stateflow®-调度示例中的高级任务,并逐步执行模拟任务。

  • ROS工具箱™-连接MATLAB®统一。

本例基于以下相关示例中的关键概念:

拾起并定位工作流程

安装Unity并创建新项目

按照以下步骤安装Unity并创建一个新项目:

  1. 下载和安装联合中心

  2. 发射联合中心然后用你的账户登录。

  3. 安装统一编辑器来自Unity Hub。这个例子已经用Unity Editor 2021.3.6f1 LTS进行了测试。

  4. 在Unity Hub中,选择创建项目.Unity编辑器打开一个新项目。

安装Unity软件包

使用Unity中的包管理器安装这些包。

  • URDF进口国—从URDF文件中导入机器人模型。以ZIP文件的形式从URDF进口国GitHub库。此示例已使用URDF Importer 0.5.2版本进行了测试。

  • ROS TCP连接器—连接Unity与ROS服务器。以ZIP文件的形式从ROS TCP连接器GitHub库。此示例已使用ROS TCP连接器0.7.0版本进行测试。

按照以下步骤安装软件包:

  1. 解压缩包含包的ZIP文件。

  2. 在Unity Editor的菜单中,选择窗口>包管理器打开包管理器窗口。

  3. 包管理器窗口中,单击+签名和选择从磁盘中添加包

  4. 浏览并打开package.json两个包的文件。的位置package.json文件每个包。

将机器人模型导入Unity

Robot.zip本例中包含的文件包含了KINOVA Gen3机器人的URDF文件,并附加了一个自定义夹具。该文件还包含机器人模型的相关网格文件。

将URDF模型导入Unity:

  1. 的内容Robot.zip文件到资产文件夹在Unity项目目录。

  2. 中的URDF文件单击鼠标右键项目窗格并选择从选定的URDF文件导入机器人

  3. URDF导入设置窗口中,单击进口URDF

放大场景,查看进口KINOVA Gen3机器人模型。

在Unity中设置场景

为了在Unity中模拟拾取和放置工作流,在Unity中创建一个环境,其中包含地板、桌子和要拾取的盒子。

添加层

  1. 从Unity菜单中选择游戏对象> 3D对象>平面.Unity Editor将一个平面添加到场景中,并将其列在层次结构窗格。

  2. 层次结构窗格中,右键单击平面对象并选择重命名.将其重命名为地板上

  3. 检查员窗格中,在变换,设置XY,Z的值位置0

添加表

  1. 从Unity菜单中选择游戏对象> 3D对象>立方体.Unity Editor将一个立方体添加到场景中,并将其列在层次结构窗格。

  2. 层次结构窗格中,右键单击多维数据集对象并选择重命名.将其重命名为表格

  3. 检查员窗格中,在变换,设置Y而且Z的值位置0.25并设置Y的价值规模0.5

加框

  1. 从Unity菜单中选择游戏对象> 3D对象>立方体.Unity Editor将一个立方体添加到场景中,并将其列在层次结构窗格。

  2. 层次结构窗格中,右键单击多维数据集对象并选择重命名.将其重命名为盒子

  3. 检查员窗格中,在变换,设置Y的价值位置0.525而且Z的值位置0.25

  4. 设置XY,Z的值规模0.05

  5. 检查员窗格中,在网格渲染器,更改材料属性设置为非默认颜色,以方便可视化。

  6. 点击添加组件然后搜索rigidbody

  7. 选择RigidBody组件,将其添加到检查员窗格。

  8. 检查员窗格中,在RigidBody,设置的值质量0.01.如果使用重力未选中,请选中它。

添加标签到盒子

  1. 层次结构窗格中,选择盒子

  2. 检查员窗格,单击标签下拉并选择添加标签

  3. 单击+签名以创建标记。为标签命名PickObject

  4. 层次结构窗格中,选择盒子

  5. 检查员窗格,单击标签下拉并选择PickObject

您可以重复上述步骤加框而且添加标签到盒子为机器人添加更多的物体来挑选。

调整相机

  1. 层次结构窗格中,选择主要的相机

  2. 检查员窗格中,在变换,调整位置而且旋转属性。

  3. 或者,您可以手动调整相机的位置和方向使用工具叠加场景窗格。

  4. 你可以在调整相机的时候预览它的视角。

在Unity中配置机器人模型

配置机器人模型:

  1. 层次结构窗格中,选择机器人对象gen3_camera

  2. 检查员窗格中,在变换,设置Y的价值位置0.5,将机器人放置在桌子的顶部。

  3. 控制器(脚本),设置刚度1000阻尼One hundred.,力限制10

  4. 将机器人对象重命名为gen3类中使用的机器人名称setCurrentRobotJConfig方法exampleHelperCoordinatorPickPlaceROSUnity类。

setCurrentRobotJConfig方法exampleHelperCoordinatorPickPlaceROSUnity类使用此代码。

函数configRespUnity = setCurrentRobotJConfig(obj,JConfig) disp(“把机器人派到初始位置……”%的统一configReqUnity = rosmessage(obj.ROSinfo.UnityConfigClient);configReqUnity。ModelName =“gen3”;configReqUnity。JointPositions = JConfig;configRespUnity = call(obj.ROSinfo.UnityConfigClient,configReqUnity,“超时”3);结束

配置机器人模型的基本链路:

  1. 层次结构窗格,在gen3机器人对象,选择base_link

  2. 检查员窗格中,在清晰度的身体中,选择不动的

为抓取器手指添加碰撞框:

  1. 层次结构窗格,在gen3机器人对象,选择gripper_finger1_finger_tip_link

  2. 检查员窗格中,单击添加组件然后搜索盒子对撞机

  3. 选择盒子对撞机组件,将其添加到检查员窗格。

  4. 的值进行调整中心而且大小属性的碰撞盒,以确保它与夹持器手指网格对齐。

  5. 重复以上步骤gripper_finger2_finger_tip_link

设置物理解算器类型:

  1. 从菜单中选择编辑>项目设置启动项目设置窗口。

  2. 的左窗格中项目设置窗口中,选择物理

  3. 物理设置窗格,设置解算器类型Temporal Gauss Seidel。

ROS自定义服务和发布者

MATLAB需要与Unity通信,以便传输和接收关于机器人模型的信息。取放工作流的执行需要MATLAB和Unity之间的通信通道。要为这些渠道建立通信,请使用自定义服务和发布者。

此示例包括ROS自定义服务定义(.srv)文件。您可以在unity_robotics_demo_msgs文件夹中。的为自定义服务生成Unity脚本小节展示了如何从Unity中的自定义服务定义文件生成ROS消息。的在MATLAB中生成自定义ROS消息小节展示了如何从MATLAB中的自定义服务定义文件生成ROS消息。

  • SetModelConfiguration.srv-将机器人关节配置从MATLAB发送到Unity。

  • FollowTrajectory.srv-将机器人关节空间轨迹从MATLAB发送到Unity。

  • ObjectPosition.srv-在MATLAB中接收要从Unity场景中挑选的盒子的位置。

  • MoveGripperCommand.srv-从MATLAB中发送打开或关闭夹持器手指的命令。

PNPScripts.zip此示例包含的文件包含c# (cs)脚本,可以用来建立Unity和MATLAB之间的通信。的在Unity中添加ROS服务脚本章节展示了如何将Unity ROS服务脚本添加到场景中。更多实现Unity ROS服务的例子,请看这些统一的脚本在Unity Robotics Hub GitHub仓库中。

  • SetModelConfiguration.cs-在Unity中接收MATLAB中的机器人关节组态。然后,Unity将这些关节配置值分配给机器人模型的相应关节。脚本还取消选择使用重力仿真过程中机器人各环节的选项。

  • FollowTrajectory.cs-沿MATLAB提供的轨迹提供的一组关节配置移动机器人模型。

  • ObjectPosition.cs-将要从Unity场景中挑选的盒子的位置发送到MATLAB。

  • MoveGripper.cs-在Unity中打开或关闭附着在机器人手臂上的夹具手指。

  • JointStatePublisher.cs-在MATLAB中将当前的联合配置从Unity发布到ROS网络。有关从Unity发布消息的更多信息,请参见ROS-Unity沟通

为自定义服务生成Unity脚本

您必须将ROS自定义服务定义文件构建到c#脚本中,以便在Unity编程中使用。的ROS TCP连接器Package提供了可用于构建消息和服务的工具。

要构建自定义服务:

  1. 复制unity_robotics_demo_msgs文件夹,其中包含ROS自定义服务定义文件,到Unity项目文件夹。有关服务定义文件的详细信息,请参见unity_robotics_demo_msgs文件夹,请参见ROS自定义服务和发布者部分。

  2. 从Unity菜单栏中选择Robotics >生成ROS消息,以启动构建自定义服务的工具。

  3. ROS消息浏览器窗口,浏览到unity_robotics_demo_msgs文件夹内的Unity项目文件夹。

  4. 点击建造4个srvs

Unity从ROS自定义服务定义文件生成c#服务脚本。

Unity也会返回关于缺失的错误control_msgs消息。

构建所需的control_msgs消息:

  1. 提取Control_Msgs. zip在Unity项目文件夹中的文件。有关ROS控制消息的详细信息,请参见control_msgsGithub库。

  2. 从Unity菜单栏中选择Robotics >生成ROS消息,以启动构建这些消息的工具。

  3. ROS消息浏览器窗口,浏览到control_msgs文件夹内的Unity项目文件夹。

  4. 只构建这些消息,在Unity返回的错误中命名:FollowJointTrajectoryGoal.msgGripperCommand.msg,JointTolerance.msg

  5. 点击构建3个msg

Unity生成c#消息脚本control_msgs消息定义文件,它可以解决错误。

在Unity中添加ROS服务脚本

添加Unity ROS服务脚本到场景:

  1. 提取PNPScripts.zip文件到资产文件夹在Unity项目目录。有关服务脚本的详细信息,请参见PNPScripts.zip文件,请参阅ROS自定义服务和发布者部分。

  2. 从Unity菜单栏中选择创建空.Unity添加了一个空GameObject并将其列在层次结构窗格。

  3. 重命名空GameObjectPNPScriptsObject

  4. 中的所有c#脚本文件PNPScripts文件夹中。

  5. 将文件拖至PNPScriptsObject层次结构窗格。

的组件添加脚本PNPScriptsObject.在层次结构面板的PNPScriptsObject,设置创3的属性跟踪轨迹联合国家出版商移动夹具,模型配置的组件gen3机器人对象。

在MATLAB中创建拾取和放置工作流

本示例使用状态流程图来安排取放工作流的任务。打开图表以检查内容并跟踪图表执行期间的状态转换。

编辑exampleHelperFlowChartPickPlaceROSUnity.sfx

图表说明了机械手如何与物体或部件相互作用。它包括基本的初始化步骤,然后是两个主要部分:

  • 识别零件并确定放置它们的位置。

  • 执行拾取-放置工作流。

有关拾取放置步骤的高级描述,请参见使用MATLAB的状态流

打开和关闭夹持器

exampleCommandActivateGripperROSUnity命令函数发送一个服务请求来打开和关闭在Unity中实现的夹持器。

移动机械手到指定的姿态

使用exampleCommandMoveToTaskConfigROSUnity将机械手移动到指定姿势的命令功能。在生成机器人要遵循的关节轨迹后exampleCommandMoveToTaskConfigROSUnity函数以期望的采样率对轨迹进行采样,然后将其打包成联合轨迹ROS消息,并向Unity发送服务请求。

轨迹规划

使用trapveltraj而且transformtraj函数生成从初始任务到所需任务配置的简单任务空间轨迹。有关计划和执行轨迹的详细信息,请参见使用KINOVA Gen3机械手计划和执行任务和关节空间轨迹

在MATLAB中生成自定义ROS消息

中的自定义服务定义文件在MATLAB中生成ROS自定义消息unity_robotics_demo_msgs文件夹中。有关这些服务定义文件的更多信息,请参见ROS自定义服务和发布者部分。

使用rosgenmsg(ROS工具箱)函数生成自定义消息,并按照对话框中的说明将消息添加到MATLAB路径。

答案= questdlg(“自定义ROS消息是否为MATLAB生成?”...MATLAB自定义ROS消息“是的”“不”“不”);开关回答情况下“是的”继续选择和放置情况下“不”%运行rosgenmsg为MATLAB构建自定义ROS消息rosgenmsg结束答案= questdlg(“自定义ROS消息是否添加到MATLAB路径?”...“ROS信息”“是的”“添加路径……”从当前目录添加路径“是的”);开关回答情况下“是的”继续选择和放置情况下“添加路径……”将自定义ROS消息添加到MATLAB路径customROSMsgPath = uigetdir("""选择由rosgenmsg创建的安装\m文件夹");addpath(customROSMsgPath)保存路径清除重新处理toolboxcache情况下从当前目录添加路径customROSMsgPath = uigetdir(fullfile(pwd,“matlab_msg_gen_ros1”),"选择由rosgenmsg创建的安装\m文件夹");addpath(customROSMsgPath)保存路径清除重新处理toolboxcache结束

建立MATLAB的Unity连接

ROS主设置在MATLAB中

从MATLAB启动ROS master。或者,您可以将Unity和MATLAB连接到运行在其他地方的ROS主机。

关闭任何现有的ROS Masterrosshutdown创建一个ROS Masterrosinit
启动ROS Core... ........耗时8.3609秒。在http://172.18.250.141:11311上初始化ROS master。使用NodeURI http://hyd-shivarad:53031/和MasterURI http://localhost:11311初始化全局节点/matlab_global_node_65508。

在MATLAB中运行TCP端点节点

一个ROS TCP端点节点可以促进Unity和ROS之间的通信,以发送和接收消息。

在MATLAB中启动ROS TCP端点节点。

helperConnectROSUnity;

Unity ROS连接设置

从Unity菜单栏中选择Robotics > ROS设置,打开工具,在MATLAB会话中指定运行ROS master的机器的IP地址。有关设置ROS连接的详细指南,请参见统一的一方

Unity安装验证

点击Unity中的播放按钮来模拟场景。控制台显示设置中的任何严重错误。在继续示例之前解决错误。

确保Unity场景正在运行,并且与MATLAB的连接正在运行。当Unity场景正在播放时,你应该看到一个覆盖在游戏窗格。旁边的蓝色和绿色箭头ROS IP说明在Unity和ROS master之间有一个连接。

Unity安装检查在MATLAB中

使用对话框确认Unity正在运行。点击是的在对话框中开始模拟。

答案= questdlg(点击Unity中的Play按钮。一旦连接建立,请选择Yes。”...“运行Unity场景”“是的”“不”“不”);开关回答情况下“是的”继续选择和放置情况下“不”停止拣放作业coordinator.FlowChart.endPickPlace;删除(coordinator.FlowChart)删除(协调);结束

要检查MATLAB中的连接状态是否正常,请运行以下命令rostopic命令并验证MATLAB是否接收Unity发布的ROS主题/ my_gen3_unity joint_states

rostopic列表
/my_gen3_unity/joint_states /rosout /tf . txt
rostopic回声/ my_gen3_unity joint_states
头邮票秒:0 Nsec: 0 Seq: 1 FrameId: 1名称:{1}shoulder_link {2} half_arm_1_link {3} half_arm_2_link {4} forearm_link {5} spherical_腕_1_link {6} spherical_腕_link {7} bracelet_link位置:[3.84349641535664e-06, -5.377179604693083e-06, 5.302986664901255e-06, -1.095666357286973e-05, 5.450971798381943e-07, -3.903266687643736e-08][1.649751438306241e-05, -3.894936167378246e-05, 5.202663783397106e-05, - 5.82921963625724e -06, -5.537591719446247e-05, 2.984850922248081e-05, -9.524918674711089e-06]努力:[]——

开始“拾取放置任务”

MATLAB加载机器人模型

本仿真使用KINOVA Gen3机械手Robotiq夹附呈。加载机器人模型.mat文件作为rigidBodyTree对象。

负载(“exampleHelperKINOVAGen3GripperROSUnity.mat”);

初始化拾取-放置协调器

设置机器人初始配置。通过指定机器人模型、初始配置和末端执行器名称,初始化处理机器人控制的协调器。

initialRobotJConfig = [3.5797 -0.6562 -1.2507 -0.7008 0.7303 -2.0500 -1.9053];endEffectorFrame =“爪”;coordinator = exampleHelperCoordinatorPickPlaceROSUnity(机器人,initialRobotJConfig,endEffectorFrame);
把机器人派到初始位置……

在Unity中,验证机器人模型已经移动到指定的位置initialRobotJConfig

指定主配置和放置对象的两个姿势。

协调员。HomeRobotTaskConfig = getTransform(robot,initialRobotJConfig,endEffectorFrame);协调员。PlacingPose{1} = trvec2tform([0.2 0.55 0.26])*axang2tform([0 0 1 pi/2])*axang2tform([0 1 0 pi]);协调员。PlacingPose{2} = trvec2tform([0.2 -0.55 0.26])*axang2tform([0 0 1 pi/2])*axang2tform([0 1 0 pi]);

运行和可视化模拟

将协调器连接到状态流程图。一旦启动,状态流图负责连续地检查检测对象的状态、拾取它们并将它们放置在正确的staging区域。

协调员。流程图= exampleHelperFlowChartPickPlaceROSUnity(“协调员”协调员);

创建一个对话框,用于开始拾取和放置任务执行。要开始模拟,请单击是的在对话框中。

答案= questdlg(“你想现在就开始找东西吗?”...“开始工作”“是的”“不”“不”);开关回答情况下“是的”触发事件以启动状态流程图中的“选择和放置”coordinator.FlowChart.startPickPlace;情况下“不”coordinator.FlowChart.endPickPlace;删除(coordinator.FlowChart)删除(协调)结束

在Unity中观察机器人模型,并检查它是否执行了拾取和放置操作。

结束拾取放置任务

在四次检测新对象失败后,状态流图自动停止。若要过早停止拾取和放置任务,请取消注释并执行这些代码行,或选择命令窗口并按下Ctrl + C

% coordinator.FlowChart.endPickPlace;%删除(coordinator.FlowChart)%删除(协调)

在Unity中可视化挑选和放置动作

Unity场景显示了机器人在工作区域移动物体到所需位置的过程。机器人继续工作,直到所有物体都放置好。当检测步骤四次都没有找到任何对象时,状态流图结束。

如果比较字符串(答案,“是的”协调员。NumDetectionRuns < 4%等待未检测到任何对象。结束结束

杀死ROS TCP端点节点并关闭ROS网络。

helperKillTCPEndpointNode;rosshutdown
使用NodeURI http://hyd-shivarad:64473/和MasterURI http://localhost:11311关闭全局节点/matlab_global_node_37032。在http://172.18.250.141:11311上关闭ROS master。