Skip to content

Commit 0191e3e

Browse files
committed
URDF transform to Unity working.
1 parent 1994fa6 commit 0191e3e

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

Runtime/Scripts/Util/Extensions/ZOROSConversionExtensions.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ public static Vector3 Unity2RosRollPitchYaw(this Quaternion q) {
3333
-q.eulerAngles.y * Mathf.Deg2Rad);
3434
}
3535

36+
public static Quaternion RosRollPitchYawToQuaternion(this Vector3 rpy) {
37+
// Negate X and Z because we're going from Right to Left handed rotations. Y is handled because the axis itself is flipped
38+
rpy.x *= -1;
39+
rpy.z *= -1;
40+
rpy *= Mathf.Rad2Deg;
41+
42+
// swap the angle values
43+
rpy = new Vector3(rpy.y, rpy.z, rpy.x);
44+
45+
// Applying rotations in ZYX ordering, as indicated above
46+
Quaternion q = Quaternion.identity;
47+
48+
q *= Quaternion.Euler(0, rpy.y, 0);
49+
q *= Quaternion.Euler(rpy.x, 0, 0);
50+
q *= Quaternion.Euler(0, 0, rpy.z);
51+
52+
53+
return q;
54+
}
55+
3656
public static string ToXMLString(this Vector3 v) {
3757
return $"{v.x} {v.y} {v.z}";
3858
}
@@ -58,7 +78,7 @@ public static Vector3 FromURDFStringToVector3(this string s) {
5878
Debug.LogWarning($"Could not parse string: {s}");
5979

6080
return Vector3.zero;
61-
}
81+
}
6282

6383

6484
}

Runtime/Scripts/Util/ImportExport/ZOImportURDF.cs

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,30 +61,30 @@ public static ZOSimDocumentRoot Import(XmlDocument xmlDocument) {
6161
XmlNode[] xmlVisuals = xmlLink.GetChildrenByName("visual");
6262

6363
foreach (XmlNode xmlVisual in xmlVisuals) {
64-
65-
64+
65+
6666
XmlNode[] xmlGeometries = xmlVisual.GetChildrenByName("geometry");
6767

6868
foreach (XmlNode xmlGeom in xmlGeometries) {
69-
69+
7070
GameObject visualGeo = null;
7171

7272
XmlNode xmlBox = xmlGeom.GetChildByName("box");
7373
if (xmlBox != null) {
7474
visualGeo = GameObject.CreatePrimitive(PrimitiveType.Cube);
7575
Vector3 size = xmlBox.Attributes["size"].Value.FromURDFStringToVector3();
76-
76+
7777
visualGeo.transform.localScale = size.Ros2UnityScale();
7878
}
79-
79+
8080
XmlNode xmlCylinder = xmlGeom.GetChildByName("cylinder");
8181
if (xmlCylinder != null) {
8282
visualGeo = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
8383
float radius = float.Parse(xmlCylinder.Attributes["radius"].Value);
8484
float length = float.Parse(xmlCylinder.Attributes["length"].Value);
8585
visualGeo.transform.localScale = new Vector3(radius * 2.0f, length * 0.5f, radius * 2.0f);
8686
}
87-
87+
8888
XmlNode xmlSphere = xmlGeom.GetChildByName("sphere");
8989
if (xmlSphere != null) {
9090
visualGeo = GameObject.CreatePrimitive(PrimitiveType.Sphere);
@@ -97,14 +97,23 @@ public static ZOSimDocumentRoot Import(XmlDocument xmlDocument) {
9797
// TODO
9898
}
9999
if (visualGeo != null) {
100+
// set parent
100101
visualGeo.transform.SetParent(goVisualsEmpty.transform);
101102
string visualName = xmlVisual.Attributes["name"].Value;
102103
if (visualName != null) {
103104
visualGeo.name = visualName;
104105
}
106+
107+
// set transform
108+
XmlNode xmlOrigin = xmlVisual.GetChildByName("origin");
109+
Tuple<Vector3, Quaternion> transform = OriginXMLToUnity(xmlOrigin);
110+
visualGeo.transform.localPosition = transform.Item1;
111+
visualGeo.transform.localRotation = transform.Item2;
112+
105113
}
106114

107115
}
116+
108117
}
109118

110119
// get the origin
@@ -118,6 +127,8 @@ public static ZOSimDocumentRoot Import(XmlDocument xmlDocument) {
118127

119128
// find link parent
120129
GameObject linkParent = rootObject;
130+
GameObject linkChild = goLink.Value.Item2;
131+
XmlNode workingJoint = null;
121132
foreach (XmlNode joint in xmlJoints) {
122133
XmlNode xmlChildLink = joint.GetChildByName("child");
123134
string childName = xmlChildLink.Attributes["link"].Value;
@@ -126,18 +137,48 @@ public static ZOSimDocumentRoot Import(XmlDocument xmlDocument) {
126137
XmlNode xmlParentLink = joint.GetChildByName("parent");
127138
string parentName = xmlParentLink.Attributes["link"].Value;
128139
linkParent = goLinks[parentName].Item2;
140+
141+
workingJoint = joint;
142+
129143
break;
130144
}
131145

132146
}
133147

134-
goLink.Value.Item2.transform.SetParent(linkParent.transform);
135-
ZOSimOccurrence occurrence = goLink.Value.Item2.AddComponent<ZOSimOccurrence>();
148+
linkChild.transform.SetParent(linkParent.transform);
149+
ZOSimOccurrence occurrence = linkChild.AddComponent<ZOSimOccurrence>();
150+
151+
// set transform
152+
if (workingJoint != null) {
153+
XmlNode xmlOrigin = workingJoint.GetChildByName("origin");
154+
Tuple<Vector3, Quaternion> transform = OriginXMLToUnity(xmlOrigin);
155+
linkChild.transform.localPosition = transform.Item1;
156+
linkChild.transform.localRotation = transform.Item2;
157+
158+
}
159+
136160

137161
}
138162

139163
return simDocumentRoot;
140164
}
141165

166+
protected static Tuple<Vector3, Quaternion> OriginXMLToUnity(XmlNode xmlOrigin) {
167+
Vector3 translation = Vector3.zero;
168+
string xyz = xmlOrigin.Attributes["xyz"].Value;
169+
if (xyz != null && xyz != "") {
170+
translation = xyz.FromURDFStringToVector3().Ros2Unity();
171+
}
172+
173+
Quaternion rotation = Quaternion.identity;
174+
string rpy = xmlOrigin.Attributes["rpy"].Value;
175+
if (rpy != null && rpy != "") {
176+
rotation = rpy.FromURDFStringToVector3().RosRollPitchYawToQuaternion();
177+
}
178+
Tuple<Vector3, Quaternion> transform = new Tuple<Vector3, Quaternion>(translation, rotation);
179+
180+
return transform;
181+
}
182+
142183
}
143184
}

0 commit comments

Comments
 (0)