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
11 changes: 10 additions & 1 deletion src/core/Ros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,11 @@ export default class Ros extends EventEmitter<
const arrayLen = theType.fieldarraylen[i];
const fieldName = theType.fieldnames[i];
const fieldType = theType.fieldtypes[i];
if (fieldName === undefined || fieldType === undefined) {
throw new Error(
"Received mismatched type definition vector lengths!",
);
}
if (!fieldType.includes("/")) {
// check the fieldType includes '/' or not
if (arrayLen === -1) {
Expand Down Expand Up @@ -677,7 +682,11 @@ export default class Ros extends EventEmitter<
return typeDefDict;
};

return decodeTypeDefsRec(defs[0], defs);
if (defs[0]) {
return decodeTypeDefsRec(defs[0], defs);
} else {
return {};
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/urdf/UrdfBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class UrdfBox {
const size: Optional<string[]> = xml
.getAttribute(UrdfAttrs.Size)
?.split(" ");
if (size?.length !== 3) {
if (!(size?.[0] && size[1] && size[2])) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/urdf/UrdfColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class UrdfColor {
const rgba: Optional<string[]> = xml
.getAttribute(UrdfAttrs.Rgba)
?.split(" ");
if (rgba?.length !== 4) {
if (!(rgba?.[0] && rgba[1] && rgba[2] && rgba[3])) {
return;
}

Expand Down
10 changes: 5 additions & 5 deletions src/urdf/UrdfJoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ export default class UrdfJoint {
this.type = xml.getAttribute(UrdfAttrs.Type);

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

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

const limits = xml.getElementsByTagName(UrdfAttrs.Limit);
if (limits.length > 0) {
if (limits[0]) {
this.minval = parseFloat(
limits[0].getAttribute(UrdfAttrs.Lower) ?? "NaN",
);
Expand All @@ -52,12 +52,12 @@ export default class UrdfJoint {

// Origin
const origins = xml.getElementsByTagName(UrdfAttrs.Origin);
if (origins.length > 0) {
if (origins[0]) {
this.origin = parseUrdfOrigin(origins[0]);
}

const axis = xml.getElementsByTagName(UrdfAttrs.Axis);
if (axis.length > 0) {
if (axis[0]) {
const xyzValue = axis[0].getAttribute(UrdfAttrs.Xyz)?.split(" ");
if (!xyzValue || xyzValue.length !== 3) {
throw new Error(
Expand Down
4 changes: 2 additions & 2 deletions src/urdf/UrdfMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export default class UrdfMaterial {

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

// Color
const colors = xml.getElementsByTagName(UrdfAttrs.Color);
if (colors.length > 0) {
if (colors[0]) {
// Parse the RBGA string
this.color = new UrdfColor({
xml: colors[0],
Expand Down
2 changes: 1 addition & 1 deletion src/urdf/UrdfMesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class UrdfMesh {
const scale: Optional<string[]> = xml
.getAttribute(UrdfAttrs.Scale)
?.split(" ");
if (scale?.length !== 3) {
if (!(scale?.[0] && scale[1] && scale[2])) {
return;
}

Expand Down
10 changes: 6 additions & 4 deletions src/urdf/UrdfModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ export default class UrdfModel {
break;
}

if (this.materials[material.name].isLink()) {
this.materials[material.name].assign(material);
const existingMaterial = this.materials[material.name];
if (existingMaterial?.isLink()) {
existingMaterial.assign(material);
} else {
console.warn(`Material ${material.name} is not unique.`);
}
Expand All @@ -95,8 +96,9 @@ export default class UrdfModel {
continue;
}

if (Object.hasOwn(this.materials, mat.name)) {
item.material = this.materials[mat.name];
const material = this.materials[mat.name];
if (material) {
item.material = material;
} else {
this.materials[mat.name] = mat;
}
Expand Down
4 changes: 2 additions & 2 deletions src/urdf/UrdfUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function parseUrdfOrigin(originElement: Element): Pose {
.getAttribute(UrdfAttrs.Xyz)
?.split(" ");
let position: Vector3 = new Vector3();
if (xyz?.length === 3) {
if (xyz?.[0] && xyz[1] && xyz[2]) {
position = new Vector3({
x: parseFloat(xyz[0]),
y: parseFloat(xyz[1]),
Expand All @@ -22,7 +22,7 @@ export function parseUrdfOrigin(originElement: Element): Pose {
// Check the RPY
const rpy = originElement.getAttribute(UrdfAttrs.Rpy)?.split(" ");
let orientation = new Quaternion();
if (rpy?.length === 3) {
if (rpy?.[0] && rpy[1] && rpy[2]) {
// Convert from RPY
const roll = parseFloat(rpy[0]);
const pitch = parseFloat(rpy[1]);
Expand Down
6 changes: 3 additions & 3 deletions src/urdf/UrdfVisual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,19 @@ export default class UrdfVisual {

// Origin
const origins = xml.getElementsByTagName(UrdfAttrs.Origin);
if (origins.length > 0) {
if (origins[0]) {
this.origin = parseUrdfOrigin(origins[0]);
}

// Geometry
const geoms = xml.getElementsByTagName(UrdfAttrs.Geometry);
if (geoms.length > 0) {
if (geoms[0]) {
this.geometry = parseUrdfGeometry(geoms[0]);
}

// Material
const materials = xml.getElementsByTagName(UrdfAttrs.Material);
if (materials.length > 0) {
if (materials[0]) {
this.material = new UrdfMaterial({
xml: materials[0],
});
Expand Down
12 changes: 9 additions & 3 deletions src/util/cborTypedArrayTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ function decodeUint64LE(bytes: Uint8Array) {
const si = i * 2;
const lo = uint32View[si];
const hi = uint32View[si + 1];
if (lo === undefined || hi === undefined) {
throw new Error("Invalid byte array");
}
arr[i] = lo + UPPER32 * hi;
}

Expand All @@ -55,6 +58,9 @@ function decodeInt64LE(bytes: Uint8Array) {
const si = i * 2;
const lo = uint32View[si];
const hi = int32View[si + 1];
if (lo === undefined || hi === undefined) {
throw new Error("Invalid byte array");
}
arr[i] = lo + UPPER32 * hi;
}

Expand Down Expand Up @@ -120,12 +126,12 @@ export default function cborTypedArrayTagger(
data: Uint8Array<ArrayBuffer>,
tag: number,
) {
if (tag in nativeArrayTypes) {
const arrayType = nativeArrayTypes[tag];
const arrayType = nativeArrayTypes[tag];
if (arrayType) {
return decodeNativeArray(data, arrayType);
}
if (tag in conversionArrayTypes) {
return conversionArrayTypes[tag](data);
return conversionArrayTypes[tag]?.(data);
}
return data;
}
4 changes: 2 additions & 2 deletions test/examples/params.example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe("Param setting", function () {
ros.getParams(callback);
await vi.waitFor(() => {
expect(callback).toHaveBeenCalledOnce();
expect(callback.mock.calls[0][0]).to.include(PARAM_NAME);
expect(callback.mock.calls[0]?.[0]).to.include(PARAM_NAME);
});
},
);
Expand All @@ -74,7 +74,7 @@ describe("Param setting", function () {
const getParamsCallback = vi.fn();
ros.getParams(getParamsCallback);
await vi.waitFor(() =>
expect(getParamsCallback.mock.calls[0][0]).to.not.include(PARAM_NAME),
expect(getParamsCallback.mock.calls[0]?.[0]).to.not.include(PARAM_NAME),
);
},
);
Expand Down
54 changes: 26 additions & 28 deletions test/urdf.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,70 +88,68 @@ describe("URDF", function () {
});

// Check all the visual elements
expect(urdfModel.links["link1"].visuals.length).to.equal(1);
expect(urdfModel.links["link1"]?.visuals.length).to.equal(1);
if (
!(urdfModel.links["link1"].visuals[0]?.geometry instanceof UrdfSphere)
!(urdfModel.links["link1"]?.visuals[0]?.geometry instanceof UrdfSphere)
) {
throw new Error("Expected geometry to be an instance of UrdfSphere");
}
expect(urdfModel.links["link1"].visuals[0]?.geometry?.radius).to.equal(
1.0,
);
if (!(urdfModel.links["link2"].visuals[0]?.geometry instanceof UrdfBox)) {
expect(urdfModel.links["link1"].visuals[0].geometry.radius).to.equal(1.0);
if (
!(urdfModel.links["link2"]?.visuals[0]?.geometry instanceof UrdfBox)
) {
throw new Error("Expected geometry to be an instance of UrdfBox");
}
expect(
urdfModel.links["link2"].visuals[0]?.geometry?.dimension?.x,
urdfModel.links["link2"].visuals[0].geometry.dimension?.x,
).to.equal(0.5);
expect(
urdfModel.links["link2"].visuals[0]?.geometry?.dimension?.y,
urdfModel.links["link2"].visuals[0].geometry.dimension?.y,
).to.equal(0.5);
expect(
urdfModel.links["link2"].visuals[0]?.geometry?.dimension?.z,
urdfModel.links["link2"].visuals[0].geometry.dimension?.z,
).to.equal(0.5);
if (
!(urdfModel.links["link3"].visuals[0]?.geometry instanceof UrdfCylinder)
!(
urdfModel.links["link3"]?.visuals[0]?.geometry instanceof UrdfCylinder
)
) {
throw new Error("Expected geometry to be an instance of UrdfCylinder");
}
expect(urdfModel.links["link3"].visuals[0]?.geometry?.length).to.equal(
2.0,
);
expect(urdfModel.links["link3"].visuals[0]?.geometry?.radius).to.equal(
0.2,
);
expect(urdfModel.links["link3"].visuals[0].geometry.length).to.equal(2.0);
expect(urdfModel.links["link3"].visuals[0].geometry.radius).to.equal(0.2);

expect(urdfModel.links["link4"].visuals.length).to.equal(1);
expect(urdfModel.links["link4"].visuals[0]?.material?.name).to.equal(
expect(urdfModel.links["link4"]?.visuals.length).to.equal(1);
expect(urdfModel.links["link4"]?.visuals[0]?.material?.name).to.equal(
"red",
);
expect(urdfModel.links["link4"].visuals[0]?.material?.color?.r).to.equal(
expect(urdfModel.links["link4"]?.visuals[0]?.material?.color?.r).to.equal(
1.0,
);
expect(urdfModel.links["link4"].visuals[0]?.material?.color?.g).to.equal(
expect(urdfModel.links["link4"]?.visuals[0]?.material?.color?.g).to.equal(
0,
);
expect(urdfModel.links["link4"].visuals[0]?.material?.color?.b).to.equal(
expect(urdfModel.links["link4"]?.visuals[0]?.material?.color?.b).to.equal(
0,
);
expect(urdfModel.links["link4"].visuals[0]?.material?.color?.a).to.equal(
expect(urdfModel.links["link4"]?.visuals[0]?.material?.color?.a).to.equal(
1.0,
);

expect(urdfModel.links["link5"].visuals.length).to.equal(2);
expect(urdfModel.links["link5"].visuals[0]?.material?.name).to.equal(
expect(urdfModel.links["link5"]?.visuals.length).to.equal(2);
expect(urdfModel.links["link5"]?.visuals[0]?.material?.name).to.equal(
"blue",
);
expect(urdfModel.links["link5"].visuals[0]?.material?.color?.r).to.equal(
expect(urdfModel.links["link5"]?.visuals[0]?.material?.color?.r).to.equal(
0.0,
);
expect(urdfModel.links["link5"].visuals[0]?.material?.color?.g).to.equal(
expect(urdfModel.links["link5"]?.visuals[0]?.material?.color?.g).to.equal(
0.0,
);
expect(urdfModel.links["link5"].visuals[0]?.material?.color?.b).to.equal(
expect(urdfModel.links["link5"]?.visuals[0]?.material?.color?.b).to.equal(
1.0,
);
expect(urdfModel.links["link5"].visuals[0]?.material?.color?.a).to.equal(
expect(urdfModel.links["link5"]?.visuals[0]?.material?.color?.a).to.equal(
1.0,
);
});
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
"strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */,
"strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */,
"noImplicitOverride": true /* Ensure overriding members in derived classes are marked with an override modifier. */,
"noUncheckedIndexedAccess": true /* Add `undefined` to a type when accessed using an index. */,

/* Rules to be enabled */
"exactOptionalPropertyTypes": false /* Differentiate between undefined and not present when type checking */,
"noImplicitAny": false /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
"noUncheckedIndexedAccess": false /* Add `undefined` to a type when accessed using an index. */,

"types": ["@types/node"]
},
Expand Down