Unity实现物理与虚拟车间的联动(一)

时隔几年后更新:看到评论很多想要demo,其实内容上我基本已经比较详细写了怎么实现了,调用的也是基础的方法。这个项目做完也就没管过了,代码也都没有了。最近两年转做基于虚幻引擎的相关软件研制工作了,也会尽量挤时间分享下UE的学习记录。

对六轴机械臂的简单控制

上周开始做一个新项目,需要在Unity里实现一个六轴机械臂的实体与模型的联动。机械臂传输回来的数据包含每一个轴当前旋转的角度,当然,这个角度是机械臂自身按照自己的坐标系计算的。所以在Unity中要想实现转到同样的位置,必然还需要对数据进行角度转换。目前由于机械臂的通信还在调试,所以先在Unity中实现了对机械臂的简易控制。

本人是新手,所以实现方法可能不是最好的。但是分享出来供大家参考。

先贴上机械臂的图:

unity 3D机器人仿真 unity机械仿真_六轴机械臂

由于这个模型是别人做的,模型是由一块块小零件组合而成。如图:

unity 3D机器人仿真 unity机械仿真_机械臂_02


可以看出来零件是非常多的,所以第一步我是按照每一个部分,将零件归类整理,这样方便下一步的操作,如图:

unity 3D机器人仿真 unity机械仿真_六轴机械臂_03


接下来就是要对每一个部分进行控制了。其实对机械臂的控制很简单,每一个关节只有旋转。所以首先想到的是能不能用Physics下面的joint呢?经过尝试以后,发现效果并不好。很难实现要求的按照传过来的角度进行控制。


再经过一番思考,发现其实可以通过创建一个空物体,也就是一个点,将它作为父级,对应的机械臂上的模块作为子集。例如:

unity 3D机器人仿真 unity机械仿真_unity 3D机器人仿真_04


我在一轴加了一个点,然后把机械臂上面的所有部分作为它的子级,这时候,我只要旋转Z轴,就可以实现机械臂的左右旋转,其他几个关节同理,最后Hierarchy里面的视图是这样的

unity 3D机器人仿真 unity机械仿真_unity 3D机器人仿真_05


标注的红线就是我所添加的空物体,然后在Point1下面添加C#脚本。

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Arm : MonoBehaviour {
    public float speed1 = 0.1f;
    public float speed2 = 0.1f;
    public float speed3 = 0.1f;
    public float speed4 = 0.2f;
    public float speed5 = 0.2f;
    public float speed6 = 0.2f;

    GameObject Point1;
    GameObject Point2;
    GameObject Point3;
    GameObject Point4;
    GameObject Point5;
    GameObject Point6;
    
	// Use this for initialization
	void Start ()
    {
        Point1 = GameObject.Find("Point1");
        Point2 = GameObject.Find("Point2");
        Point3 = GameObject.Find("Point3");
        Point4 = GameObject.Find("Point4");
        Point5 = GameObject.Find("Point5");
        Point6 = GameObject.Find("Point6");
       
	}

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            //一轴左转
            Point1.transform.Rotate(0,0,-speed1);
        }
        if (Input.GetKey(KeyCode.D))
        {
            //一轴右转
            Point1.transform.Rotate(0, 0, speed1);
        }
        if (Input.GetKey(KeyCode.W))
        {
            //二轴向前
            Point2.transform.Rotate(0,0,speed2);
        }
        if (Input.GetKey(KeyCode.S))
        {
            //二轴向后
            Point2.transform.Rotate(0, 0, -speed2);
        }
        if (Input.GetKey(KeyCode.UpArrow))
        {
            //三轴向上
            Point3.transform.Rotate(0, 0, -speed3);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            //三轴向下
            Point3.transform.Rotate(0, 0, speed3);
        }
        if (Input.GetKey(KeyCode.Q))
        {
            //四轴逆时针
            Point4.transform.Rotate(speed4, 0,0 );
        }
        if (Input.GetKey(KeyCode.E))
        {
            //四轴顺时针
            Point4.transform.Rotate(-speed4, 0, 0);
        }
        if (Input.GetKey(KeyCode.Alpha1))
        {
            //五轴向上
            Point5.transform.Rotate(0,0, -speed5);
        }
        if (Input.GetKey(KeyCode.Alpha2))
        {
            //五轴向下
            Point5.transform.Rotate(0, 0,speed5 );
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            //六轴逆时针
            Point6.transform.Rotate(speed6, 0, 0);
        }
        if (Input.GetKey(KeyCode.RightArrow))
            Point6.transform.Rotate(-speed6, 0, 0);
        {
            //六轴顺时针
        }


    }
}