@viamrobotics/motion-tools 1.9.1 → 1.11.0
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/HoverUpdater.svelte.d.ts +16 -0
- package/dist/HoverUpdater.svelte.js +78 -0
- package/dist/WorldObject.svelte.d.ts +27 -0
- package/dist/WorldObject.svelte.js +8 -55
- package/dist/{draw → buf/draw}/v1/drawing_pb.d.ts +6 -0
- package/dist/{draw → buf/draw}/v1/drawing_pb.js +7 -0
- package/dist/buf/draw/v1/service_connect.d.ts +122 -0
- package/dist/buf/draw/v1/service_connect.js +126 -0
- package/dist/buf/draw/v1/service_pb.d.ts +382 -0
- package/dist/buf/draw/v1/service_pb.js +612 -0
- package/dist/components/App.svelte +28 -30
- package/dist/components/Arrows/Arrows.svelte +16 -3
- package/dist/components/FileDrop/file-dropper.d.ts +1 -1
- package/dist/components/FileDrop/snapshot-dropper.js +1 -1
- package/dist/components/FileDrop/useFileDrop.svelte.d.ts +2 -1
- package/dist/components/Frame.svelte +1 -1
- package/dist/components/Geometry.svelte +113 -71
- package/dist/components/Geometry.svelte.d.ts +6 -7
- package/dist/components/MeasureTool/MeasurePoint.svelte +3 -3
- package/dist/components/MeasureTool/MeasureTool.svelte +6 -6
- package/dist/components/SceneProviders.svelte +4 -0
- package/dist/components/Snapshot.svelte +1 -1
- package/dist/components/Snapshot.svelte.d.ts +1 -1
- package/dist/components/hover/HoveredEntities.svelte +23 -0
- package/dist/components/hover/HoveredEntity.svelte +15 -0
- package/dist/components/hover/HoveredEntity.svelte.d.ts +3 -0
- package/dist/components/hover/HoveredEntityTooltip.svelte +70 -0
- package/dist/components/{HoveredEntityTooltip.svelte.d.ts → hover/HoveredEntityTooltip.svelte.d.ts} +2 -2
- package/dist/components/hover/LinkedHoveredEntity.svelte +55 -0
- package/dist/components/hover/LinkedHoveredEntity.svelte.d.ts +9 -0
- package/dist/components/overlay/AddRelationship.svelte +131 -0
- package/dist/components/overlay/AddRelationship.svelte.d.ts +7 -0
- package/dist/components/overlay/Details.svelte +55 -2
- package/dist/components/overlay/FloatingPanel.svelte +78 -0
- package/dist/components/overlay/FloatingPanel.svelte.d.ts +13 -0
- package/dist/components/overlay/{left-pane/RefreshRate.svelte → RefreshRate.svelte} +1 -1
- package/dist/components/overlay/ToggleGroup.svelte +22 -26
- package/dist/components/overlay/ToggleGroup.svelte.d.ts +6 -7
- package/dist/components/overlay/left-pane/TreeContainer.svelte +0 -4
- package/dist/components/overlay/settings/Settings.svelte +330 -0
- package/dist/components/overlay/settings/Tabs.svelte +54 -0
- package/dist/components/overlay/settings/Tabs.svelte.d.ts +12 -0
- package/dist/components/overlay/widgets/Camera.svelte +20 -12
- package/dist/components/xr/ArmTeleop.svelte +469 -0
- package/dist/components/xr/ArmTeleop.svelte.d.ts +10 -0
- package/dist/components/xr/CameraFeed.svelte +191 -47
- package/dist/components/xr/CameraFeed.svelte.d.ts +7 -0
- package/dist/components/xr/Controllers.svelte +45 -38
- package/dist/components/xr/Controllers.svelte.d.ts +2 -17
- package/dist/components/xr/Hands.svelte +2 -4
- package/dist/components/xr/JointLimitsWidget.svelte +209 -0
- package/dist/components/xr/JointLimitsWidget.svelte.d.ts +13 -0
- package/dist/components/xr/OriginMarker.svelte +1 -15
- package/dist/components/xr/XR.svelte +78 -5
- package/dist/components/xr/XRConfigPanel.svelte +449 -0
- package/dist/components/xr/XRConfigPanel.svelte.d.ts +11 -0
- package/dist/components/xr/XRControllerSettings.svelte +240 -0
- package/dist/components/xr/XRControllerSettings.svelte.d.ts +3 -0
- package/dist/components/xr/XRToast.svelte +215 -0
- package/dist/components/xr/XRToast.svelte.d.ts +3 -0
- package/dist/components/xr/math.d.ts +14 -0
- package/dist/components/xr/math.js +26 -0
- package/dist/components/xr/toasts.svelte.d.ts +20 -0
- package/dist/components/xr/toasts.svelte.js +32 -0
- package/dist/components/xr/useOrigin.svelte.d.ts +2 -2
- package/dist/components/xr/useOrigin.svelte.js +4 -4
- package/dist/ecs/index.d.ts +1 -0
- package/dist/ecs/index.js +1 -0
- package/dist/ecs/relations.d.ts +7 -0
- package/dist/ecs/relations.js +7 -0
- package/dist/ecs/traits.d.ts +15 -1
- package/dist/ecs/traits.js +19 -5
- package/dist/ecs/useTrait.svelte.d.ts +3 -3
- package/dist/frame.d.ts +0 -3
- package/dist/hooks/useArmKinematics.svelte.d.ts +12 -0
- package/dist/hooks/useArmKinematics.svelte.js +31 -0
- package/dist/hooks/useGeometries.svelte.js +47 -36
- package/dist/hooks/useLinked.svelte.d.ts +7 -0
- package/dist/hooks/useLinked.svelte.js +35 -0
- package/dist/hooks/useObjectEvents.svelte.js +52 -16
- package/dist/hooks/usePartConfig.svelte.d.ts +0 -35
- package/dist/hooks/usePartConfig.svelte.js +2 -2
- package/dist/hooks/usePointcloudObjects.svelte.js +45 -64
- package/dist/hooks/usePointclouds.svelte.js +13 -9
- package/dist/hooks/usePose.svelte.js +5 -2
- package/dist/hooks/useResourceByName.svelte.d.ts +7 -0
- package/dist/hooks/useResourceByName.svelte.js +2 -2
- package/dist/hooks/useSettings.svelte.d.ts +14 -0
- package/dist/hooks/useSettings.svelte.js +10 -0
- package/dist/hooks/useWorldState.svelte.d.ts +0 -8
- package/dist/lib.d.ts +1 -3
- package/dist/lib.js +1 -3
- package/dist/snapshot.d.ts +2 -2
- package/dist/snapshot.js +2 -2
- package/dist/three/InstancedArrows/raycast.d.ts +2 -4
- package/dist/three/InstancedArrows/raycast.js +5 -5
- package/dist/transform.js +1 -0
- package/package.json +7 -5
- package/dist/assert.d.ts +0 -14
- package/dist/assert.js +0 -21
- package/dist/components/BatchedGeometry.svelte +0 -0
- package/dist/components/BatchedGeometry.svelte.d.ts +0 -26
- package/dist/components/Detections.svelte +0 -41
- package/dist/components/Detections.svelte.d.ts +0 -3
- package/dist/components/DetectionsPlane.svelte +0 -23
- package/dist/components/DetectionsPlane.svelte.d.ts +0 -21
- package/dist/components/Geometry2.svelte +0 -211
- package/dist/components/Geometry2.svelte.d.ts +0 -19
- package/dist/components/HoveredEntities.svelte +0 -19
- package/dist/components/HoveredEntityTooltip.svelte +0 -242
- package/dist/components/overlay/left-pane/Settings.svelte +0 -221
- package/dist/components/overlay/left-pane/Widgets.svelte +0 -65
- package/dist/components/overlay/left-pane/Widgets.svelte.d.ts +0 -3
- package/dist/entries.d.ts +0 -1
- package/dist/entries.js +0 -3
- package/dist/hooks/index.d.ts +0 -0
- package/dist/hooks/index.js +0 -1
- package/dist/test.d.ts +0 -1
- package/dist/test.js +0 -1
- package/dist/three/BoxHelper.d.ts +0 -50
- package/dist/three/BoxHelper.js +0 -134
- /package/dist/{common → buf/common}/v1/common_pb.d.ts +0 -0
- /package/dist/{common → buf/common}/v1/common_pb.js +0 -0
- /package/dist/{draw → buf/draw}/v1/metadata_pb.d.ts +0 -0
- /package/dist/{draw → buf/draw}/v1/metadata_pb.js +0 -0
- /package/dist/{draw → buf/draw}/v1/scene_pb.d.ts +0 -0
- /package/dist/{draw → buf/draw}/v1/scene_pb.js +0 -0
- /package/dist/{draw → buf/draw}/v1/snapshot_pb.d.ts +0 -0
- /package/dist/{draw → buf/draw}/v1/snapshot_pb.js +0 -0
- /package/dist/{draw → buf/draw}/v1/transforms_pb.d.ts +0 -0
- /package/dist/{draw → buf/draw}/v1/transforms_pb.js +0 -0
- /package/dist/components/{HoveredEntities.svelte.d.ts → hover/HoveredEntities.svelte.d.ts} +0 -0
- /package/dist/components/overlay/{left-pane/RefreshRate.svelte.d.ts → RefreshRate.svelte.d.ts} +0 -0
- /package/dist/components/overlay/{left-pane → settings}/Settings.svelte.d.ts +0 -0
- /package/dist/components/{BentPlaneGeometry.svelte → xr/BentPlaneGeometry.svelte} +0 -0
- /package/dist/components/{BentPlaneGeometry.svelte.d.ts → xr/BentPlaneGeometry.svelte.d.ts} +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Switch, Input } from '@viamrobotics/prime-core'
|
|
3
|
+
import { Portal } from '@threlte/extras'
|
|
4
|
+
import RefreshRate from '../RefreshRate.svelte'
|
|
5
|
+
import { useSettings } from '../../../hooks/useSettings.svelte'
|
|
6
|
+
import { useResourceNames } from '@viamrobotics/svelte-sdk'
|
|
7
|
+
import { usePartID } from '../../../hooks/usePartID.svelte'
|
|
8
|
+
import { RefreshRates, useMachineSettings } from '../../../hooks/useMachineSettings.svelte'
|
|
9
|
+
import { useGeometries } from '../../../hooks/useGeometries.svelte'
|
|
10
|
+
import { usePointClouds } from '../../../hooks/usePointclouds.svelte'
|
|
11
|
+
import { useThrelte } from '@threlte/core'
|
|
12
|
+
import { useRefetchPoses } from '../../../hooks/useRefetchPoses'
|
|
13
|
+
import FloatingPanel from '../FloatingPanel.svelte'
|
|
14
|
+
import DashboardButton from '../dashboard/Button.svelte'
|
|
15
|
+
import Tabs from './Tabs.svelte'
|
|
16
|
+
import { PersistedState } from 'runed'
|
|
17
|
+
import ToggleGroup from '../ToggleGroup.svelte'
|
|
18
|
+
import XRControllerSettings from '../../xr/XRControllerSettings.svelte'
|
|
19
|
+
|
|
20
|
+
const { invalidate } = useThrelte()
|
|
21
|
+
const partID = usePartID()
|
|
22
|
+
const cameras = useResourceNames(() => partID.current, 'camera')
|
|
23
|
+
const visionServices = useResourceNames(() => partID.current, 'vision')
|
|
24
|
+
const settings = useSettings()
|
|
25
|
+
const { disabledCameras, disabledVisionServices } = useMachineSettings()
|
|
26
|
+
const geometries = useGeometries()
|
|
27
|
+
const pointclouds = usePointClouds()
|
|
28
|
+
const { refetchPoses } = useRefetchPoses()
|
|
29
|
+
|
|
30
|
+
// Invalidate the renderer for any settings change
|
|
31
|
+
$effect(() => {
|
|
32
|
+
for (const key in settings.current) {
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
34
|
+
settings.current[key as keyof typeof settings.current]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
invalidate()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const currentRobotCameraWidgets = $derived(
|
|
41
|
+
settings.current.openCameraWidgets[partID.current] || []
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
const isOpen = new PersistedState('settings-is-open', false)
|
|
45
|
+
const activeTab = new PersistedState('settings-active-tab', 'Connection')
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<Portal id="dashboard">
|
|
49
|
+
<fieldset>
|
|
50
|
+
<DashboardButton
|
|
51
|
+
active
|
|
52
|
+
icon="cog"
|
|
53
|
+
description="Settings"
|
|
54
|
+
onclick={() => {
|
|
55
|
+
isOpen.current = !isOpen.current
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
58
|
+
</fieldset>
|
|
59
|
+
</Portal>
|
|
60
|
+
|
|
61
|
+
{#snippet SectionTitle(title: string)}
|
|
62
|
+
<h3 class="border-gray-3 border-b py-1 text-sm"><strong>{title}</strong></h3>
|
|
63
|
+
{/snippet}
|
|
64
|
+
|
|
65
|
+
{#snippet Connection()}
|
|
66
|
+
<div class="flex flex-col gap-2.5 text-xs">
|
|
67
|
+
{@render SectionTitle('Polling rates')}
|
|
68
|
+
|
|
69
|
+
<RefreshRate
|
|
70
|
+
id={RefreshRates.poses}
|
|
71
|
+
label="Poses"
|
|
72
|
+
allowLive
|
|
73
|
+
onManualRefetch={() => {
|
|
74
|
+
refetchPoses()
|
|
75
|
+
geometries.refetch()
|
|
76
|
+
}}
|
|
77
|
+
/>
|
|
78
|
+
<RefreshRate
|
|
79
|
+
id={RefreshRates.pointclouds}
|
|
80
|
+
label="Pointclouds"
|
|
81
|
+
onManualRefetch={() => {
|
|
82
|
+
pointclouds.refetch()
|
|
83
|
+
}}
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
{/snippet}
|
|
87
|
+
|
|
88
|
+
{#snippet Pointclouds()}
|
|
89
|
+
<div class="flex flex-col gap-1 text-xs">
|
|
90
|
+
<label class="flex items-center justify-between gap-2">
|
|
91
|
+
Default point size
|
|
92
|
+
|
|
93
|
+
<div class="w-20">
|
|
94
|
+
<Input
|
|
95
|
+
bind:value={settings.current.pointSize}
|
|
96
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
</label>
|
|
100
|
+
|
|
101
|
+
<label class="flex items-center justify-between gap-2">
|
|
102
|
+
Default point color
|
|
103
|
+
|
|
104
|
+
<div class="w-20">
|
|
105
|
+
<Input
|
|
106
|
+
type="color"
|
|
107
|
+
bind:value={settings.current.pointColor}
|
|
108
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</label>
|
|
112
|
+
|
|
113
|
+
{@render SectionTitle('Enabled cameras')}
|
|
114
|
+
|
|
115
|
+
{#each cameras.current as camera (camera)}
|
|
116
|
+
<div class="flex items-center justify-between py-0.5 text-xs">
|
|
117
|
+
{camera.name}
|
|
118
|
+
<Switch
|
|
119
|
+
on={disabledCameras.get(camera.name) !== true}
|
|
120
|
+
on:change={(event) => {
|
|
121
|
+
disabledCameras.set(camera.name, !event.detail)
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
{:else}
|
|
126
|
+
No cameras detected
|
|
127
|
+
{/each}
|
|
128
|
+
</div>
|
|
129
|
+
{/snippet}
|
|
130
|
+
|
|
131
|
+
{#snippet Vision()}
|
|
132
|
+
<div class="text-gray-9 flex flex-col gap-1 text-xs">
|
|
133
|
+
{@render SectionTitle('Enabled vision services')}
|
|
134
|
+
|
|
135
|
+
{#each visionServices.current as visionService (visionService)}
|
|
136
|
+
<div class="flex items-center justify-between py-0.5">
|
|
137
|
+
{visionService.name}
|
|
138
|
+
<Switch
|
|
139
|
+
on={disabledVisionServices.get(visionService.name) !== true}
|
|
140
|
+
on:change={(event) => {
|
|
141
|
+
disabledVisionServices.set(visionService.name, !event.detail)
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
{:else}
|
|
146
|
+
No vision services detected
|
|
147
|
+
{/each}
|
|
148
|
+
</div>
|
|
149
|
+
{/snippet}
|
|
150
|
+
|
|
151
|
+
{#snippet Scene()}
|
|
152
|
+
<div class="text-gray-9 flex flex-col gap-1 text-xs">
|
|
153
|
+
<label class="flex items-center justify-between gap-2 py-1">
|
|
154
|
+
Arm Models
|
|
155
|
+
|
|
156
|
+
<ToggleGroup
|
|
157
|
+
multiple
|
|
158
|
+
options={[
|
|
159
|
+
{
|
|
160
|
+
label: 'Colliders',
|
|
161
|
+
value: 'colliders',
|
|
162
|
+
selected: settings.current.renderArmModels.includes('colliders'),
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
label: 'Model',
|
|
166
|
+
value: 'model',
|
|
167
|
+
selected: settings.current.renderArmModels.includes('model'),
|
|
168
|
+
},
|
|
169
|
+
]}
|
|
170
|
+
onSelect={(value) => {
|
|
171
|
+
settings.current.renderArmModels = (value.join('+') || 'colliders') as
|
|
172
|
+
| 'colliders'
|
|
173
|
+
| 'model'
|
|
174
|
+
| 'colliders+model'
|
|
175
|
+
|
|
176
|
+
console.log(settings.current.renderArmModels)
|
|
177
|
+
}}
|
|
178
|
+
/>
|
|
179
|
+
</label>
|
|
180
|
+
|
|
181
|
+
<label class="flex items-center justify-between gap-2">
|
|
182
|
+
Single item hover details <Switch bind:on={settings.current.renderSubEntityHoverDetail} />
|
|
183
|
+
</label>
|
|
184
|
+
|
|
185
|
+
<label class="flex items-center justify-between gap-2">
|
|
186
|
+
Object labels <Switch bind:on={settings.current.enableLabels} />
|
|
187
|
+
</label>
|
|
188
|
+
|
|
189
|
+
{@render SectionTitle('Grid')}
|
|
190
|
+
|
|
191
|
+
<label class="flex items-center justify-between gap-2 py-1">
|
|
192
|
+
Visible <Switch bind:on={settings.current.grid} />
|
|
193
|
+
</label>
|
|
194
|
+
|
|
195
|
+
<label class="flex items-center justify-between gap-2">
|
|
196
|
+
Cell size (m)
|
|
197
|
+
|
|
198
|
+
<div class="w-20">
|
|
199
|
+
<Input
|
|
200
|
+
bind:value={settings.current.gridCellSize}
|
|
201
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
</label>
|
|
205
|
+
|
|
206
|
+
<label class="flex items-center justify-between gap-2">
|
|
207
|
+
Section size (m)
|
|
208
|
+
|
|
209
|
+
<div class="w-20">
|
|
210
|
+
<Input
|
|
211
|
+
bind:value={settings.current.gridSectionSize}
|
|
212
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
213
|
+
/>
|
|
214
|
+
</div>
|
|
215
|
+
</label>
|
|
216
|
+
|
|
217
|
+
<label class="flex items-center justify-between gap-2">
|
|
218
|
+
Fade distance (m)
|
|
219
|
+
|
|
220
|
+
<div class="w-20">
|
|
221
|
+
<Input
|
|
222
|
+
bind:value={settings.current.gridFadeDistance}
|
|
223
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
</label>
|
|
227
|
+
|
|
228
|
+
{@render SectionTitle('Lines')}
|
|
229
|
+
|
|
230
|
+
<label class="flex items-center justify-between gap-2">
|
|
231
|
+
Thickness
|
|
232
|
+
|
|
233
|
+
<div class="w-20">
|
|
234
|
+
<Input
|
|
235
|
+
bind:value={settings.current.lineWidth}
|
|
236
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
237
|
+
/>
|
|
238
|
+
</div>
|
|
239
|
+
</label>
|
|
240
|
+
|
|
241
|
+
<label class="flex items-center justify-between gap-2">
|
|
242
|
+
Dot size
|
|
243
|
+
|
|
244
|
+
<div class="w-20">
|
|
245
|
+
<Input
|
|
246
|
+
bind:value={settings.current.lineDotSize}
|
|
247
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
248
|
+
/>
|
|
249
|
+
</div>
|
|
250
|
+
</label>
|
|
251
|
+
</div>
|
|
252
|
+
{/snippet}
|
|
253
|
+
|
|
254
|
+
{#snippet Stats()}
|
|
255
|
+
<div class="flex w-full flex-col gap-2.5 text-xs">
|
|
256
|
+
<label class="flex items-center justify-between gap-2">
|
|
257
|
+
Query devtools <Switch bind:on={settings.current.enableQueryDevtools} />
|
|
258
|
+
</label>
|
|
259
|
+
|
|
260
|
+
<label class="flex items-center justify-between gap-2">
|
|
261
|
+
Render stats <Switch bind:on={settings.current.renderStats} />
|
|
262
|
+
</label>
|
|
263
|
+
</div>
|
|
264
|
+
{/snippet}
|
|
265
|
+
|
|
266
|
+
{#snippet XR()}
|
|
267
|
+
<div class="flex flex-col gap-2.5 text-xs">
|
|
268
|
+
<XRControllerSettings />
|
|
269
|
+
</div>
|
|
270
|
+
{/snippet}
|
|
271
|
+
|
|
272
|
+
{#snippet Widgets()}
|
|
273
|
+
<div class="text-gray-9 flex flex-col gap-1 text-xs">
|
|
274
|
+
<label class="flex items-center justify-between gap-2 py-1">
|
|
275
|
+
Arm positions
|
|
276
|
+
<Switch bind:on={settings.current.enableArmPositionsWidget} />
|
|
277
|
+
</label>
|
|
278
|
+
|
|
279
|
+
{@render SectionTitle('Camera widgets')}
|
|
280
|
+
|
|
281
|
+
{#each cameras.current as camera (camera)}
|
|
282
|
+
{@const isWidgetOpen = currentRobotCameraWidgets.includes(camera.name)}
|
|
283
|
+
<div class="flex items-center justify-between gap-2 py-0.5">
|
|
284
|
+
<span class="min-w-0 truncate">{camera.name}</span>
|
|
285
|
+
<Switch
|
|
286
|
+
on={isWidgetOpen}
|
|
287
|
+
on:change={(event) => {
|
|
288
|
+
if (event.detail) {
|
|
289
|
+
settings.current.openCameraWidgets = {
|
|
290
|
+
...settings.current.openCameraWidgets,
|
|
291
|
+
[partID.current]: [...currentRobotCameraWidgets, camera.name],
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
settings.current.openCameraWidgets = {
|
|
295
|
+
...settings.current.openCameraWidgets,
|
|
296
|
+
[partID.current]: currentRobotCameraWidgets.filter(
|
|
297
|
+
(widget) => widget !== camera.name
|
|
298
|
+
),
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}}
|
|
302
|
+
/>
|
|
303
|
+
</div>
|
|
304
|
+
{:else}
|
|
305
|
+
No cameras detected
|
|
306
|
+
{/each}
|
|
307
|
+
</div>
|
|
308
|
+
{/snippet}
|
|
309
|
+
|
|
310
|
+
<FloatingPanel
|
|
311
|
+
title="Settings"
|
|
312
|
+
bind:isOpen={isOpen.current}
|
|
313
|
+
defaultSize={{ width: 460, height: 500 }}
|
|
314
|
+
>
|
|
315
|
+
<Tabs
|
|
316
|
+
defaultTab={activeTab.current}
|
|
317
|
+
items={[
|
|
318
|
+
{ label: 'Connection', content: Connection },
|
|
319
|
+
{ label: 'Scene', content: Scene },
|
|
320
|
+
{ label: 'Pointclouds', content: Pointclouds },
|
|
321
|
+
{ label: 'Vision', content: Vision },
|
|
322
|
+
{ label: 'Widgets', content: Widgets },
|
|
323
|
+
{ label: 'Stats', content: Stats },
|
|
324
|
+
...('xr' in navigator ? [{ label: 'VR / AR', content: XR }] : []),
|
|
325
|
+
]}
|
|
326
|
+
onValueChange={(value) => {
|
|
327
|
+
activeTab.current = value
|
|
328
|
+
}}
|
|
329
|
+
/>
|
|
330
|
+
</FloatingPanel>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
import * as tabs from '@zag-js/tabs'
|
|
4
|
+
import { useMachine, normalizeProps } from '@zag-js/svelte'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
defaultTab?: string
|
|
8
|
+
onValueChange: (value: string) => void
|
|
9
|
+
items: {
|
|
10
|
+
label: string
|
|
11
|
+
content: Snippet
|
|
12
|
+
}[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { defaultTab, items, onValueChange }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const id = $props.id()
|
|
18
|
+
const service = useMachine(tabs.machine, () => ({
|
|
19
|
+
id,
|
|
20
|
+
defaultValue: defaultTab,
|
|
21
|
+
onValueChange: (details) => onValueChange(details.value),
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
const api = $derived(tabs.connect(service, normalizeProps))
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<div
|
|
28
|
+
{...api.getRootProps()}
|
|
29
|
+
class="flex h-full gap-2 overflow-hidden"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
{...api.getListProps()}
|
|
33
|
+
class="bg-gray-1 flex h-full flex-col items-start p-2 text-sm"
|
|
34
|
+
>
|
|
35
|
+
{#each items as item (item.label)}
|
|
36
|
+
<button
|
|
37
|
+
{...api.getTriggerProps({ value: item.label })}
|
|
38
|
+
class="text-gray-8 w-full py-1 pr-8 pl-3 text-left"
|
|
39
|
+
class:bg-gray-2={api.focusedValue === item.label}
|
|
40
|
+
>
|
|
41
|
+
{item.label}
|
|
42
|
+
</button>
|
|
43
|
+
{/each}
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{#each items as item (item.label)}
|
|
47
|
+
<div
|
|
48
|
+
{...api.getContentProps({ value: item.label })}
|
|
49
|
+
class="h-full w-full overflow-y-auto p-4"
|
|
50
|
+
>
|
|
51
|
+
{@render item.content()}
|
|
52
|
+
</div>
|
|
53
|
+
{/each}
|
|
54
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
defaultTab?: string;
|
|
4
|
+
onValueChange: (value: string) => void;
|
|
5
|
+
items: {
|
|
6
|
+
label: string;
|
|
7
|
+
content: Snippet;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
declare const Tabs: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Tabs = ReturnType<typeof Tabs>;
|
|
12
|
+
export default Tabs;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { draggable } from '@neodrag/svelte'
|
|
3
3
|
import { Icon, Select } from '@viamrobotics/prime-core'
|
|
4
|
-
import { CameraStream, useRobotClient } from '@viamrobotics/svelte-sdk'
|
|
5
|
-
import { StreamClient } from '@viamrobotics/sdk'
|
|
4
|
+
import { CameraStream, useRobotClient, useConnectionStatus } from '@viamrobotics/svelte-sdk'
|
|
5
|
+
import { StreamClient, MachineConnectionEvent } from '@viamrobotics/sdk'
|
|
6
6
|
import { useSettings } from '../../../hooks/useSettings.svelte'
|
|
7
7
|
import { usePartID } from '../../../hooks/usePartID.svelte'
|
|
8
8
|
import { useEnvironment } from '../../../hooks/useEnvironment.svelte'
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
const settings = useSettings()
|
|
18
18
|
const partID = usePartID()
|
|
19
19
|
const client = useRobotClient(() => partID.current)
|
|
20
|
+
const connectionStatus = useConnectionStatus(() => partID.current)
|
|
20
21
|
const environment = useEnvironment()
|
|
21
22
|
|
|
22
23
|
let dragElement = $state.raw<HTMLElement>()
|
|
@@ -70,13 +71,18 @@
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
//
|
|
74
|
-
let streamClient = $derived(
|
|
74
|
+
// Only create StreamClient when connection is fully established
|
|
75
|
+
let streamClient = $derived(
|
|
76
|
+
client.current && connectionStatus.current === MachineConnectionEvent.CONNECTED
|
|
77
|
+
? new StreamClient(client.current)
|
|
78
|
+
: undefined
|
|
79
|
+
)
|
|
75
80
|
|
|
76
81
|
$effect(() => {
|
|
77
82
|
if (streamClient) {
|
|
78
83
|
isLoading = true
|
|
79
84
|
error = undefined
|
|
85
|
+
|
|
80
86
|
streamClient
|
|
81
87
|
.getOptions(name)
|
|
82
88
|
.then((options) => {
|
|
@@ -164,14 +170,16 @@
|
|
|
164
170
|
class="relative min-h-0 w-full flex-1 overflow-hidden bg-black [&_img]:h-full [&_img]:w-full [&_img]:object-fill [&_video]:h-full [&_video]:w-full [&_video]:object-fill"
|
|
165
171
|
style:aspect-ratio={aspectRatio}
|
|
166
172
|
>
|
|
167
|
-
{#
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
{#if connectionStatus.current === MachineConnectionEvent.CONNECTED}
|
|
174
|
+
{#key environment.current.viewerMode === 'monitor'}
|
|
175
|
+
<CameraStream
|
|
176
|
+
{name}
|
|
177
|
+
partID={partID.current}
|
|
178
|
+
onloadedmetadata={onMediaLoad}
|
|
179
|
+
onload={onMediaLoad}
|
|
180
|
+
/>
|
|
181
|
+
{/key}
|
|
182
|
+
{/if}
|
|
175
183
|
|
|
176
184
|
<!-- FPS Pill -->
|
|
177
185
|
{#if fps > 0}
|