写在前面
本人目前研二下,第一次写这个blog,菜的一批,一部分python和unity代码是在我几个同门帮助下完成的,历经千辛万苦,拖了一天又一天,终于完成,深知自己不适合读研,希望早日毕业,因此写这篇文章记录一下学习过程。😅
一、软件介绍
1.Unity 2022.3.55(unity官网下载)
2.OPC UA 服务器的插件Iot Gateway(ABB官网下载)
3.UaExpert软件 (Downloads - Unified Automation)
4.Pycharm 2020.1(python3.7)
5.Robotstudio 6.08(后面简称RS)
二、效果展示
打包在其他工控机上可视化:
三、实现过程
1、unity只与虚拟ABB机器人Robot studio通讯
1)首先要有一个RS的机器人仿真工作站,并且仿真可以运行。
2)unity需要有一个RobotToAPP的包,我在unitystore官网买的(用于制作游戏的优质资源 | Unity Asset Store),C#代码会调用RobotToAPP方法。
1.unity设置UI,并绑定变量
2.unity C#代码如下:
using System.Collections;
//using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using RobotToAPP;
//using TMPro;
//using static RobotToAPPSamples;
public class RobotToUnity : MonoBehaviour
{
public Text[] jointTexts; // 引用用于显示关节数据
public GameObject[] robotJoints; // 引用机器人的 6 个关节 GameObject
private Quaternion[] initialJointRotations; // 保存关节的初始旋转
public Text[] tcpTexts;// 引用用于显示 TCP 信息
public Text[] quaternionTexts;// 引用用于显示四元数信息
public Text[] externalAxisTexts;// 引用用于显示外部轴数据
private Vector3[] axisRotationInfo = new[]
{
new Vector3(0, 0, 1), // 轴1:绕 Z 轴,正向
new Vector3(0, -1, 0), // 轴2:绕 Y 轴,反向
new Vector3(0, -1, 0), // 轴3:绕 Y 轴,反向
new Vector3(-1, 0, 0), // 轴4:绕 X 轴,反向
new Vector3(0, -1, 0), // 轴5:绕 Y 轴,反向
new Vector3(-1, 0, 0) // 轴6:绕 X 轴,反向
};
void Start()
{
// 初始化初始旋转数组
initialJointRotations = new Quaternion[6];
for (int i = 0; i < 6; i++)
{
if (robotJoints.Length > i && robotJoints[i] != null)
{
initialJointRotations[i] = robotJoints[i].transform.localRotation;
}
}
ABBCommunicator.Instance.HOST = "http://localhost/";
StartCoroutine(PeriodicallyReadJoints());
//PerformAdditionalActions();// 调用封装的方法
}
IEnumerator PeriodicallyReadJoints()
{
while (true)
{
// 读取关节数据
ReadJointAction jointAction = new ReadJointAction();
jointAction.OnCompleted = jointData =>
{
UpdateJointTexts(jointData);
DriveRobotJoints(jointData);
};
jointAction.Execute();
// 读取 TCP 和四元数数据
ReadRobotTargetAction targetAction = new ReadRobotTargetAction();
targetAction.OnCompleted = targetData =>
{
UpdateTcpTexts(targetData);
UpdateQuaternionTexts(targetData);
};
targetAction.Execute();
// 读取外部轴数据
ReadExternalJointAction externalAction = new ReadExternalJointAction();
externalAction.OnCompleted = externalData =>
{
UpdateExternalAxisTexts(externalData);
};
externalAction.Execute();
// 每 0.1 秒读取一次数据,可根据需要调整间隔时间
yield return new WaitForSeconds(0.1f);
}
}
// 更新关节数据的 UI 显示
void UpdateJointTexts(JointsData data)
{
if (jointTexts.Length >= 6)
{
jointTexts[0].text = $"Joint1: {data.Joint1}";
jointTexts[1].text = $"Joint2: {data.Joint2}";
jointTexts[2].text = $"Joint3: {data.Joint3}";
jointTexts[3].text = $"Joint4: {data.Joint4}";
jointTexts[4].text = $"Joint5: {data.Joint5}";
jointTexts[5].text = $"Joint6: {data.Joint6}";
}
}
void DriveRobotJoints(JointsData data)
{
if (robotJoints.Length >= 6)
{
float[] jointValues = new float[6]
{
data.Joint1,
data.Joint2,
data.Joint3,
data.Joint4,