• 从Unity Robotics Hub入门Unity-ROS


    0.简介

    对于Unity而言,其拥有非常完备的物理特性,这对于机器人仿真是非常有用的,但是实际上Unity和ROS之间的通信一直是摆在两者之间的难题,正好看到宇宙爆肝锦标赛冠军写的这个系列,所以个人想参照为数不多的资料来进行整理,并完成这个系列的文章。“Unity Robotics Hub”是一种基于Unity环境的机器人模拟工具、教程、资源以及文档信息的资料库。机器人工作者可以在模拟场景中使用Unity。

    1. 环境安装

    1.1 安装 Docker

    卸载旧的docker版本

    sudo apt-get update
    sudo apt-get remove docker docker-engine docker.io containerd runc
    
    • 1
    • 2

    允许apt命令可以使用HTTPS访问Docker repository

    sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
    
    • 1

    在这里插入图片描述
    添加Docker官方的GPG key

    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
    • 1

    在这里插入图片描述
    验证key(搜索后8位即可显示完成秘钥):

    sudo apt-key fingerprint 0EBFCD88
    
    • 1

    设置repository版本为stable并更新软件列表

    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt-get update
    
    • 1
    • 2

    开始安装docker

    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
    • 1

    安装完成后,在命令行输入docker --version;出现docker版本信息即表示安装成功。

    1.2 Unity安装

    从官网(Unity官网)下载Unity Hub。
    在这里插入图片描述
    或者直接通过命令行安装

    sudo sh -c 'echo "deb https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unityhub.list'
    wget -qO - https://hub.unity3d.com/linux/keys/public | 
    sudo apt-key add -
    sudo apt updatesudo apt-get install unityhub
    
    • 1
    • 2
    • 3
    • 4

    然后安装安装Unity Editor,进入网址。然后点Unity Editor就行。接着把下载好文件的解压。然后打开Unity Hub,点Locate,选择你Unity Editor文件夹下的Unity即可
    在这里插入图片描述

    2. 安装Unity Robotics包

    这个小节用来提供关于安装Unity Robotics软件包的简短说明。

    1. 创建或打开一个Unity项目,值得注意的是如果需要添加URDF-Importer,请确保你使用的是2020.2.0+版本的Unity Editor。

    2. 打开Window -> Package Manager菜单

    3. 在Package Manager窗口中,找到并单击窗口左上角的+按钮。选择Add package from git URL…
      在这里插入图片描述

    4. 输入所需包的git URL。注意:你可以在git url的末尾添加一个版本标签,比如#v0.4.0或#v0.5.0,来声明一个特定的包版本,或者排除这个标签来从包的主分支获取最新的版本。

    5. 点击 Add.

    在这里插入图片描述
    在上面项目导入成功的情况下,在Unity的功能面部中会出现对应的Robotics功能选项,点击Robotics->ROS Setting面板
    在这里插入图片描述

    3. Unity Robotics Hub安装

    开发环境的需要的环境如下:

    1. Unity版本2020.2+
    2. URDF导入的repo
    3. 拥有ROS环境

    接着就可以开始安装环境了

    git clone --recurse-submodules https://github.com/Unity-Technologies/Unity-Robotics-Hub.git
    
    • 1

    下面官方文档中提供了两种方法,第一种是使用Docker,另外一种就是直接在本地安装环境。

    3.1 Docker安装

    启动Docker守护进程。我们可以使用系统无关的docker info命令可以验证docker是否正在运行。如果Docker守护进程当前没有运行,此命令将抛出Server: ERROR,否则将打印适当的系统范围信息。

    构建提供的ROS Docker映像:

    cd /PATH/TO/Unity-Robotics-Hub/tutorials/pick_and_place &&
    git submodule update --init --recursive &&
    docker build -t unity-robotics:pick-and-place -f docker/Dockerfile .
    
    • 1
    • 2
    • 3

    这里提供的Dockerfile使用ROS Melodic基本镜像并安装必要的包,将提供的ROS包和子模块复制到容器中,并构建ROS工作区。

    启动新建的Docker容器

    docker run -it --rm -p 10000:10000 unity-robotics:pick-and-place /bin/bash
    
    • 1

    3.2 手动设置

    导航到这个下载的repo的/PATH/ to /Unity-Robotics-Hub/tutorials/pick_and_place/ROS目录,然后在ROS Melodic环境中运行以下命令

    sudo apt-get update && sudo apt-get upgrade
    sudo apt-get install python-pip ros-melodic-robot-state-publisher ros-melodic-moveit ros-melodic-rosbridge-suite ros-melodic-joy ros-melodic-ros-control ros-melodic-ros-controllers ros-melodic-tf2-web-republisher
    sudo -H pip install rospkg jsonpickle
    
    • 1
    • 2
    • 3

    ROS Noetic用户应运行

    sudo apt-get update && sudo apt-get upgrade
    sudo apt-get install python3-pip ros-noetic-robot-state-publisher ros-noetic-moveit ros-noetic-rosbridge-suite ros-noetic-joy ros-noetic-ros-control ros-noetic-ros-controllers
    sudo -H pip3 install rospkg jsonpickle
    
    • 1
    • 2
    • 3

    如果您在导入新的ROS包之后还没有构建和源化ROS工作区,请导航到您的ROS工作区,并运行catkin_make && source devel/setup.bash。确保没有错误。

    3.3 ros_tcp_endpoint

    打开一个容器的终端,导航到 ~/catkin_ws ,执行

    source devel/setup.bash
    roslauch ros_tcp_endpoint endpoint.launch tcp_ip:=127.0.0.1 tcp_port:=10000 # 将127.0.0.1替换为所需的ip,将10000替换为所需要的端口号。
    
    • 1
    • 2

    4. URDF文件导入

    为了检查整个物理模型是否导入,我们需要检查以下几点项目设置:

    打开菜单“Window→Package Manager”,确认是否导入了“URDF Importer”(在上面已经完成安装)。在Unity中导入“URDF”,使用“URDF Importer”。
    在这里插入图片描述

    在菜单“Edit→Project Settings→Physics”中确认“SolverType”是“TemporalGaussSeidel”。以防止关节不稳定的动作由默认的求解器引起。
    在这里插入图片描述
    然后下面就是对场景进行设置:

    1. 将“Asssets/Prefabs”中的“Table”、“Target”、“TargetPlacement”拖拽到Hierarchy窗口。
    2. 将MainCamera的Transform设定如下。

    ・Position : (0, 1.4, -0.7)
    ・Rotation : (45, 0, 0)
    ・Rotation : (1, 1, 1)

    在这里插入图片描述
    接下来导入URDF

    1. 在Project窗口右键点击URDF文件“Assets/niryo_one/niryo_one”,选择“Import Robot form Selected URDF file”

    …详情请参照古月居

    ``` 成功后,会显示以下信息
    [INFO] [1634298752.158262]: Starting server on 172.17.0.2:10000
    
    • 1
    1. 在Unity编辑器中按Play按钮。

    2. 按Publish键。相关数据会在ROS主题中公布。

    3. 确认正在运行roslaunch的终端。并输出了相关数据。

    I heard:
    joints: [-0.00016236382361967117, -0.007215713616460562, -0.0010509941494092345, 0.01564762368798256, 0.00016680661065038294, 0.00013635685900226235]
    pick_pose: 
     position: 
       x: -0.157005697489
       y: -0.216008037329
       z: 0.643718481064
     orientation: 
       x: -1.49643722125e-06
       y: -0.707106769085
       z: 1.49643722125e-06
       w: -0.707106769085
    place_pose: 
     position: 
       x: -0.187000006437
       y: 0.216000005603
       z: 0.639999985695
     orientation: 
       x: -0.499999970198
       y: -0.499999970198
       z: 0.499999970198
       w: -0.499999970198
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    我们看一下代码就可以发现在,代码中我们发布了NiryoMoveitJointsMsg。这个msg信息中保存着以下信息。

    ·Joint的角度(float[])
    ·Target姿势(vector+quaternion)
    ·TargetPlacement的姿势(vector+quaternion)

    下面是本例子的注释

    using System;
    using RosMessageTypes.Geometry;
    using RosMessageTypes.NiryoMoveit;
    using Unity.Robotics.ROSTCPConnector;
    using Unity.Robotics.ROSTCPConnector.ROSGeometry;
    using Unity.Robotics.UrdfImporter;
    using UnityEngine;
    
    // 发布者
    public class SourceDestinationPublisher : MonoBehaviour
    {
        // 关键数
        const int k_NumRobotJoints = 6;
    
        // tf
        public static readonly string[] LinkNames =
            { "world/base_link/shoulder_link", "/arm_link", "/elbow_link", "/forearm_link", "/wrist_link", "/hand_link" };
    
        // Topic节点名称
        [SerializeField]
        string m_TopicName = "/niryo_joints";
    
        // 作为object传入的参数
        [SerializeField]
        GameObject m_NiryoOne;
        [SerializeField]
        GameObject m_Target;
        [SerializeField]
        GameObject m_TargetPlacement;
        readonly Quaternion m_PickOrientation = Quaternion.Euler(90, 90, 0);
    
        // 关节
        UrdfJointRevolute[] m_JointArticulationBodies;
    
        // ROS连接命名
        ROSConnection m_Ros;
    
        void Start()
        {
            // ROS连接准备
            m_Ros = ROSConnection.GetOrCreateInstance();
    
            // 发布者的生成
            m_Ros.RegisterPublisher<NiryoMoveitJointsMsg>(m_TopicName);
    
            // 关节信息获取
            m_JointArticulationBodies = new UrdfJointRevolute[k_NumRobotJoints];
            var linkName = string.Empty;
            for (var i = 0; i < k_NumRobotJoints; i++)
            {
                linkName += LinkNames[i];
                m_JointArticulationBodies[i] = m_NiryoOne.transform.Find(linkName).GetComponent<UrdfJointRevolute>();
            }
        }
    
        // パ发布的程序
        public void Publish()
        {
            // 信息的定义
            var sourceDestinationMessage = new NiryoMoveitJointsMsg();
    
            // Joint角度的传输
            for (var i = 0; i < k_NumRobotJoints; i++)
            {
                sourceDestinationMessage.joints[i] = m_JointArticulationBodies[i].GetPosition();
            }
    
            // Target姿态的传输
            sourceDestinationMessage.pick_pose = new PoseMsg
            {
                position = m_Target.transform.position.To<FLU>(),
                orientation = Quaternion.Euler(90, m_Target.transform.eulerAngles.y, 0).To<FLU>()
            };
    
            // TargetPlacement姿态的传输
            sourceDestinationMessage.place_pose = new PoseMsg
            {
                position = m_TargetPlacement.transform.position.To<FLU>(),
                orientation = m_PickOrientation.To<FLU>()
            };
    
            // 根据connection发布topic
            m_Ros.Publish(m_TopicName, sourceDestinationMessage);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    7. 参考链接

    https://github.com/Unity-Technologies/Unity-Robotics-Hub

    https://www.guyuehome.com/40908

    https://codeantenna.com/a/I1dRyJjemI

    https://github.com/Unity-Technologies/Robotics-Object-Pose-Estimation

    https://github.com/Unity-Technologies/articulations-robot-demo

  • 相关阅读:
    Linux I/O 原理和 Zero-copy 技术全面分析
    VIT(Vision Transformer)学习(二)- 基础代码学习
    云服务器部署k8s集群
    Docker Swarm 网络
    Jenkins最新版java11的docker安装教程
    Shopify是什么平台?可以做测评吗?
    Webpack字体文件处理指南
    WEB 渗透之信息收集
    【c语言】通讯录【动态版本:有排序和文件操作】
    PAE-PEG-HSA 聚(β-氨基酯)-聚乙二醇-人血清白蛋白,BSA/OVA修饰聚(β-氨基酯)
  • 原文地址:https://blog.csdn.net/lovely_yoshino/article/details/128190276