Skip to content

Fix NaN poses from orientation JSON that omits its zero fields - #941

Open
East Agile Tracker (eastagiletracker) wants to merge 1 commit into
viamrobotics:mainfrom
eastagiletracker:agile-board/decode-partial-orientation-json
Open

Fix NaN poses from orientation JSON that omits its zero fields#941
East Agile Tracker (eastagiletracker) wants to merge 1 commit into
viamrobotics:mainfrom
eastagiletracker:agile-board/decode-partial-orientation-json

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes reading a spatialmath orientation that omits its zero-valued fields the way RDK does, instead of decoding it to a NaN pose. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/321. You can sign in with your GitHub ID to claim ownership of the project.

What this fixes

Go's unmarshal reads an absent scalar as zero, so {"type": "euler_angles", "value": {"yaw": 1.5707963267948966}} is a valid frame orientation to RDK — a hand-written machine config leaves the zero fields out. quatFromJson passes those absent fields straight into three.js: Euler.set(undefined, undefined, yaw) gives a NaN quaternion, so Pose.setFromFrame returns a pose whose orientation and theta are all NaN, and toMatrix4 returns an all-NaN rotation block — the frame and everything parented to it can no longer be placed in the scene. axis_angles takes the same input to a NaN lengthSq, fails its > 0 axis check, and silently falls back to identity while warning about a zero axis it does not have. The quaternion branch already defaults omitted fields to Go's zero, and the two orientation-vector branches get it for free from OrientationVector.set, so this was the last pair of encodings not following the rule your own spatial-math notes state: "protobuf materialises absent scalars as 0 and RDK's Normalize does the same substitution".

Reproduced on main at a934603:

new Pose().setFromFrame({
  translation: { x: 10, y: 0, z: 0 },
  orientation: { type: 'euler_angles', value: { yaw: Math.PI / 2 } },
})
// oX / oY / oZ / theta are all NaN — pose.isFinite() === false
// pose.toMatrix4().elements → NaN,NaN,NaN,0,NaN,NaN,NaN,0,NaN,NaN,NaN,0,0.01,0,0,1

poseFromJson(undefined, { type: 'axis_angles', value: { x: 1, th: Math.PI / 2 } })
// warns "[spatialJson] axis_angles has a zero axis — using identity"
// +Y stays at +Y instead of mapping to +Z

The change is four lines in orientationJson.ts: default the euler_angles and axis_angles components to 0, and type EulerJson / OvJson as partial records the way QuatJson already is, so the wire shape is what the types say it is. Values that carry every field decode exactly as before.

The tests cover all five encodings twice — the same 90° turn about +X spelled with its zero fields omitted, through poseFromJson and through Pose.setFromFrame (which also asserts a finite matrix) — plus an empty value for each encoding that resolves to identity. Reverting only orientationJson.ts takes 5 of them red (Tests 5 failed | 117 passed) while the ov_degrees, ov_radians and quaternion cases stay green, which is the split the diff predicts. On the full suite pnpm test goes from 682 passing on a934603 to 696 passing here with no new failures, and pnpm check, pnpm lint:prettier and pnpm lint:eslint are clean. Heads up that #912 also edits spatialJson.ts, but in geometryCenterInFrame rather than the decoder, so the two should not collide.

How this was managed

We imported this repository's issues and pull requests into a live agile board — 915 stories and 6 labels — and worked this fix on it as Partial spatialmath orientation JSON decodes to a NaN pose, on the board at https://eastagiletracker.com/projects/321.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

Go's unmarshal reads an absent scalar as zero, so RDK accepts a frame
orientation that leaves its zero-valued fields out. The euler_angles and
axis_angles branches passed those absent fields straight through: the
first produced a NaN quaternion, taking the frame's pose and matrix with
it, and the second failed its axis-length check and fell back to
identity while warning about a zero axis.

Default them to zero, as the quaternion branch already does, and cover
every encoding with a partial value.
@changeset-bot

changeset-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a5d9ff0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@viamrobotics/motion-tools Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants