@viamrobotics/motion-tools 0.15.1 → 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/WorldObject.svelte.d.ts +3 -1
- package/dist/WorldObject.svelte.js +24 -5
- package/dist/components/StaticGeometries.svelte +3 -1
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.d.ts +2 -0
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.js +35 -0
- package/dist/hooks/useFrames.svelte.js +16 -5
- package/dist/hooks/usePose.svelte.js +3 -1
- package/dist/hooks/useStaticGeometries.svelte.js +14 -4
- package/dist/three/BatchedArrow.d.ts +0 -1
- package/dist/three/BatchedArrow.js +0 -1
- package/dist/transform.d.ts +1 -1
- package/dist/transform.js +8 -8
- package/package.json +2 -2
|
@@ -56,7 +56,9 @@ export declare class WorldObject<T extends Geometries = Geometries> {
|
|
|
56
56
|
geometry?: T;
|
|
57
57
|
metadata: Metadata;
|
|
58
58
|
localEditedPose: PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Pose>;
|
|
59
|
-
constructor(name
|
|
59
|
+
constructor(name?: string, pose?: Pose, parent?: string, geometry?: T, metadata?: Metadata);
|
|
60
|
+
toJSON(): Omit<WorldObject, 'toJSON' | 'fromJSON' | 'metadata'>;
|
|
61
|
+
fromJSON(json: WorldObject): this;
|
|
60
62
|
}
|
|
61
63
|
export declare const parseMetadata: (fields?: PlainMessage<Struct>["fields"]) => Metadata;
|
|
62
64
|
export declare const fromTransform: (transform: TransformWithUUID) => WorldObject<PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Geometry>>;
|
|
@@ -22,15 +22,14 @@ export const isMetadataKey = (key) => {
|
|
|
22
22
|
return METADATA_KEYS.includes(key);
|
|
23
23
|
};
|
|
24
24
|
export class WorldObject {
|
|
25
|
-
uuid;
|
|
26
|
-
name;
|
|
25
|
+
uuid = MathUtils.generateUUID();
|
|
26
|
+
name = '';
|
|
27
27
|
referenceFrame = $state.raw();
|
|
28
28
|
pose = $state.raw(createPose());
|
|
29
|
-
geometry;
|
|
29
|
+
geometry = $state();
|
|
30
30
|
metadata = $state({});
|
|
31
31
|
localEditedPose = $state.raw(createPose());
|
|
32
|
-
constructor(name, pose, parent = 'world', geometry, metadata) {
|
|
33
|
-
this.uuid = MathUtils.generateUUID();
|
|
32
|
+
constructor(name = '', pose, parent = 'world', geometry, metadata) {
|
|
34
33
|
this.name = name;
|
|
35
34
|
this.referenceFrame = parent;
|
|
36
35
|
this.geometry = geometry;
|
|
@@ -42,6 +41,26 @@ export class WorldObject {
|
|
|
42
41
|
this.localEditedPose = { ...pose };
|
|
43
42
|
}
|
|
44
43
|
}
|
|
44
|
+
toJSON() {
|
|
45
|
+
return {
|
|
46
|
+
uuid: this.uuid,
|
|
47
|
+
name: this.name,
|
|
48
|
+
referenceFrame: $state.snapshot(this.referenceFrame),
|
|
49
|
+
pose: $state.snapshot(this.pose),
|
|
50
|
+
geometry: $state.snapshot(this.geometry),
|
|
51
|
+
localEditedPose: $state.snapshot(this.localEditedPose),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
fromJSON(json) {
|
|
55
|
+
this.uuid = json.uuid;
|
|
56
|
+
this.name = json.name;
|
|
57
|
+
this.referenceFrame = json.referenceFrame;
|
|
58
|
+
this.pose = json.pose;
|
|
59
|
+
this.geometry = json.geometry;
|
|
60
|
+
this.localEditedPose = json.localEditedPose;
|
|
61
|
+
this.metadata = {};
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
45
64
|
}
|
|
46
65
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
66
|
const unwrapValue = (value) => {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
metadata={object.metadata}
|
|
41
41
|
>
|
|
42
42
|
{#snippet children({ ref })}
|
|
43
|
-
{#if selected.current ===
|
|
43
|
+
{#if selected.current === object.uuid}
|
|
44
44
|
{#key mode}
|
|
45
45
|
<TransformControls
|
|
46
46
|
object={ref}
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
scaleToDimensions(ref.scale, object.geometry.geometryType)
|
|
64
64
|
ref.scale.setScalar(1)
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
object.pose = { ...object.pose }
|
|
66
68
|
}}
|
|
67
69
|
/>
|
|
68
70
|
{/key}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { WorldObject } from '../../../WorldObject.svelte';
|
|
2
|
+
export const createWorldObjectFixture = () => {
|
|
3
|
+
const object = new WorldObject();
|
|
4
|
+
object.name = 'Test Object';
|
|
5
|
+
object.uuid = '1234-5678';
|
|
6
|
+
object.referenceFrame = 'parent_frame';
|
|
7
|
+
object.pose = {
|
|
8
|
+
x: 10,
|
|
9
|
+
y: 20,
|
|
10
|
+
z: 30,
|
|
11
|
+
oX: 0.1,
|
|
12
|
+
oY: 0.2,
|
|
13
|
+
oZ: 0.3,
|
|
14
|
+
theta: 0.4,
|
|
15
|
+
};
|
|
16
|
+
object.geometry = {
|
|
17
|
+
label: 'my geometry',
|
|
18
|
+
geometryType: {
|
|
19
|
+
case: 'box',
|
|
20
|
+
value: {
|
|
21
|
+
dimsMm: { x: 10, y: 20, z: 30 },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
object.localEditedPose = {
|
|
26
|
+
x: 10,
|
|
27
|
+
y: 20,
|
|
28
|
+
z: 30,
|
|
29
|
+
oX: 0.1,
|
|
30
|
+
oY: 0.2,
|
|
31
|
+
oZ: 0.3,
|
|
32
|
+
theta: 0.4,
|
|
33
|
+
};
|
|
34
|
+
return object;
|
|
35
|
+
};
|
|
@@ -6,9 +6,9 @@ import { resourceNameToColor } from '../color';
|
|
|
6
6
|
import { usePartConfig } from './usePartConfig.svelte';
|
|
7
7
|
import { useEnvironment } from './useEnvironment.svelte';
|
|
8
8
|
import { createPoseFromFrame } from '../transform';
|
|
9
|
-
import { usePersistentUUIDs } from './usePersistentUUIDs.svelte';
|
|
10
9
|
import { createGeometryFromFrame } from '../geometry';
|
|
11
10
|
import { useResourceByName } from './useResourceByName.svelte';
|
|
11
|
+
import { usePersistentUUIDs } from './usePersistentUUIDs.svelte';
|
|
12
12
|
const key = Symbol('frames-context');
|
|
13
13
|
export const provideFrames = (partID) => {
|
|
14
14
|
const resourceByName = useResourceByName();
|
|
@@ -47,12 +47,14 @@ export const provideFrames = (partID) => {
|
|
|
47
47
|
}
|
|
48
48
|
return objects;
|
|
49
49
|
});
|
|
50
|
-
const configFrames = $derived.by(() => {
|
|
50
|
+
const [configFrames, configUnsetFrames] = $derived.by(() => {
|
|
51
51
|
const components = partConfig.localPartConfig.toJson().components;
|
|
52
52
|
const objects = [];
|
|
53
|
+
const unsetObjects = [];
|
|
53
54
|
// deal with part defined frame config
|
|
54
55
|
for (const component of components ?? []) {
|
|
55
56
|
if (!component.frame) {
|
|
57
|
+
unsetObjects.push(component.name);
|
|
56
58
|
continue;
|
|
57
59
|
}
|
|
58
60
|
const pose = createPoseFromFrame(component.frame);
|
|
@@ -60,7 +62,7 @@ export const provideFrames = (partID) => {
|
|
|
60
62
|
const worldObject = new WorldObject(component.name, pose, component.frame.parent, geometry);
|
|
61
63
|
objects.push(worldObject);
|
|
62
64
|
}
|
|
63
|
-
return objects;
|
|
65
|
+
return [objects, unsetObjects];
|
|
64
66
|
});
|
|
65
67
|
const [fragmentFrames, fragmentUnsetFrames] = $derived.by(() => {
|
|
66
68
|
const { fragment_mods: fragmentMods = [] } = partConfig.localPartConfig.toJson() ?? {};
|
|
@@ -94,7 +96,7 @@ export const provideFrames = (partID) => {
|
|
|
94
96
|
const result = machineFrames[frame.name];
|
|
95
97
|
if (result) {
|
|
96
98
|
result.referenceFrame = frame.referenceFrame;
|
|
97
|
-
result.
|
|
99
|
+
result.localEditedPose = frame.pose;
|
|
98
100
|
result.geometry = frame.geometry;
|
|
99
101
|
}
|
|
100
102
|
else {
|
|
@@ -107,7 +109,7 @@ export const provideFrames = (partID) => {
|
|
|
107
109
|
const result = machineFrames[frame.name];
|
|
108
110
|
if (result) {
|
|
109
111
|
result.referenceFrame = frame.referenceFrame;
|
|
110
|
-
result.
|
|
112
|
+
result.localEditedPose = frame.pose;
|
|
111
113
|
result.geometry = frame.geometry;
|
|
112
114
|
}
|
|
113
115
|
else {
|
|
@@ -115,12 +117,21 @@ export const provideFrames = (partID) => {
|
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
});
|
|
120
|
+
$effect.pre(() => {
|
|
121
|
+
for (const name of configUnsetFrames) {
|
|
122
|
+
delete machineFrames[name];
|
|
123
|
+
}
|
|
124
|
+
});
|
|
118
125
|
$effect.pre(() => {
|
|
119
126
|
for (const name of fragmentUnsetFrames) {
|
|
120
127
|
delete machineFrames[name];
|
|
121
128
|
}
|
|
122
129
|
});
|
|
123
130
|
const current = $derived.by(() => {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
132
|
+
const _configFrames = configFrames;
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
134
|
+
const _fragmentFrames = fragmentFrames;
|
|
124
135
|
const results = Object.values(machineFrames);
|
|
125
136
|
updateUUIDs(results);
|
|
126
137
|
return results;
|
|
@@ -8,6 +8,7 @@ import { useMotionClient } from './useMotionClient.svelte';
|
|
|
8
8
|
import { useEnvironment } from './useEnvironment.svelte';
|
|
9
9
|
import { observe } from '@threlte/core';
|
|
10
10
|
import { untrack } from 'svelte';
|
|
11
|
+
import { useFrames } from './useFrames.svelte';
|
|
11
12
|
export const usePose = (name, parent) => {
|
|
12
13
|
const { refreshRates } = useMachineSettings();
|
|
13
14
|
const partID = usePartID();
|
|
@@ -16,6 +17,7 @@ export const usePose = (name, parent) => {
|
|
|
16
17
|
const resource = $derived(resources.current.find((resource) => resource.name === name()));
|
|
17
18
|
const parentResource = $derived(resources.current.find((resource) => resource.name === parent()));
|
|
18
19
|
const environment = useEnvironment();
|
|
20
|
+
const frames = useFrames();
|
|
19
21
|
const client = createResourceClient(MotionClient, () => partID.current, () => motionClient.current ?? '');
|
|
20
22
|
const interval = $derived(refreshRates.get(RefreshRates.poses));
|
|
21
23
|
const options = $derived(queryOptions({
|
|
@@ -34,7 +36,7 @@ export const usePose = (name, parent) => {
|
|
|
34
36
|
},
|
|
35
37
|
}));
|
|
36
38
|
const query = fromStore(createQuery(toStore(() => options)));
|
|
37
|
-
observe.pre(() => [environment.current.viewerMode], () => {
|
|
39
|
+
observe.pre(() => [environment.current.viewerMode, frames.current], () => {
|
|
38
40
|
if (environment.current.viewerMode === 'monitor') {
|
|
39
41
|
untrack(() => query.current).refetch();
|
|
40
42
|
}
|
|
@@ -5,15 +5,25 @@ import { createGeometry } from '../geometry';
|
|
|
5
5
|
import { WorldObject } from '../WorldObject.svelte';
|
|
6
6
|
const key = Symbol('static-geometries-context');
|
|
7
7
|
export const provideStaticGeometries = () => {
|
|
8
|
-
|
|
8
|
+
const geometries = $state([]);
|
|
9
|
+
let loaded = $state(false);
|
|
9
10
|
const debounced = new Debounced(() => geometries, 500);
|
|
10
11
|
get('static-geometries').then((response) => {
|
|
11
12
|
if (Array.isArray(response)) {
|
|
12
|
-
|
|
13
|
+
for (const json of response) {
|
|
14
|
+
geometries.push(new WorldObject().fromJSON(json));
|
|
15
|
+
}
|
|
13
16
|
}
|
|
17
|
+
loaded = true;
|
|
14
18
|
});
|
|
15
19
|
$effect(() => {
|
|
16
|
-
|
|
20
|
+
if (!loaded)
|
|
21
|
+
return;
|
|
22
|
+
const results = [];
|
|
23
|
+
for (const geometry of debounced.current) {
|
|
24
|
+
results.push(geometry.toJSON());
|
|
25
|
+
}
|
|
26
|
+
set('static-geometries', results);
|
|
17
27
|
});
|
|
18
28
|
setContext(key, {
|
|
19
29
|
get current() {
|
|
@@ -24,7 +34,7 @@ export const provideStaticGeometries = () => {
|
|
|
24
34
|
case: 'box',
|
|
25
35
|
value: { dimsMm: { x: 100, y: 100, z: 100 } },
|
|
26
36
|
}));
|
|
27
|
-
geometries.push(
|
|
37
|
+
geometries.push(object);
|
|
28
38
|
},
|
|
29
39
|
remove(name) {
|
|
30
40
|
const index = geometries.findIndex((geo) => geo.name === name);
|
package/dist/transform.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Geometry, Pose } from '@viamrobotics/sdk';
|
|
|
2
2
|
import { type Object3D, Matrix4, Quaternion, Vector3 } from 'three';
|
|
3
3
|
import type { Frame } from './frame';
|
|
4
4
|
export declare const createPose: (pose?: Pose) => Pose;
|
|
5
|
-
export declare const createPoseFromFrame: (frame: Frame) => Pose;
|
|
5
|
+
export declare const createPoseFromFrame: (frame: Partial<Frame>) => Pose;
|
|
6
6
|
export declare const quaternionToPose: (quaternion: Quaternion, pose: Partial<Pose>) => void;
|
|
7
7
|
export declare const vector3ToPose: (vec3: Vector3, pose: Partial<Pose>) => void;
|
|
8
8
|
export declare const object3dToPose: (object3d: Object3D, pose: Partial<Pose>) => Partial<import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Pose>>;
|
package/dist/transform.js
CHANGED
|
@@ -17,26 +17,26 @@ export const createPose = (pose) => {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
export const createPoseFromFrame = (frame) => {
|
|
20
|
-
if (frame.orientation
|
|
20
|
+
if (frame.orientation?.type === 'quaternion') {
|
|
21
21
|
quaternion.copy(frame.orientation.value);
|
|
22
22
|
ov.setFromQuaternion(quaternion);
|
|
23
23
|
}
|
|
24
|
-
else if (frame.orientation
|
|
24
|
+
else if (frame.orientation?.type === 'euler_angles') {
|
|
25
25
|
euler.set(frame.orientation.value.roll, frame.orientation.value.pitch, frame.orientation.value.yaw, 'ZYX');
|
|
26
26
|
quaternion.setFromEuler(euler);
|
|
27
27
|
ov.setFromQuaternion(quaternion);
|
|
28
28
|
}
|
|
29
|
-
else if (frame.orientation
|
|
29
|
+
else if (frame.orientation?.type === 'ov_radians') {
|
|
30
30
|
ov.copy(frame.orientation.value);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
const th = MathUtils.degToRad(frame.orientation
|
|
34
|
-
ov.set(frame.orientation
|
|
33
|
+
const th = MathUtils.degToRad(frame.orientation?.value.th ?? 0);
|
|
34
|
+
ov.set(frame.orientation?.value.x, frame.orientation?.value.y, frame.orientation?.value.z, th);
|
|
35
35
|
}
|
|
36
36
|
return {
|
|
37
|
-
x: frame.translation
|
|
38
|
-
y: frame.translation
|
|
39
|
-
z: frame.translation
|
|
37
|
+
x: frame.translation?.x ?? 0,
|
|
38
|
+
y: frame.translation?.y ?? 0,
|
|
39
|
+
z: frame.translation?.z ?? 0,
|
|
40
40
|
oX: ov.x,
|
|
41
41
|
oY: ov.y,
|
|
42
42
|
oZ: ov.z,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/motion-tools",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.3",
|
|
4
4
|
"description": "Motion visualization with Viam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prettier-plugin-tailwindcss": "0.6.14",
|
|
57
57
|
"publint": "0.3.12",
|
|
58
58
|
"runed": "0.31.1",
|
|
59
|
-
"svelte": "5.
|
|
59
|
+
"svelte": "5.43.0",
|
|
60
60
|
"svelte-check": "4.3.1",
|
|
61
61
|
"svelte-virtuallists": "1.4.2",
|
|
62
62
|
"tailwindcss": "4.1.13",
|