Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions src/urdf/UrdfBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,30 @@
* @author Russell Toris - [email protected]
*/

import Vector3 from '../math/Vector3.js';
import * as UrdfTypes from './UrdfTypes.js';
import { Vector3 } from '../math/index.js';
import { UrdfAttrs, UrdfType, type UrdfDefaultOptions } from './UrdfTypes.js';
import type { Optional, Nullable } from '../types/interface-types.js';

/**
* A Box element in a URDF.
*/
export default class UrdfBox {
/** @type {Vector3 | null} */
dimension;
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
*/
constructor(options) {
this.type = UrdfTypes.URDF_BOX;
type: UrdfType;
dimension: Nullable<Vector3> = null;

constructor({ xml }: UrdfDefaultOptions) {
this.type = UrdfType.BOX;

// Parse the xml string
var xyz = options.xml.getAttribute('size')?.split(' ');
if (xyz) {
this.dimension = new Vector3({
x: parseFloat(xyz[0]),
y: parseFloat(xyz[1]),
z: parseFloat(xyz[2])
});
} else {
this.dimension = null;
const size: Optional<string[]> = xml.getAttribute(UrdfAttrs.Size)?.split(' ');
if (!size || size.length !== 3) {
return;
}

this.dimension = new Vector3({
x: parseFloat(size[0]),
y: parseFloat(size[1]),
z: parseFloat(size[2])
});
}
}
37 changes: 28 additions & 9 deletions src/urdf/UrdfColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,41 @@
* @author Russell Toris - [email protected]
*/

import { UrdfAttrs, type UrdfDefaultOptions } from './UrdfTypes.js';
import type { Optional } from '../types/interface-types.js';

/**
* A Color element in a URDF.
*/
export default class UrdfColor {

/**
* Color Red, [0, 1]
*/
r = 0.0;
/**
* Color Green, [0, 1]
*/
g = 0.0;
/**
* Color Blue, [0, 1]
*/
b = 0.0;
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
* Alpha/Opacity, [0, 1]
*/
constructor(options) {
a = 1.0;

constructor({ xml }: UrdfDefaultOptions) {
// Parse the xml string
var rgba = options.xml.getAttribute('rgba')?.split(' ');
if (rgba) {
this.r = parseFloat(rgba[0]);
this.g = parseFloat(rgba[1]);
this.b = parseFloat(rgba[2]);
this.a = parseFloat(rgba[3]);
const rgba: Optional<string[]> = xml.getAttribute(UrdfAttrs.Rgba)?.split(' ');
if (!rgba || rgba.length !== 4) {
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring JS into TS always uncovers extremely odd control flow like this.. early return from a constructor, lol 🤦🏻

}

this.r = parseFloat(rgba[0]);
this.g = parseFloat(rgba[1]);
this.b = parseFloat(rgba[2]);
this.a = parseFloat(rgba[3]);
}
}
22 changes: 11 additions & 11 deletions src/urdf/UrdfCylinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
* @author Russell Toris - [email protected]
*/

import * as UrdfTypes from './UrdfTypes.js';
import { type UrdfDefaultOptions, UrdfType, UrdfAttrs } from './UrdfTypes.js';

/**
* A Cylinder element in a URDF.
*/
export default class UrdfCylinder {
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
*/
constructor(options) {
this.type = UrdfTypes.URDF_CYLINDER;
// @ts-expect-error -- possibly null
this.length = parseFloat(options.xml.getAttribute('length'));
// @ts-expect-error -- possibly null
this.radius = parseFloat(options.xml.getAttribute('radius'));

type: UrdfType;
length: number;
radius: number;

constructor({ xml }: UrdfDefaultOptions) {
this.type = UrdfType.CYLINDER;

this.length = parseFloat(xml.getAttribute(UrdfAttrs.Length) ?? 'NaN');
this.radius = parseFloat(xml.getAttribute(UrdfAttrs.Radius) ?? 'NaN');
}
}
98 changes: 27 additions & 71 deletions src/urdf/UrdfJoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,49 @@
* @author David V. Lu!! - [email protected]
*/

import Pose from '../math/Pose.js';
import Vector3 from '../math/Vector3.js';
import Quaternion from '../math/Quaternion.js';
import { UrdfAttrs, type UrdfDefaultOptions } from './UrdfTypes.js';
import { Pose } from '../math/index.js';
import { parseUrdfOrigin } from './UrdfUtils.js';
import type { Nullable } from '../types/interface-types.js';

/**
* A Joint element in a URDF.
*/
export default class UrdfJoint {
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
*/
constructor(options) {
this.name = options.xml.getAttribute('name');
this.type = options.xml.getAttribute('type');

var parents = options.xml.getElementsByTagName('parent');
name: string;
type: Nullable<string>;
parent: Nullable<string> = null;
child: Nullable<string> = null;
minval = NaN;
maxval = NaN;
origin: Pose = new Pose();


constructor({xml}: UrdfDefaultOptions) {
this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';
this.type = xml.getAttribute(UrdfAttrs.Type);

const parents = xml.getElementsByTagName(UrdfAttrs.Parent);
if (parents.length > 0) {
this.parent = parents[0].getAttribute('link');
this.parent = parents[0].getAttribute(UrdfAttrs.Link);
}

var children = options.xml.getElementsByTagName('child');
const children = xml.getElementsByTagName(UrdfAttrs.Child);
if (children.length > 0) {
this.child = children[0].getAttribute('link');
this.child = children[0].getAttribute(UrdfAttrs.Link);
}

var limits = options.xml.getElementsByTagName('limit');
const limits = xml.getElementsByTagName(UrdfAttrs.Limit);
if (limits.length > 0) {
this.minval = parseFloat(limits[0].getAttribute('lower') || 'NaN');
this.maxval = parseFloat(limits[0].getAttribute('upper') || 'NaN');
this.minval = parseFloat(limits[0].getAttribute(UrdfAttrs.Lower) ?? 'NaN');
this.maxval = parseFloat(limits[0].getAttribute(UrdfAttrs.Upper) ?? 'NaN');
}

// Origin
var origins = options.xml.getElementsByTagName('origin');
if (origins.length === 0) {
// use the identity as the default
this.origin = new Pose();
} else {
// Check the XYZ
var xyzValue = origins[0].getAttribute('xyz');
var position = new Vector3();
if (xyzValue) {
var xyz = xyzValue.split(' ');
position = new Vector3({
x: parseFloat(xyz[0]),
y: parseFloat(xyz[1]),
z: parseFloat(xyz[2])
});
}

// Check the RPY
var rpyValue = origins[0].getAttribute('rpy');
var orientation = new Quaternion();
if (rpyValue) {
var rpy = rpyValue.split(' ');
// Convert from RPY
var roll = parseFloat(rpy[0]);
var pitch = parseFloat(rpy[1]);
var yaw = parseFloat(rpy[2]);
var phi = roll / 2.0;
var the = pitch / 2.0;
var psi = yaw / 2.0;
var x =
Math.sin(phi) * Math.cos(the) * Math.cos(psi) -
Math.cos(phi) * Math.sin(the) * Math.sin(psi);
var y =
Math.cos(phi) * Math.sin(the) * Math.cos(psi) +
Math.sin(phi) * Math.cos(the) * Math.sin(psi);
var z =
Math.cos(phi) * Math.cos(the) * Math.sin(psi) -
Math.sin(phi) * Math.sin(the) * Math.cos(psi);
var w =
Math.cos(phi) * Math.cos(the) * Math.cos(psi) +
Math.sin(phi) * Math.sin(the) * Math.sin(psi);

orientation = new Quaternion({
x: x,
y: y,
z: z,
w: w
});
orientation.normalize();
}
this.origin = new Pose({
position: position,
orientation: orientation
});
const origins = xml.getElementsByTagName(UrdfAttrs.Origin);
if (origins.length > 0) {
this.origin = parseUrdfOrigin(origins[0]);
}
}
}
20 changes: 10 additions & 10 deletions src/urdf/UrdfLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
*/

import UrdfVisual from './UrdfVisual.js';
import { UrdfAttrs, type UrdfDefaultOptions } from './UrdfTypes.js';

/**
* A Link element in a URDF.
*/
export default class UrdfLink {
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
*/
constructor(options) {
this.name = options.xml.getAttribute('name');
this.visuals = [];
var visuals = options.xml.getElementsByTagName('visual');

for (var i = 0; i < visuals.length; i++) {
name: string;
visuals: UrdfVisual[] = [];

constructor({ xml }: UrdfDefaultOptions) {
this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';
const visuals = xml.getElementsByTagName(UrdfAttrs.Visuals);

for (const visual of visuals) {
this.visuals.push(
new UrdfVisual({
xml: visuals[i]
xml: visual
})
);
}
Expand Down
31 changes: 16 additions & 15 deletions src/urdf/UrdfMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,43 @@
*/

import UrdfColor from './UrdfColor.js';
import { UrdfAttrs, type UrdfDefaultOptions } from './UrdfTypes.js';
import type { Nullable } from '../types/interface-types.js';

/**
* A Material element in a URDF.
*/
export default class UrdfMaterial {
/** @type {string | null} */
textureFilename = null;
/** @type {UrdfColor | null} */
color = null;
/**
* @param {Object} options
* @param {Element} options.xml - The XML element to parse.
*/
constructor(options) {

this.name = options.xml.getAttribute('name');

name: string;
textureFilename: Nullable<string> = null;
color: Nullable<UrdfColor> = null;

constructor({ xml }: UrdfDefaultOptions) {

this.name = xml.getAttribute(UrdfAttrs.Name) ?? 'unknown_name';

// Texture
var textures = options.xml.getElementsByTagName('texture');
const textures = xml.getElementsByTagName(UrdfAttrs.Texture);
if (textures.length > 0) {
this.textureFilename = textures[0].getAttribute('filename');
this.textureFilename = textures[0].getAttribute(UrdfAttrs.Filename);
}

// Color
var colors = options.xml.getElementsByTagName('color');
const colors = xml.getElementsByTagName(UrdfAttrs.Color);
if (colors.length > 0) {
// Parse the RBGA string
this.color = new UrdfColor({
xml: colors[0]
});
}
}

isLink() {
return this.color === null && this.textureFilename === null;
}
assign(obj) {

assign(obj: UrdfMaterial): this & UrdfMaterial {
return Object.assign(this, obj);
}
}
Loading