Skip to content

Commit 5410af3

Browse files
committed
refactor(UrdfVisual, UrdfUtils): Convert UrdfVisual to TypeScript, add isElement check in UrdfUtils
Signed-off-by: Drew Hoener <[email protected]>
1 parent 16122cf commit 5410af3

File tree

3 files changed

+59
-109
lines changed

3 files changed

+59
-109
lines changed

src/urdf/UrdfUtils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,9 @@ export function parseUrdfOrigin(originElement: Element): Pose {
5151
position: position,
5252
orientation: orientation
5353
});
54-
}
54+
}
55+
56+
export function isElement(node: Node): node is Element {
57+
// Node.ELEMENT_TYPE = 1
58+
return node.nodeType === 1;
59+
}

src/urdf/UrdfVisual.ts

Lines changed: 51 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -5,132 +5,76 @@
55
*/
66

77
import Pose from '../math/Pose.js';
8-
import Vector3 from '../math/Vector3.js';
9-
import Quaternion from '../math/Quaternion.js';
10-
118
import UrdfCylinder from './UrdfCylinder.js';
129
import UrdfBox from './UrdfBox.js';
1310
import UrdfMaterial from './UrdfMaterial.js';
1411
import UrdfMesh from './UrdfMesh.js';
1512
import UrdfSphere from './UrdfSphere.js';
13+
import { UrdfAttrs, type UrdfDefaultOptions } from './UrdfTypes.js';
14+
import { isElement, parseUrdfOrigin } from './UrdfUtils.js';
15+
16+
export type UrdfGeometryLike = UrdfMesh | UrdfSphere | UrdfBox | UrdfCylinder;
17+
18+
function parseUrdfGeometry(geometryElem: Element): UrdfGeometryLike | null {
19+
20+
let childShape: Element | null = null;
21+
for (const childNode of geometryElem.childNodes) {
22+
if (isElement(childNode)) {
23+
// Safe type check after checking nodeType
24+
childShape = childNode;
25+
break;
26+
}
27+
}
28+
29+
if (!childShape) {
30+
return null;
31+
}
32+
33+
const options: UrdfDefaultOptions = {
34+
xml: childShape
35+
}
36+
37+
switch (childShape.nodeName) {
38+
case 'sphere':
39+
return new UrdfSphere(options);
40+
case 'box':
41+
return new UrdfBox(options);
42+
case 'cylinder':
43+
return new UrdfCylinder(options);
44+
case 'mesh':
45+
return new UrdfMesh(options);
46+
default:
47+
console.warn(`Unknown geometry type ${childShape.nodeName}`);
48+
return null
49+
}
50+
}
1651

1752
/**
1853
* A Visual element in a URDF.
1954
*/
2055
export default class UrdfVisual {
21-
/** @type {Pose | null} */
22-
origin = null;
23-
/** @type {UrdfMesh | UrdfSphere | UrdfBox | UrdfCylinder | null} */
24-
geometry = null;
25-
/** @type {UrdfMaterial | null} */
26-
material = null;
27-
/**
28-
* @param {Object} options
29-
* @param {Element} options.xml - The XML element to parse.
30-
*/
31-
constructor(options) {
32-
var xml = options.xml;
33-
this.name = options.xml.getAttribute('name');
56+
name: string | null;
57+
origin: Pose | null = new Pose();
58+
geometry: UrdfGeometryLike | null = null;
59+
material: UrdfMaterial | null = null;
3460

35-
// Origin
36-
var origins = xml.getElementsByTagName('origin');
37-
if (origins.length === 0) {
38-
// use the identity as the default
39-
this.origin = new Pose();
40-
} else {
41-
// Check the XYZ
42-
var xyzValue = origins[0].getAttribute('xyz');
43-
var position = new Vector3();
44-
if (xyzValue) {
45-
var xyz = xyzValue.split(' ');
46-
position = new Vector3({
47-
x: parseFloat(xyz[0]),
48-
y: parseFloat(xyz[1]),
49-
z: parseFloat(xyz[2])
50-
});
51-
}
52-
53-
// Check the RPY
54-
var rpyValue = origins[0].getAttribute('rpy');
55-
var orientation = new Quaternion();
56-
if (rpyValue) {
57-
var rpy = rpyValue.split(' ');
58-
// Convert from RPY
59-
var roll = parseFloat(rpy[0]);
60-
var pitch = parseFloat(rpy[1]);
61-
var yaw = parseFloat(rpy[2]);
62-
var phi = roll / 2.0;
63-
var the = pitch / 2.0;
64-
var psi = yaw / 2.0;
65-
var x =
66-
Math.sin(phi) * Math.cos(the) * Math.cos(psi) -
67-
Math.cos(phi) * Math.sin(the) * Math.sin(psi);
68-
var y =
69-
Math.cos(phi) * Math.sin(the) * Math.cos(psi) +
70-
Math.sin(phi) * Math.cos(the) * Math.sin(psi);
71-
var z =
72-
Math.cos(phi) * Math.cos(the) * Math.sin(psi) -
73-
Math.sin(phi) * Math.sin(the) * Math.cos(psi);
74-
var w =
75-
Math.cos(phi) * Math.cos(the) * Math.cos(psi) +
76-
Math.sin(phi) * Math.sin(the) * Math.sin(psi);
61+
constructor({ xml }: UrdfDefaultOptions) {
62+
this.name = xml.getAttribute(UrdfAttrs.Name);
7763

78-
orientation = new Quaternion({
79-
x: x,
80-
y: y,
81-
z: z,
82-
w: w
83-
});
84-
orientation.normalize();
85-
}
86-
this.origin = new Pose({
87-
position: position,
88-
orientation: orientation
89-
});
64+
// Origin
65+
const origins = xml.getElementsByTagName(UrdfAttrs.Origin);
66+
if (origins.length > 0) {
67+
this.origin = parseUrdfOrigin(origins[0]);
9068
}
9169

9270
// Geometry
93-
var geoms = xml.getElementsByTagName('geometry');
71+
const geoms = xml.getElementsByTagName(UrdfAttrs.Geometry);
9472
if (geoms.length > 0) {
95-
var geom = geoms[0];
96-
var shape = null;
97-
// Check for the shape
98-
for (var i = 0; i < geom.childNodes.length; i++) {
99-
/** @type {Element} */
100-
// @ts-expect-error -- unknown why this doesn't work properly.
101-
var node = geom.childNodes[i];
102-
if (node.nodeType === 1) {
103-
shape = node;
104-
break;
105-
}
106-
}
107-
if (shape) {
108-
// Check the type
109-
var type = shape.nodeName;
110-
if (type === 'sphere') {
111-
this.geometry = new UrdfSphere({
112-
xml: shape
113-
});
114-
} else if (type === 'box') {
115-
this.geometry = new UrdfBox({
116-
xml: shape
117-
});
118-
} else if (type === 'cylinder') {
119-
this.geometry = new UrdfCylinder({
120-
xml: shape
121-
});
122-
} else if (type === 'mesh') {
123-
this.geometry = new UrdfMesh({
124-
xml: shape
125-
});
126-
} else {
127-
console.warn('Unknown geometry type ' + type);
128-
}
129-
}
73+
this.geometry = parseUrdfGeometry(geoms[0]);
13074
}
13175

13276
// Material
133-
var materials = xml.getElementsByTagName('material');
77+
const materials = xml.getElementsByTagName(UrdfAttrs.Material);
13478
if (materials.length > 0) {
13579
this.material = new UrdfMaterial({
13680
xml: materials[0]

src/urdf/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export { default as UrdfMaterial } from './UrdfMaterial.js';
66
export { default as UrdfMesh } from './UrdfMesh.js';
77
export { default as UrdfModel } from './UrdfModel.js';
88
export { default as UrdfSphere } from './UrdfSphere.js';
9-
export { default as UrdfVisual } from './UrdfVisual.js';
9+
export { default as UrdfVisual, type UrdfGeometryLike } from './UrdfVisual.js';
1010

1111
export {UrdfAttrs, UrdfType, type UrdfDefaultOptions} from './UrdfTypes.js';
12+
export {isElement, parseUrdfOrigin} from './UrdfUtils.js';

0 commit comments

Comments
 (0)