写在前面
本人目前研二下,第一次写这个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 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,
data.Joint5,
data.Joint6
};
// 遍历每个关节并应用旋转
for (int i = 0; i < 6; i++)
{
if (robotJoints[i] != null)
{
// 获取当前关节的初始旋转
Quaternion initialRotation = initialJointRotations[i];
// 根据轴配置创建旋转
Quaternion rotation = Quaternion.AngleAxis(jointValues[i], axisRotationInfo[i]);
// 应用旋转(相对于初始旋转)
robotJoints[i].transform.localRotation = initialRotation * rotation;
}
}
}
// 更新 TCP 信息的 UI 显示
void Update