英文:
Problem with rotation of an AR object with Vuforia
问题
I'm facing issues with the rotation of an object, I'm using Unity and Vuforia. I have a kinematic chain (it's a robotic arm) and I want to control his movement. I have a Remote Controller which sends a string with angular position for each link of the robot. I decode the string and then assign the final position for each link. I'm using slerp to modify the local rotations.
When I try this code without Vuforia, the code works well, and the links rotate, but when I use Vuforia and the chain is above the marker, I can make the links rotate, but then all of them come to their original position. I don't know why I have this behavior.
This is the code I am working on. I've also tried updating the position of each link, but I suppose I don't need that because I am working with local angles. I am receiving data through TCP/IP.
using UnityEngine;
using Vuforia;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using TMPro;
public class MyListener : MonoBehaviour
{
// ... (the code continues)
}
I appreciate your collaboration. Thanks.
英文:
I'm facing issues with the rotation of an object, I'm using Unity and Vuforia. I have a kinematic chain (it's a robotic arm) and I want to control his movement. I have a Remote Controller which sends a string with angular position for each link of the robot. I decode the string and then assign final position for each link. I'm using slerp to modify the local rotations.
When I try this code without Vuforia, the code works well and the links rotate, but when I use Vuforia and the chain is above the marker, I can make the links rotate but then all of them come to their original position. I don't know why I have this behaviour.
This is the code I am working, I've tried also updating the position of each link, but I suppose I don't need that because I am working with local angles. I am receiving data through TCP/IP.
using UnityEngine;
using Vuforia;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using TMPro;
public class MyListener : MonoBehaviour
{
public int connectionPort = 25001;
TcpListener listener;
string[] stringArray;
float[] Objetivo;
float[] posInicial;
float[] currAngle;
string msg;
public Transform[] Link = new Transform[6];
Quaternion[] startRotation = new Quaternion[6];
Quaternion[] currentRotation = new Quaternion[6];
Quaternion[] smoothRotation = new Quaternion[6];
Quaternion[] endRotation = new Quaternion[6];
int flagGiro, remoto;
public int flag;
float duration = 3f;
public TMP_Text Text1;
public TMP_Text Text2;
public TMP_Text Text3;
public TMP_Text Text4;
public TMP_Text Text5;
public TMP_Text Text6;
void Start()
{
flagGiro = 0;
flag=0;
remoto = 0;
listener = new TcpListener(IPAddress.Any, connectionPort);
listener.Start();
for (int i=0;i<6;i++){
startRotation[i] = Quaternion.Euler(0, 0, 0);
}
}
void Update()
{
if (!listener.Pending()){
flag=0;
for (int i = 0; i < 6; i++)
{
Link[i].localRotation = endRotation[i];
}
if (remoto==1)
{
for (int i = 0; i < 6; i++)
{
Link[i].localRotation = endRotation[i];
}
}
}
else {
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
StreamReader reader = new StreamReader(ns);
msg = reader.ReadToEnd();
stringArray = ParseData(msg);
Text1.text = stringArray[0];
Text2.text = stringArray[1];
Text3.text = stringArray[2];
Text4.text = stringArray[3];
Text5.text = stringArray[4];
Text6.text = stringArray[5];
//x,y,z también pueden ser un array
float y = float.Parse(stringArray[0]);
float x = float.Parse(stringArray[1]);
float x1 = float.Parse(stringArray[2]);
float y1 = float.Parse(stringArray[3]);
float z = float.Parse(stringArray[4]);
float x3 = float.Parse(stringArray[5]);
endRotation[0] = Quaternion.Euler(Link[0].localEulerAngles.x, y, Link[0].localEulerAngles.z); //endRotation[0] = Quaternion.Euler(0, y/div, 0);
endRotation[1] = Quaternion.Euler(x, Link[1].localEulerAngles.y, Link[1].localEulerAngles.z);
endRotation[2] = Quaternion.Euler(x1, Link[2].localEulerAngles.y, Link[2].localEulerAngles.z);
endRotation[3] = Quaternion.Euler(Link[3].localEulerAngles.x, y1, Link[3].localEulerAngles.z);
endRotation[4] = Quaternion.Euler(Link[4].localEulerAngles.x, Link[4].localEulerAngles.y, z);
endRotation[5] = Quaternion.Euler(x3, Link[5].localEulerAngles.y, Link[5].localEulerAngles.z);
// Obtener las rotaciones iniciales de los objetos secundarios
for (int i = 0; i < 6; i++)
{
startRotation[i] = Link[i].localRotation;
}
StartCoroutine(RotateObject(duration));
}
}
public static string[] ParseData(string dataString)
{
Debug.Log(dataString);
if (dataString[0]==':'){
dataString = dataString.Remove(dataString.Length-4);
dataString = dataString.Substring(1);
}
// Split the elements into an array
string[] stringArray = dataString.Split('/');
return stringArray;
}
IEnumerator RotateObject(float duration)
{
for (int i = 0; i < 6; i++)
{
startRotation[i] = Link[i].localRotation;
}
float elapsedTime = 0f;
while (elapsedTime < duration)
{
for (int i = 0; i < 6; i++)
{
smoothRotation[i] = Quaternion.Slerp(startRotation[i], endRotation[i], elapsedTime / duration);
Link[i].localRotation = smoothRotation[i];
}
elapsedTime += Time.deltaTime;
yield return null;
}
for (int i = 0; i < 6; i++)
{
Link[i].localRotation = endRotation[i];
Vector3 endPosition = Link[i].localPosition;
Link[i].localPosition = endPosition;
}
remoto = 1;
}
}
I appreciate your collaboration. Thanks
答案1
得分: 1
请看下方的翻译:
"Since your marker is most probably not at (0, 0, 0) or at the same position as your remote controller assumes the robot to be, the local rotations cannot be correct. You can verify this by placing your marker in Unity at the matching robot origin. As you said yourself, everythings moves back to their "original" position."
"由于你的标志物很可能不在(0, 0, 0)处,或者与你的遥控器假设机器人所在位置不同,所以本地旋转可能不正确。你可以通过在Unity中将你的标志物放置在匹配的机器人原点来验证这一点。正如你自己所说,一切都会回到它们的“原始”位置。"
"What you need to do is to convert your rotations into your marker coordinate system. If your position really is irrelvant, you can convert your quaternions only. If you need further input for that, take a look at this quaternionToLocal."
"你需要做的是将你的旋转转换成你的标志物坐标系。如果你的位置确实无关紧要,你可以只转换你的四元数。如果需要更多的信息,请查看这个quaternionToLocal。"
"Generally, I would suggest using rotation matrices especially in the context of kinematic chains of robots. With these (homogeneous) transformation matrices conversion between coordinates systems reduces to simple multiplication."
"一般来说,我建议在机器人的运动链上特别是上下文中使用旋转矩阵。使用这些(齐次)转换矩阵,坐标系之间的转换变得简化为简单的乘法。"
"I hope the idea is clear. Let me know if you need any further information:)"
"希望这个想法清楚明白。如果你需要更多信息,请告诉我:)"
英文:
Since your marker is most probably not at (0, 0, 0) or at the same position as your remote controller assumes the robot to be, the local rotations cannot be correct. You can verify this by placing your marker in Unity at the matching robot origin. As you said yourself, everythings moves back to their "original" position.
What you need to do is to convert your rotations into your marker coordinate system. If your position really is irrelvant, you can convert your quaternions only. If you need further input for that, take a look at this quaternionToLocal.
Generally, I would suggest using rotation matrices especially in the context of kinematic chains of robots. With these (homogeneous) transformation matrices conversion between coordinates systems reduces to simple multiplication.
I hope the idea is clear. Let me know if you need any further information:)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论