@viamrobotics/test-widgets 0.11.2 → 0.11.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/components/widgets/arm/move-to-joint-positions.svelte +39 -47
- package/dist/components/widgets/movement-sensor/map.svelte +1 -1
- package/dist/components/widgets/movement-sensor/movement-sensor.svelte +129 -127
- package/dist/components/widgets/navigation/navigation.svelte +79 -75
- package/dist/components/widgets/slam/move-on-map.svelte +1 -1
- package/dist/components/widgets/slam/slam.svelte +72 -64
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Icon, Tooltip } from '@viamrobotics/prime-core'
|
|
2
|
+
import { Icon, ToggleButtons, Tooltip } from '@viamrobotics/prime-core'
|
|
3
3
|
|
|
4
4
|
import AngleUnitToggle from '../../angle-unit-toggle.svelte'
|
|
5
5
|
import CopyButton from '../../copy-button.svelte'
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
import { type JointLimit } from './joint-position-limits'
|
|
12
12
|
import JointPositionQuickMove from './joint-position-quick-move.svelte'
|
|
13
13
|
|
|
14
|
-
type ControlMode = '
|
|
14
|
+
type ControlMode = 'Joint Positions' | 'Quick Move'
|
|
15
|
+
|
|
16
|
+
const CONTROL_MODES: ControlMode[] = ['Joint Positions', 'Quick Move']
|
|
15
17
|
|
|
16
18
|
interface Props {
|
|
17
19
|
positions: number[]
|
|
@@ -32,9 +34,9 @@
|
|
|
32
34
|
// svelte-ignore state_referenced_locally
|
|
33
35
|
let desiredPositions = $state([...positions]) // in degrees
|
|
34
36
|
let useRadians = $state(false)
|
|
35
|
-
let controlMode = $state<ControlMode>('
|
|
37
|
+
let controlMode = $state<ControlMode>('Joint Positions')
|
|
36
38
|
|
|
37
|
-
const isQuickMoveMode = $derived(controlMode === '
|
|
39
|
+
const isQuickMoveMode = $derived(controlMode === 'Quick Move')
|
|
38
40
|
|
|
39
41
|
const getJointMin = (index: number): number => jointLimitsDegrees[index]?.minDegrees ?? -180
|
|
40
42
|
const getJointMax = (index: number): number => jointLimitsDegrees[index]?.maxDegrees ?? 180
|
|
@@ -44,8 +46,11 @@
|
|
|
44
46
|
const displayPositions = $derived(desiredPositions.map((degrees) => toDisplayAngle(degrees)))
|
|
45
47
|
const copyData = $derived(`[${displayPositions.map((v) => formatNumeric(v)).join(', ')}]`)
|
|
46
48
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
+
const handleModeChange = ({ detail }: CustomEvent<string>) => {
|
|
50
|
+
const nextMode = CONTROL_MODES.find((mode) => mode === detail)
|
|
51
|
+
if (nextMode) {
|
|
52
|
+
controlMode = nextMode
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
const handlePaste = (data: string): boolean => {
|
|
@@ -63,48 +68,35 @@
|
|
|
63
68
|
</script>
|
|
64
69
|
|
|
65
70
|
<div class="flex min-w-0 flex-col gap-4">
|
|
66
|
-
<div class="flex items-center justify-between">
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<span slot="description">
|
|
75
|
-
Joint position limits are based solely on the arm kinematics and do not take into account
|
|
76
|
-
motion service limit overrides.
|
|
77
|
-
</span>
|
|
78
|
-
</Tooltip>
|
|
79
|
-
</span>
|
|
71
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
72
|
+
<ToggleButtons
|
|
73
|
+
role="group"
|
|
74
|
+
aria-label="Control mode"
|
|
75
|
+
options={CONTROL_MODES}
|
|
76
|
+
selected={controlMode}
|
|
77
|
+
on:input={handleModeChange}
|
|
78
|
+
/>
|
|
80
79
|
<div class="flex items-center gap-1">
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
>
|
|
102
|
-
<Icon name="lightning-bolt-outline" />
|
|
103
|
-
</button>
|
|
104
|
-
<span slot="description">
|
|
105
|
-
{isQuickMoveMode ? 'Exit quick move mode' : 'Enter quick move mode'}
|
|
106
|
-
</span>
|
|
107
|
-
</Tooltip>
|
|
80
|
+
{#if !isQuickMoveMode}
|
|
81
|
+
<Tooltip>
|
|
82
|
+
<Icon
|
|
83
|
+
name="information-outline"
|
|
84
|
+
cx="text-gray-6"
|
|
85
|
+
/>
|
|
86
|
+
<span slot="description">
|
|
87
|
+
Joint position limits are based solely on the arm kinematics and do not take into
|
|
88
|
+
account motion service limit overrides.
|
|
89
|
+
</span>
|
|
90
|
+
</Tooltip>
|
|
91
|
+
<CopyButton data={copyData} />
|
|
92
|
+
<PasteButton onPaste={handlePaste} />
|
|
93
|
+
{/if}
|
|
94
|
+
<AngleUnitToggle
|
|
95
|
+
{useRadians}
|
|
96
|
+
onToggle={() => {
|
|
97
|
+
useRadians = !useRadians
|
|
98
|
+
}}
|
|
99
|
+
/>
|
|
108
100
|
</div>
|
|
109
101
|
</div>
|
|
110
102
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
const lng = $derived(safeReadCoordinate(coordinate?.longitude))
|
|
25
25
|
</script>
|
|
26
26
|
|
|
27
|
-
<div class="relative h-[300px] w-full
|
|
27
|
+
<div class="relative h-[300px] w-full @4xl:h-auto @4xl:w-1/2">
|
|
28
28
|
<MapLibre
|
|
29
29
|
zoom={15}
|
|
30
30
|
options={{ attributionControl: { compact: false } }}
|
|
@@ -103,150 +103,152 @@
|
|
|
103
103
|
query={propertiesQuery}
|
|
104
104
|
contentCx="p-4 h-14"
|
|
105
105
|
>
|
|
106
|
-
<div class="
|
|
107
|
-
<div class="flex
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
106
|
+
<div class="@container">
|
|
107
|
+
<div class="flex flex-wrap text-xs @4xl:flex-nowrap">
|
|
108
|
+
<div class="flex w-full flex-col gap-5 py-4 pr-6 pl-4 @4xl:w-1/4">
|
|
109
|
+
{#if propertiesQuery.data?.positionSupported}
|
|
110
|
+
<div class="flex flex-col gap-2">
|
|
111
|
+
<SectionTitle
|
|
112
|
+
title="GetPosition"
|
|
113
|
+
api={MS_API}
|
|
114
|
+
/>
|
|
115
|
+
<Query
|
|
116
|
+
query={positionQuery}
|
|
117
|
+
contentCx="h-6"
|
|
118
|
+
>
|
|
119
|
+
{#if positionQuery.data !== undefined}
|
|
120
|
+
<Position data={positionQuery.data} />
|
|
121
|
+
{/if}
|
|
122
|
+
</Query>
|
|
123
|
+
</div>
|
|
124
|
+
{/if}
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
{#if propertiesQuery.data?.orientationSupported}
|
|
127
|
+
<div class="flex flex-col gap-2">
|
|
128
|
+
<SectionTitle
|
|
129
|
+
title="GetOrientation"
|
|
130
|
+
api={MS_API}
|
|
131
|
+
>
|
|
132
|
+
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal">(º)</span
|
|
133
|
+
>{/snippet}
|
|
134
|
+
</SectionTitle>
|
|
135
|
+
<Query
|
|
136
|
+
query={orientationQuery}
|
|
137
|
+
contentCx="h-6"
|
|
138
|
+
>
|
|
139
|
+
{#if orientationQuery.data !== undefined}
|
|
140
|
+
<Orientation data={orientationQuery.data} />
|
|
141
|
+
{/if}
|
|
142
|
+
</Query>
|
|
143
|
+
</div>
|
|
144
|
+
{/if}
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
146
|
+
{#if propertiesQuery.data?.compassHeadingSupported}
|
|
147
|
+
<div class="flex flex-col gap-2">
|
|
148
|
+
<SectionTitle
|
|
149
|
+
title="GetCompassHeading"
|
|
150
|
+
api={MS_API}
|
|
151
|
+
>
|
|
152
|
+
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal">(º)</span
|
|
153
|
+
>{/snippet}
|
|
154
|
+
</SectionTitle>
|
|
155
|
+
<Query
|
|
156
|
+
query={compassHeadingQuery}
|
|
157
|
+
contentCx="h-6"
|
|
158
|
+
>
|
|
159
|
+
{#if compassHeadingQuery.data !== undefined}
|
|
160
|
+
<CompassHeading data={compassHeadingQuery.data} />
|
|
161
|
+
{/if}
|
|
162
|
+
</Query>
|
|
163
|
+
</div>
|
|
164
|
+
{/if}
|
|
165
|
+
</div>
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
167
|
+
<div class="flex w-full flex-col gap-5 p-4 @4xl:w-1/4">
|
|
168
|
+
{#if propertiesQuery.data?.angularVelocitySupported}
|
|
169
|
+
<div class="flex flex-col gap-2">
|
|
170
|
+
<SectionTitle
|
|
171
|
+
title="GetAngularVelocity"
|
|
172
|
+
api={MS_API}
|
|
173
|
+
>
|
|
174
|
+
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal">(º/s)</span
|
|
175
|
+
>{/snippet}
|
|
176
|
+
</SectionTitle>
|
|
177
|
+
<Query
|
|
178
|
+
query={angularVelocityQuery}
|
|
179
|
+
contentCx="h-6"
|
|
180
|
+
>
|
|
181
|
+
{#if angularVelocityQuery.data !== undefined}
|
|
182
|
+
<Vector3 data={angularVelocityQuery.data} />
|
|
183
|
+
{/if}
|
|
184
|
+
</Query>
|
|
185
|
+
</div>
|
|
186
|
+
{/if}
|
|
186
187
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
188
|
+
{#if propertiesQuery.data?.linearVelocitySupported}
|
|
189
|
+
<div class="flex flex-col gap-2">
|
|
190
|
+
<SectionTitle
|
|
191
|
+
title="GetLinearVelocity"
|
|
192
|
+
api={MS_API}
|
|
193
|
+
>
|
|
194
|
+
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal">(m/s)</span
|
|
195
|
+
>{/snippet}
|
|
196
|
+
</SectionTitle>
|
|
197
|
+
<Query
|
|
198
|
+
query={linearVelocityQuery}
|
|
199
|
+
contentCx="h-6"
|
|
200
|
+
>
|
|
201
|
+
{#if linearVelocityQuery.data !== undefined}
|
|
202
|
+
<Vector3 data={linearVelocityQuery.data} />
|
|
203
|
+
{/if}
|
|
204
|
+
</Query>
|
|
205
|
+
</div>
|
|
206
|
+
{/if}
|
|
207
|
+
|
|
208
|
+
{#if propertiesQuery.data?.linearAccelerationSupported}
|
|
209
|
+
<div class="flex flex-col gap-2">
|
|
210
|
+
<SectionTitle
|
|
211
|
+
title="GetLinearAcceleration"
|
|
212
|
+
api={MS_API}
|
|
213
|
+
>
|
|
214
|
+
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal"
|
|
215
|
+
>(m/s<sup>2</sup>)</span
|
|
216
|
+
>{/snippet}
|
|
217
|
+
</SectionTitle>
|
|
218
|
+
<Query
|
|
219
|
+
query={linearAccelerationQuery}
|
|
220
|
+
contentCx="h-6"
|
|
221
|
+
>
|
|
222
|
+
{#if linearAccelerationQuery.data !== undefined}
|
|
223
|
+
<Vector3 data={linearAccelerationQuery.data} />
|
|
224
|
+
{/if}
|
|
225
|
+
</Query>
|
|
226
|
+
</div>
|
|
227
|
+
{/if}
|
|
206
228
|
|
|
207
|
-
{#if propertiesQuery.data?.linearAccelerationSupported}
|
|
208
229
|
<div class="flex flex-col gap-2">
|
|
209
230
|
<SectionTitle
|
|
210
|
-
title="
|
|
231
|
+
title="GetAccuracy"
|
|
211
232
|
api={MS_API}
|
|
212
|
-
|
|
213
|
-
{#snippet suffix()}<span class="text-subtle-2 text-xs font-normal"
|
|
214
|
-
>(m/s<sup>2</sup>)</span
|
|
215
|
-
>{/snippet}
|
|
216
|
-
</SectionTitle>
|
|
233
|
+
/>
|
|
217
234
|
<Query
|
|
218
|
-
query={
|
|
235
|
+
query={accuracyQuery}
|
|
219
236
|
contentCx="h-6"
|
|
220
237
|
>
|
|
221
|
-
{#if
|
|
222
|
-
<
|
|
238
|
+
{#if accuracyQuery.data !== undefined}
|
|
239
|
+
<Accuracy data={accuracyQuery.data} />
|
|
223
240
|
{/if}
|
|
224
241
|
</Query>
|
|
225
242
|
</div>
|
|
226
|
-
|
|
243
|
+
</div>
|
|
227
244
|
|
|
228
|
-
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
245
|
+
{#if propertiesQuery.data?.positionSupported}
|
|
246
|
+
<Map
|
|
247
|
+
coordinate={positionQuery.data?.coordinate}
|
|
248
|
+
rotation={orientationQuery.data?.oZ}
|
|
232
249
|
/>
|
|
233
|
-
|
|
234
|
-
query={accuracyQuery}
|
|
235
|
-
contentCx="h-6"
|
|
236
|
-
>
|
|
237
|
-
{#if accuracyQuery.data !== undefined}
|
|
238
|
-
<Accuracy data={accuracyQuery.data} />
|
|
239
|
-
{/if}
|
|
240
|
-
</Query>
|
|
241
|
-
</div>
|
|
250
|
+
{/if}
|
|
242
251
|
</div>
|
|
243
|
-
|
|
244
|
-
{#if propertiesQuery.data?.positionSupported}
|
|
245
|
-
<Map
|
|
246
|
-
coordinate={positionQuery.data?.coordinate}
|
|
247
|
-
rotation={orientationQuery.data?.oZ}
|
|
248
|
-
/>
|
|
249
|
-
{/if}
|
|
250
252
|
</div>
|
|
251
253
|
</Query>
|
|
252
254
|
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
|
|
135
135
|
<ConnectionStatus {partID}>
|
|
136
136
|
{#snippet connected()}
|
|
137
|
-
<div class="flex w-full justify-between p-4">
|
|
137
|
+
<div class="flex w-full flex-wrap justify-between gap-2 p-4">
|
|
138
138
|
<RefetchController
|
|
139
139
|
{refetchInterval}
|
|
140
140
|
queries={[locationQuery, obstaclesQuery, waypointsQuery]}
|
|
@@ -152,85 +152,89 @@
|
|
|
152
152
|
</div>
|
|
153
153
|
</div>
|
|
154
154
|
|
|
155
|
-
<div class="
|
|
156
|
-
<div class="w-full
|
|
157
|
-
<
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<Tab
|
|
164
|
-
title="Waypoints"
|
|
165
|
-
selected={tab.current === 'waypoints'}
|
|
166
|
-
selectTab={() => (tab.current = 'waypoints')}
|
|
167
|
-
/>
|
|
168
|
-
</TabsBar>
|
|
169
|
-
|
|
170
|
-
<ul class="h-[calc(100%-32px)] overflow-auto">
|
|
171
|
-
{#if tab.current === 'obstacles'}
|
|
172
|
-
<ObstaclesLegend
|
|
173
|
-
{map}
|
|
174
|
-
{hovered}
|
|
175
|
-
{obstacles}
|
|
176
|
-
onEnter={setHovered}
|
|
177
|
-
onLeave={setHovered}
|
|
155
|
+
<div class="@container">
|
|
156
|
+
<div class="relative flex w-full flex-col items-stretch p-2 @2xl:h-120 @2xl:flex-row">
|
|
157
|
+
<div class="w-full p-2 @2xl:max-w-62.5">
|
|
158
|
+
<TabsBar variant="secondary">
|
|
159
|
+
<Tab
|
|
160
|
+
title="Obstacles"
|
|
161
|
+
selected={tab.current === 'obstacles'}
|
|
162
|
+
selectTab={() => (tab.current = 'obstacles')}
|
|
178
163
|
/>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
{
|
|
182
|
-
{
|
|
183
|
-
{waypoints}
|
|
184
|
-
onEnter={setHovered}
|
|
185
|
-
onLeave={setHovered}
|
|
186
|
-
onRemove={async (id) => {
|
|
187
|
-
await removeWaypointMutation.mutateAsync([id])
|
|
188
|
-
await waypointsQuery.refetch()
|
|
189
|
-
}}
|
|
164
|
+
<Tab
|
|
165
|
+
title="Waypoints"
|
|
166
|
+
selected={tab.current === 'waypoints'}
|
|
167
|
+
selectTab={() => (tab.current = 'waypoints')}
|
|
190
168
|
/>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
169
|
+
</TabsBar>
|
|
170
|
+
|
|
171
|
+
<ul class="max-h-60 overflow-auto @2xl:h-[calc(100%-32px)] @2xl:max-h-none">
|
|
172
|
+
{#if tab.current === 'obstacles'}
|
|
173
|
+
<ObstaclesLegend
|
|
174
|
+
{map}
|
|
175
|
+
{hovered}
|
|
176
|
+
{obstacles}
|
|
177
|
+
onEnter={setHovered}
|
|
178
|
+
onLeave={setHovered}
|
|
179
|
+
/>
|
|
180
|
+
{:else if tab.current === 'waypoints'}
|
|
181
|
+
<WaypointsLegend
|
|
182
|
+
{map}
|
|
183
|
+
{hovered}
|
|
184
|
+
{waypoints}
|
|
185
|
+
onEnter={setHovered}
|
|
186
|
+
onLeave={setHovered}
|
|
187
|
+
onRemove={async (id) => {
|
|
188
|
+
await removeWaypointMutation.mutateAsync([id])
|
|
189
|
+
await waypointsQuery.refetch()
|
|
190
|
+
}}
|
|
191
|
+
/>
|
|
192
|
+
{/if}
|
|
193
|
+
</ul>
|
|
194
|
+
</div>
|
|
194
195
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
196
|
+
<div class="relative h-80 @2xl:h-auto @2xl:grow">
|
|
197
|
+
<MapLibre
|
|
198
|
+
class="relative"
|
|
199
|
+
maxPitch={view === '3D' ? 60 : 0}
|
|
200
|
+
mapProvider={MapProviders.googleMaps}
|
|
201
|
+
mapProviderKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY}
|
|
202
|
+
bind:map
|
|
203
|
+
>
|
|
204
|
+
<NavigationControls showZoom={false} />
|
|
205
|
+
|
|
206
|
+
<div class="absolute top-5 right-14 z-10 flex items-center gap-2">
|
|
207
|
+
<ToggleButtons
|
|
208
|
+
options={['2D', '3D']}
|
|
209
|
+
selected={view}
|
|
210
|
+
on:input={handleViewSelect}
|
|
211
|
+
/>
|
|
212
|
+
<SatelliteControls />
|
|
213
|
+
<CenterControls />
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
{#if locationQuery.data}
|
|
217
|
+
<DirectionalMarker position={locationQuery.data} />
|
|
218
|
+
{/if}
|
|
219
|
+
|
|
220
|
+
<Waypoints
|
|
221
|
+
{waypoints}
|
|
222
|
+
{addWayPoint}
|
|
223
|
+
tab={tab.current ?? 'obstacles'}
|
|
224
|
+
{hovered}
|
|
225
|
+
/>
|
|
203
226
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
{#snippet layer()}
|
|
228
|
+
<Obstacles
|
|
229
|
+
{obstacles}
|
|
230
|
+
{hovered}
|
|
231
|
+
{setHovered}
|
|
232
|
+
{view}
|
|
233
|
+
/>
|
|
234
|
+
{/snippet}
|
|
235
|
+
</MapLibre>
|
|
212
236
|
</div>
|
|
213
|
-
|
|
214
|
-
{#if locationQuery.data}
|
|
215
|
-
<DirectionalMarker position={locationQuery.data} />
|
|
216
|
-
{/if}
|
|
217
|
-
|
|
218
|
-
<Waypoints
|
|
219
|
-
{waypoints}
|
|
220
|
-
{addWayPoint}
|
|
221
|
-
tab={tab.current ?? 'obstacles'}
|
|
222
|
-
{hovered}
|
|
223
|
-
/>
|
|
224
|
-
|
|
225
|
-
{#snippet layer()}
|
|
226
|
-
<Obstacles
|
|
227
|
-
{obstacles}
|
|
228
|
-
{hovered}
|
|
229
|
-
{setHovered}
|
|
230
|
-
{view}
|
|
231
|
-
/>
|
|
232
|
-
{/snippet}
|
|
233
|
-
</MapLibre>
|
|
237
|
+
</div>
|
|
234
238
|
</div>
|
|
235
239
|
{/snippet}
|
|
236
240
|
</ConnectionStatus>
|
|
@@ -191,78 +191,86 @@
|
|
|
191
191
|
>.
|
|
192
192
|
</div>
|
|
193
193
|
{:else}
|
|
194
|
-
<div class="
|
|
195
|
-
<div class="divide-
|
|
196
|
-
<div class="
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
194
|
+
<div class="@container">
|
|
195
|
+
<div class="flex flex-col @2xl:flex-row @2xl:divide-x">
|
|
196
|
+
<div class="divide-y">
|
|
197
|
+
<div class="m-4">
|
|
198
|
+
<RefetchController
|
|
199
|
+
{refetchInterval}
|
|
200
|
+
queries={[positionQuery, pointCloudMapQuery]}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<ApiSection
|
|
205
|
+
title="GetPosition"
|
|
206
|
+
api="rdk:service:slam"
|
|
207
|
+
>
|
|
208
|
+
<Queries
|
|
209
|
+
queries={[propertiesQuery, positionQuery]}
|
|
210
|
+
contentCx="h-6"
|
|
211
|
+
>
|
|
212
|
+
{#if positionQuery.data !== undefined}
|
|
213
|
+
<Position position={positionQuery.data} />
|
|
214
|
+
{/if}
|
|
215
|
+
</Queries>
|
|
216
|
+
</ApiSection>
|
|
217
|
+
|
|
218
|
+
<ApiSection title="Motion">
|
|
219
|
+
<Label>
|
|
220
|
+
Base name
|
|
221
|
+
|
|
222
|
+
<Input
|
|
223
|
+
slot="input"
|
|
224
|
+
bind:value={baseName}
|
|
225
|
+
/>
|
|
226
|
+
</Label>
|
|
227
|
+
<Label>
|
|
228
|
+
Motion name
|
|
229
|
+
|
|
230
|
+
<Input
|
|
231
|
+
slot="input"
|
|
232
|
+
placeholder="builtin"
|
|
233
|
+
bind:value={motionName}
|
|
234
|
+
/>
|
|
235
|
+
</Label>
|
|
236
|
+
</ApiSection>
|
|
237
|
+
|
|
238
|
+
<MoveOnMap
|
|
239
|
+
{destination}
|
|
240
|
+
{updateDestination}
|
|
241
|
+
{moveOnMap}
|
|
242
|
+
{stopPlan}
|
|
243
|
+
lastError={moveOnMapMutation.error ?? stopPlanMutation.error}
|
|
200
244
|
/>
|
|
201
245
|
</div>
|
|
202
246
|
|
|
203
|
-
<
|
|
204
|
-
title="GetPosition"
|
|
205
|
-
api="rdk:service:slam"
|
|
206
|
-
>
|
|
247
|
+
<div class="flex w-full">
|
|
207
248
|
<Queries
|
|
208
|
-
queries={[propertiesQuery, positionQuery]}
|
|
209
|
-
contentCx="h-
|
|
249
|
+
queries={[propertiesQuery, positionQuery, pointCloudMapQuery]}
|
|
250
|
+
contentCx="p-4 h-auto"
|
|
210
251
|
>
|
|
211
|
-
{#if positionQuery.data !== undefined}
|
|
212
|
-
<
|
|
252
|
+
{#if positionQuery.data?.pose !== undefined && pointCloudMapQuery.data !== undefined}
|
|
253
|
+
<div class="h-80 w-full @2xl:h-full">
|
|
254
|
+
<SlamMap2D
|
|
255
|
+
pointcloud={pointCloudMapQuery.data}
|
|
256
|
+
basePose={{
|
|
257
|
+
// Position is returned in millimeters, but the map uses meters
|
|
258
|
+
x: positionQuery.data.pose.x / 1000,
|
|
259
|
+
y: positionQuery.data.pose.y / 1000,
|
|
260
|
+
theta: positionQuery.data.pose.theta,
|
|
261
|
+
}}
|
|
262
|
+
{motionPath}
|
|
263
|
+
destination={destination
|
|
264
|
+
? new Vector2(destination.x, destination.y)
|
|
265
|
+
: undefined}
|
|
266
|
+
helpers={true}
|
|
267
|
+
onClick={handleClick}
|
|
268
|
+
/>
|
|
269
|
+
</div>
|
|
213
270
|
{/if}
|
|
214
271
|
</Queries>
|
|
215
|
-
</
|
|
216
|
-
|
|
217
|
-
<ApiSection title="Motion">
|
|
218
|
-
<Label>
|
|
219
|
-
Base name
|
|
220
|
-
|
|
221
|
-
<Input
|
|
222
|
-
slot="input"
|
|
223
|
-
bind:value={baseName}
|
|
224
|
-
/>
|
|
225
|
-
</Label>
|
|
226
|
-
<Label>
|
|
227
|
-
Motion name
|
|
228
|
-
|
|
229
|
-
<Input
|
|
230
|
-
slot="input"
|
|
231
|
-
placeholder="builtin"
|
|
232
|
-
bind:value={motionName}
|
|
233
|
-
/>
|
|
234
|
-
</Label>
|
|
235
|
-
</ApiSection>
|
|
236
|
-
|
|
237
|
-
<MoveOnMap
|
|
238
|
-
{destination}
|
|
239
|
-
{updateDestination}
|
|
240
|
-
{moveOnMap}
|
|
241
|
-
{stopPlan}
|
|
242
|
-
lastError={moveOnMapMutation.error ?? stopPlanMutation.error}
|
|
243
|
-
/>
|
|
272
|
+
</div>
|
|
244
273
|
</div>
|
|
245
|
-
|
|
246
|
-
<Queries
|
|
247
|
-
queries={[propertiesQuery, positionQuery, pointCloudMapQuery]}
|
|
248
|
-
contentCx="p-4 h-auto"
|
|
249
|
-
>
|
|
250
|
-
{#if positionQuery.data?.pose !== undefined && pointCloudMapQuery.data !== undefined}
|
|
251
|
-
<SlamMap2D
|
|
252
|
-
pointcloud={pointCloudMapQuery.data}
|
|
253
|
-
basePose={{
|
|
254
|
-
// Position is returned in millimeters, but the map uses meters
|
|
255
|
-
x: positionQuery.data.pose.x / 1000,
|
|
256
|
-
y: positionQuery.data.pose.y / 1000,
|
|
257
|
-
theta: positionQuery.data.pose.theta,
|
|
258
|
-
}}
|
|
259
|
-
{motionPath}
|
|
260
|
-
destination={destination ? new Vector2(destination.x, destination.y) : undefined}
|
|
261
|
-
helpers={true}
|
|
262
|
-
onClick={handleClick}
|
|
263
|
-
/>
|
|
264
|
-
{/if}
|
|
265
|
-
</Queries>
|
|
266
274
|
</div>
|
|
267
275
|
{/if}
|
|
268
276
|
</Query>
|