Skip to content

Commit 5b8fb11

Browse files
committed
Convert URDF definitions to typescript
1 parent a653af3 commit 5b8fb11

14 files changed

+504
-414
lines changed

src/urdf/UrdfBox.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,29 @@
44
* @author Russell Toris - [email protected]
55
*/
66

7-
import Vector3 from '../math/Vector3.js';
8-
import * as UrdfTypes from './UrdfTypes.js';
7+
import { Vector3 } from '../math/index.js';
8+
import { UrdfAttrs, UrdfDefaultOptions, UrdfType } from './UrdfTypes.js';
99

1010
/**
1111
* A Box element in a URDF.
1212
*/
1313
export default class UrdfBox {
14-
/** @type {Vector3 | null} */
15-
dimension;
16-
/**
17-
* @param {Object} options
18-
* @param {Element} options.xml - The XML element to parse.
19-
*/
20-
constructor(options) {
21-
this.type = UrdfTypes.URDF_BOX;
14+
type: UrdfType;
15+
dimension: Vector3 | null = null;
16+
17+
constructor({xml}: UrdfDefaultOptions) {
18+
this.type = UrdfType.BOX;
2219

2320
// Parse the xml string
24-
var xyz = options.xml.getAttribute('size')?.split(' ');
25-
if (xyz) {
26-
this.dimension = new Vector3({
27-
x: parseFloat(xyz[0]),
28-
y: parseFloat(xyz[1]),
29-
z: parseFloat(xyz[2])
30-
});
31-
} else {
32-
this.dimension = null;
21+
const size: string[] | undefined = xml.getAttribute(UrdfAttrs.Size)?.split(' ');
22+
if (!size || size.length !== 3) {
23+
return;
3324
}
25+
26+
this.dimension = new Vector3({
27+
x: parseFloat(size[0]),
28+
y: parseFloat(size[1]),
29+
z: parseFloat(size[2])
30+
});
3431
}
3532
}

src/urdf/UrdfColor.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,40 @@
44
* @author Russell Toris - [email protected]
55
*/
66

7+
import { UrdfAttrs, UrdfDefaultOptions } from './UrdfTypes.js';
8+
79
/**
810
* A Color element in a URDF.
911
*/
1012
export default class UrdfColor {
13+
14+
/**
15+
* Color Red, [0, 1]
16+
*/
17+
r: number = 0.0;
18+
/**
19+
* Color Green, [0, 1]
20+
*/
21+
g: number = 0.0;
22+
/**
23+
* Color Blue, [0, 1]
24+
*/
25+
b: number = 0.0;
1126
/**
12-
* @param {Object} options
13-
* @param {Element} options.xml - The XML element to parse.
27+
* Alpha/Opacity, [0, 1]
1428
*/
15-
constructor(options) {
29+
a: number = 1.0;
30+
31+
constructor({xml}: UrdfDefaultOptions) {
1632
// Parse the xml string
17-
var rgba = options.xml.getAttribute('rgba')?.split(' ');
18-
if (rgba) {
19-
this.r = parseFloat(rgba[0]);
20-
this.g = parseFloat(rgba[1]);
21-
this.b = parseFloat(rgba[2]);
22-
this.a = parseFloat(rgba[3]);
33+
const rgba: string[] | undefined = xml.getAttribute(UrdfAttrs.Rgba)?.split(' ');
34+
if (!rgba || rgba.length !== 4) {
35+
return;
2336
}
37+
38+
this.r = parseFloat(rgba[0]);
39+
this.g = parseFloat(rgba[1]);
40+
this.b = parseFloat(rgba[2]);
41+
this.a = parseFloat(rgba[3]);
2442
}
2543
}

src/urdf/UrdfCylinder.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44
* @author Russell Toris - [email protected]
55
*/
66

7-
import * as UrdfTypes from './UrdfTypes.js';
7+
import { UrdfDefaultOptions, UrdfType, UrdfAttrs } from './UrdfTypes.js';
88

99
/**
1010
* A Cylinder element in a URDF.
1111
*/
1212
export default class UrdfCylinder {
13-
/**
14-
* @param {Object} options
15-
* @param {Element} options.xml - The XML element to parse.
16-
*/
17-
constructor(options) {
18-
this.type = UrdfTypes.URDF_CYLINDER;
19-
// @ts-expect-error -- possibly null
20-
this.length = parseFloat(options.xml.getAttribute('length'));
21-
// @ts-expect-error -- possibly null
22-
this.radius = parseFloat(options.xml.getAttribute('radius'));
13+
14+
type: UrdfType;
15+
length: number;
16+
radius: number;
17+
18+
constructor({xml}: UrdfDefaultOptions) {
19+
this.type = UrdfType.CYLINDER;
20+
21+
this.length = parseFloat(xml.getAttribute(UrdfAttrs.Length) ?? 'NaN');
22+
this.radius = parseFloat(xml.getAttribute(UrdfAttrs.Radius) ?? 'NaN');
2323
}
2424
}

src/urdf/UrdfJoint.ts

Lines changed: 26 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,93 +3,48 @@
33
* @author David V. Lu!! - [email protected]
44
*/
55

6-
import Pose from '../math/Pose.js';
7-
import Vector3 from '../math/Vector3.js';
8-
import Quaternion from '../math/Quaternion.js';
6+
import { UrdfAttrs, UrdfDefaultOptions } from './UrdfTypes.js';
7+
import { Pose } from '../math/index.js';
8+
import { parseUrdfOrigin } from './UrdfUtils.js';
99

1010
/**
1111
* A Joint element in a URDF.
1212
*/
1313
export default class UrdfJoint {
14-
/**
15-
* @param {Object} options
16-
* @param {Element} options.xml - The XML element to parse.
17-
*/
18-
constructor(options) {
19-
this.name = options.xml.getAttribute('name');
20-
this.type = options.xml.getAttribute('type');
2114

22-
var parents = options.xml.getElementsByTagName('parent');
15+
name: string;
16+
type: string | null;
17+
parent: string | null = null;
18+
child: string | null = null;
19+
minval: number = NaN;
20+
maxval: number = NaN;
21+
origin: Pose = new Pose();
22+
23+
24+
constructor({xml}: UrdfDefaultOptions) {
25+
this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';
26+
this.type = xml.getAttribute(UrdfAttrs.Type);
27+
28+
const parents = xml.getElementsByTagName(UrdfAttrs.Parent);
2329
if (parents.length > 0) {
24-
this.parent = parents[0].getAttribute('link');
30+
this.parent = parents[0].getAttribute(UrdfAttrs.Link);
2531
}
2632

27-
var children = options.xml.getElementsByTagName('child');
33+
const children = xml.getElementsByTagName(UrdfAttrs.Child);
2834
if (children.length > 0) {
29-
this.child = children[0].getAttribute('link');
35+
this.child = children[0].getAttribute(UrdfAttrs.Link);
3036
}
3137

32-
var limits = options.xml.getElementsByTagName('limit');
38+
const limits = xml.getElementsByTagName(UrdfAttrs.Limit);
3339
if (limits.length > 0) {
34-
this.minval = parseFloat(limits[0].getAttribute('lower') || 'NaN');
35-
this.maxval = parseFloat(limits[0].getAttribute('upper') || 'NaN');
40+
this.minval = parseFloat(limits[0].getAttribute(UrdfAttrs.Lower) ?? 'NaN');
41+
this.maxval = parseFloat(limits[0].getAttribute(UrdfAttrs.Upper) ?? 'NaN');
3642
}
3743

3844
// Origin
39-
var origins = options.xml.getElementsByTagName('origin');
40-
if (origins.length === 0) {
41-
// use the identity as the default
42-
this.origin = new Pose();
43-
} else {
44-
// Check the XYZ
45-
var xyzValue = origins[0].getAttribute('xyz');
46-
var position = new Vector3();
47-
if (xyzValue) {
48-
var xyz = xyzValue.split(' ');
49-
position = new Vector3({
50-
x: parseFloat(xyz[0]),
51-
y: parseFloat(xyz[1]),
52-
z: parseFloat(xyz[2])
53-
});
54-
}
55-
56-
// Check the RPY
57-
var rpyValue = origins[0].getAttribute('rpy');
58-
var orientation = new Quaternion();
59-
if (rpyValue) {
60-
var rpy = rpyValue.split(' ');
61-
// Convert from RPY
62-
var roll = parseFloat(rpy[0]);
63-
var pitch = parseFloat(rpy[1]);
64-
var yaw = parseFloat(rpy[2]);
65-
var phi = roll / 2.0;
66-
var the = pitch / 2.0;
67-
var psi = yaw / 2.0;
68-
var x =
69-
Math.sin(phi) * Math.cos(the) * Math.cos(psi) -
70-
Math.cos(phi) * Math.sin(the) * Math.sin(psi);
71-
var y =
72-
Math.cos(phi) * Math.sin(the) * Math.cos(psi) +
73-
Math.sin(phi) * Math.cos(the) * Math.sin(psi);
74-
var z =
75-
Math.cos(phi) * Math.cos(the) * Math.sin(psi) -
76-
Math.sin(phi) * Math.sin(the) * Math.cos(psi);
77-
var w =
78-
Math.cos(phi) * Math.cos(the) * Math.cos(psi) +
79-
Math.sin(phi) * Math.sin(the) * Math.sin(psi);
80-
81-
orientation = new Quaternion({
82-
x: x,
83-
y: y,
84-
z: z,
85-
w: w
86-
});
87-
orientation.normalize();
88-
}
89-
this.origin = new Pose({
90-
position: position,
91-
orientation: orientation
92-
});
45+
const origins = xml.getElementsByTagName(UrdfAttrs.Origin);
46+
if (origins.length > 0) {
47+
this.origin = parseUrdfOrigin(origins[0]);
9348
}
9449
}
9550
}

src/urdf/UrdfLink.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
*/
66

77
import UrdfVisual from './UrdfVisual.js';
8+
import { UrdfAttrs, UrdfDefaultOptions } from './UrdfTypes.js';
89

910
/**
1011
* A Link element in a URDF.
1112
*/
1213
export default class UrdfLink {
13-
/**
14-
* @param {Object} options
15-
* @param {Element} options.xml - The XML element to parse.
16-
*/
17-
constructor(options) {
18-
this.name = options.xml.getAttribute('name');
19-
this.visuals = [];
20-
var visuals = options.xml.getElementsByTagName('visual');
2114

22-
for (var i = 0; i < visuals.length; i++) {
15+
name: string;
16+
visuals: UrdfVisual[] = [];
17+
18+
constructor({xml}: UrdfDefaultOptions) {
19+
this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';
20+
const visuals = xml.getElementsByTagName(UrdfAttrs.Visuals);
21+
22+
for (let i = 0; i < visuals.length; i++) {
2323
this.visuals.push(
2424
new UrdfVisual({
2525
xml: visuals[i]

src/urdf/UrdfMaterial.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,42 @@
55
*/
66

77
import UrdfColor from './UrdfColor.js';
8+
import { UrdfAttrs, UrdfDefaultOptions } from './UrdfTypes.js';
89

910
/**
1011
* A Material element in a URDF.
1112
*/
1213
export default class UrdfMaterial {
13-
/** @type {string | null} */
14-
textureFilename = null;
15-
/** @type {UrdfColor | null} */
16-
color = null;
17-
/**
18-
* @param {Object} options
19-
* @param {Element} options.xml - The XML element to parse.
20-
*/
21-
constructor(options) {
22-
23-
this.name = options.xml.getAttribute('name');
14+
15+
name: string;
16+
textureFilename: string | null = null;
17+
color: UrdfColor | null = null;
18+
19+
constructor({xml}: UrdfDefaultOptions) {
20+
21+
this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';
2422

2523
// Texture
26-
var textures = options.xml.getElementsByTagName('texture');
24+
const textures = xml.getElementsByTagName(UrdfAttrs.Texture);
2725
if (textures.length > 0) {
28-
this.textureFilename = textures[0].getAttribute('filename');
26+
this.textureFilename = textures[0].getAttribute(UrdfAttrs.Filename);
2927
}
3028

3129
// Color
32-
var colors = options.xml.getElementsByTagName('color');
30+
const colors = xml.getElementsByTagName(UrdfAttrs.Color);
3331
if (colors.length > 0) {
3432
// Parse the RBGA string
3533
this.color = new UrdfColor({
3634
xml: colors[0]
3735
});
3836
}
3937
}
38+
4039
isLink() {
4140
return this.color === null && this.textureFilename === null;
4241
}
43-
assign(obj) {
42+
43+
assign(obj: UrdfMaterial): this & UrdfMaterial {
4444
return Object.assign(this, obj);
4545
}
4646
}

src/urdf/UrdfMesh.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,35 @@
44
* @author Russell Toris - [email protected]
55
*/
66

7-
import Vector3 from '../math/Vector3.js';
8-
import * as UrdfTypes from './UrdfTypes.js';
7+
import { Vector3 } from '../math/index.js';
8+
import { UrdfAttrs, UrdfDefaultOptions, UrdfType } from './UrdfTypes.js';
99

1010
/**
1111
* A Mesh element in a URDF.
1212
*/
1313
export default class UrdfMesh {
14-
/** @type {Vector3 | null} */
15-
scale = null;
14+
type: UrdfType;
15+
scale: Vector3 | null = null;
16+
filename: string | null;
17+
1618
/**
1719
* @param {Object} options
1820
* @param {Element} options.xml - The XML element to parse.
1921
*/
20-
constructor(options) {
21-
this.type = UrdfTypes.URDF_MESH;
22-
this.filename = options.xml.getAttribute('filename');
22+
constructor({xml}: UrdfDefaultOptions) {
23+
this.type = UrdfType.MESH;
24+
this.filename = xml.getAttribute('filename');
2325

2426
// Check for a scale
25-
var scale = options.xml.getAttribute('scale');
26-
if (scale) {
27-
// Get the XYZ
28-
var xyz = scale.split(' ');
29-
this.scale = new Vector3({
30-
x: parseFloat(xyz[0]),
31-
y: parseFloat(xyz[1]),
32-
z: parseFloat(xyz[2])
33-
});
27+
const scale: string[] | undefined = xml.getAttribute(UrdfAttrs.Scale)?.split(' ');
28+
if (!scale || scale.length !== 3) {
29+
return;
3430
}
31+
32+
this.scale = new Vector3({
33+
x: parseFloat(scale[0]),
34+
y: parseFloat(scale[1]),
35+
z: parseFloat(scale[2])
36+
});
3537
}
3638
}

0 commit comments

Comments
 (0)