@wandelbots/wandelbots-js-react-components 4.2.0 → 4.3.0-pr.feat-RB-3171-dynamic-motion-visualization.517.0fc2fb2
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/README.md +1 -1
- package/dist/3d.cjs.js +1 -1
- package/dist/3d.es.js +1 -1
- package/dist/MotionGroupVisualizer-DptISfx-.cjs +2 -0
- package/dist/{MotionGroupVisualizer-C3CB-L2z.cjs.map → MotionGroupVisualizer-DptISfx-.cjs.map} +1 -1
- package/dist/{MotionGroupVisualizer-CrLamHYm.js → MotionGroupVisualizer-HpVtcaDR.js} +307 -343
- package/dist/{MotionGroupVisualizer-CrLamHYm.js.map → MotionGroupVisualizer-HpVtcaDR.js.map} +1 -1
- package/dist/{auth0-spa-js.production.esm-mvPojIrB.js → auth0-spa-js.production.esm-DNao6_S5.js} +1478 -1457
- package/dist/auth0-spa-js.production.esm-DNao6_S5.js.map +1 -0
- package/dist/auth0-spa-js.production.esm-DaBMfOV8.cjs +5 -0
- package/dist/auth0-spa-js.production.esm-DaBMfOV8.cjs.map +1 -0
- package/dist/components/jogging/JoggingJointTab.d.ts +1 -1
- package/dist/components/jogging/JoggingJointTab.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointValueControl.d.ts +16 -0
- package/dist/components/jogging/JoggingJointValueControl.d.ts.map +1 -0
- package/dist/components/jogging/JoggingStore.d.ts +17 -19
- package/dist/components/jogging/JoggingStore.d.ts.map +1 -1
- package/dist/components/robots/MotionGroupVisualizer.d.ts +1 -1
- package/dist/components/robots/MotionGroupVisualizer.d.ts.map +1 -1
- package/dist/core.cjs.js +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.es.js +8 -8
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +10 -10
- package/dist/interpolation-BoUHwUGn.cjs +20 -0
- package/dist/interpolation-BoUHwUGn.cjs.map +1 -0
- package/dist/{interpolation-Cs2pC1zE.js → interpolation-CQDo4nal.js} +3042 -2894
- package/dist/interpolation-CQDo4nal.js.map +1 -0
- package/dist/lib/ConnectedMotionGroup.d.ts +1 -0
- package/dist/lib/ConnectedMotionGroup.d.ts.map +1 -1
- package/dist/lib/JoggerConnection.d.ts +4 -3
- package/dist/lib/JoggerConnection.d.ts.map +1 -1
- package/dist/{theming-C-zvh022.js → theming-B0LgsoBF.js} +2915 -2891
- package/dist/theming-B0LgsoBF.js.map +1 -0
- package/dist/{theming-Dk07SE2_.cjs → theming-BfCyghaY.cjs} +36 -36
- package/dist/theming-BfCyghaY.cjs.map +1 -0
- package/package.json +2 -2
- package/src/components/jogging/JoggingJointTab.tsx +18 -18
- package/src/components/jogging/{JoggingJointRotationControl.tsx → JoggingJointValueControl.tsx} +51 -28
- package/src/components/jogging/JoggingPanel.tsx +1 -1
- package/src/components/jogging/JoggingStore.ts +42 -12
- package/src/components/robots/MotionGroupVisualizer.tsx +18 -79
- package/src/core.ts +2 -1
- package/src/lib/JoggerConnection.test.ts +4 -2
- package/src/lib/JoggerConnection.ts +8 -4
- package/dist/MotionGroupVisualizer-C3CB-L2z.cjs +0 -2
- package/dist/auth0-spa-js.production.esm-D_IhPirK.cjs +0 -5
- package/dist/auth0-spa-js.production.esm-D_IhPirK.cjs.map +0 -1
- package/dist/auth0-spa-js.production.esm-mvPojIrB.js.map +0 -1
- package/dist/components/jogging/JoggingJointRotationControl.d.ts +0 -15
- package/dist/components/jogging/JoggingJointRotationControl.d.ts.map +0 -1
- package/dist/interpolation-C5OTEwAm.cjs +0 -20
- package/dist/interpolation-C5OTEwAm.cjs.map +0 -1
- package/dist/interpolation-Cs2pC1zE.js.map +0 -1
- package/dist/theming-C-zvh022.js.map +0 -1
- package/dist/theming-Dk07SE2_.cjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0-pr.feat-RB-3171-dynamic-motion-visualization.517.0fc2fb2",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"@types/react": "^19.1.8",
|
|
94
94
|
"@types/three": "^0.182.0",
|
|
95
95
|
"@vitejs/plugin-react": "^4.3.4",
|
|
96
|
-
"@wandelbots/nova-js": "
|
|
96
|
+
"@wandelbots/nova-js": "3.5.3-pr.feat-RB-3171-dymamic-rendering.230.d40ec9a",
|
|
97
97
|
"add": "^2.0.6",
|
|
98
98
|
"eslint-plugin-storybook": "^10.1.10",
|
|
99
99
|
"glob": "^13.0.0",
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Divider, Stack, Typography, useTheme } from "@mui/material"
|
|
2
|
-
import { radiansToDegrees } from "@wandelbots/nova-js"
|
|
3
2
|
import { observer } from "mobx-react-lite"
|
|
4
3
|
import type { ReactNode } from "react"
|
|
5
4
|
import { JoggingJointLimitDetector } from "./JoggingJointLimitDetector"
|
|
6
|
-
import {
|
|
7
|
-
import type
|
|
5
|
+
import { JoggingJointValueControl } from "./JoggingJointValueControl"
|
|
6
|
+
import { type JoggingStore, JointCategory } from "./JoggingStore"
|
|
8
7
|
import { JoggingVelocitySlider } from "./JoggingVelocitySlider"
|
|
9
8
|
|
|
10
9
|
export const JoggingJointTab = observer(
|
|
@@ -12,14 +11,22 @@ export const JoggingJointTab = observer(
|
|
|
12
11
|
const theme = useTheme()
|
|
13
12
|
async function startJointJogging(opts: {
|
|
14
13
|
joint: number
|
|
15
|
-
direction: "-" | "+"
|
|
14
|
+
direction: "-" | "+",
|
|
16
15
|
}) {
|
|
17
16
|
await store.activate()
|
|
18
17
|
|
|
19
18
|
await store.jogger.rotateJoints({
|
|
20
19
|
joint: opts.joint,
|
|
21
20
|
direction: opts.direction,
|
|
22
|
-
|
|
21
|
+
velocityUnit:
|
|
22
|
+
store.jointCategory === JointCategory.PRISMATIC
|
|
23
|
+
? "mm/s"
|
|
24
|
+
: "rad/s",
|
|
25
|
+
velocityValue:
|
|
26
|
+
store.jointCategory === JointCategory.PRISMATIC
|
|
27
|
+
? store.translationVelocityMmPerSec
|
|
28
|
+
: store.rotationVelocityRadsPerSec,
|
|
29
|
+
|
|
23
30
|
})
|
|
24
31
|
}
|
|
25
32
|
|
|
@@ -43,14 +50,6 @@ export const JoggingJointTab = observer(
|
|
|
43
50
|
const jointLimits =
|
|
44
51
|
store.motionGroupDescription.operation_limits.auto_limits
|
|
45
52
|
?.joints?.[joint.index]?.position
|
|
46
|
-
const lowerLimitDegs =
|
|
47
|
-
jointLimits?.lower_limit !== undefined
|
|
48
|
-
? radiansToDegrees(jointLimits.lower_limit)
|
|
49
|
-
: undefined
|
|
50
|
-
const upperLimitDegs =
|
|
51
|
-
jointLimits?.upper_limit !== undefined
|
|
52
|
-
? radiansToDegrees(jointLimits.upper_limit)
|
|
53
|
-
: undefined
|
|
54
53
|
|
|
55
54
|
return (
|
|
56
55
|
<Stack
|
|
@@ -73,16 +72,17 @@ export const JoggingJointTab = observer(
|
|
|
73
72
|
</Typography>
|
|
74
73
|
)}
|
|
75
74
|
|
|
76
|
-
<
|
|
75
|
+
<JoggingJointValueControl
|
|
77
76
|
disabled={store.isLocked}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
lowerLimit={jointLimits?.lower_limit}
|
|
78
|
+
upperLimit={jointLimits?.upper_limit}
|
|
79
|
+
useDegree={store.currentMotionType === "rotate"}
|
|
80
|
+
getValue={() => {
|
|
81
81
|
const value =
|
|
82
82
|
store.jogger.motionStream.rapidlyChangingMotionState
|
|
83
83
|
.joint_position[joint.index]
|
|
84
84
|
return value !== undefined
|
|
85
|
-
?
|
|
85
|
+
? value
|
|
86
86
|
: undefined
|
|
87
87
|
}}
|
|
88
88
|
startJogging={(direction: "-" | "+") =>
|
package/src/components/jogging/{JoggingJointRotationControl.tsx → JoggingJointValueControl.tsx}
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ChevronLeft from "@mui/icons-material/ChevronLeft"
|
|
2
2
|
import ChevronRight from "@mui/icons-material/ChevronRight"
|
|
3
|
+
import { radiansToDegrees } from "@wandelbots/nova-js"
|
|
3
4
|
import { IconButton, Slider, Typography, useTheme } from "@mui/material"
|
|
4
5
|
import Stack from "@mui/material/Stack"
|
|
5
6
|
import throttle from "lodash-es/throttle"
|
|
@@ -9,28 +10,29 @@ import { useTranslation } from "react-i18next"
|
|
|
9
10
|
import { externalizeComponent } from "../../externalizeComponent"
|
|
10
11
|
import { useAnimationFrame } from "../utils/hooks"
|
|
11
12
|
|
|
12
|
-
type
|
|
13
|
+
type JoggingJointValueControlProps = {
|
|
13
14
|
startJogging: (direction: "-" | "+") => void
|
|
14
15
|
stopJogging: () => void
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
lowerLimit?: number
|
|
17
|
+
upperLimit?: number
|
|
18
|
+
useDegree: boolean
|
|
19
|
+
getValue: () => number | undefined
|
|
19
20
|
disabled?: boolean
|
|
20
21
|
} & React.ComponentProps<typeof Stack>
|
|
21
22
|
|
|
22
23
|
/** A input widget to control an individual joint */
|
|
23
|
-
export const
|
|
24
|
+
export const JoggingJointValueControl = externalizeComponent(
|
|
24
25
|
observer(
|
|
25
26
|
({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
startJogging,
|
|
28
|
+
stopJogging,
|
|
29
|
+
lowerLimit,
|
|
30
|
+
upperLimit,
|
|
31
|
+
useDegree,
|
|
32
|
+
getValue,
|
|
33
|
+
disabled,
|
|
34
|
+
...rest
|
|
35
|
+
}: JoggingJointValueControlProps) => {
|
|
34
36
|
const { t } = useTranslation()
|
|
35
37
|
const [currentValue, setCurrentValue] = useState<number | undefined>()
|
|
36
38
|
const theme = useTheme()
|
|
@@ -55,11 +57,18 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
55
57
|
}))
|
|
56
58
|
|
|
57
59
|
const updateValue = throttle(() => {
|
|
58
|
-
setCurrentValue(
|
|
60
|
+
setCurrentValue(useDegree ? convertToDegree(getValue()) : getValue())
|
|
59
61
|
}, 50)
|
|
60
62
|
|
|
61
63
|
useAnimationFrame(updateValue)
|
|
62
64
|
|
|
65
|
+
function convertToDegree(value: number| undefined){
|
|
66
|
+
if (value == undefined){
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return radiansToDegrees(value);
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
function onPointerDownMinus(ev: React.PointerEvent) {
|
|
64
73
|
// Stop right click from triggering jog
|
|
65
74
|
if (ev.button === 0) state.startJogging("-")
|
|
@@ -90,6 +99,20 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
90
99
|
return output
|
|
91
100
|
}
|
|
92
101
|
}
|
|
102
|
+
function formatMm(value: number | undefined, precision = 1) {
|
|
103
|
+
if (value === undefined || isNaN(value)) return ""
|
|
104
|
+
|
|
105
|
+
const output = t("General.mm.variable", {
|
|
106
|
+
amount: value.toFixed(precision),
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
if (value > 0 && precision === 0) {
|
|
110
|
+
return `+${output}`
|
|
111
|
+
} else {
|
|
112
|
+
return output
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
93
116
|
|
|
94
117
|
return (
|
|
95
118
|
<Stack
|
|
@@ -138,8 +161,8 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
138
161
|
sx={{
|
|
139
162
|
pointerEvents: "none",
|
|
140
163
|
color:
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
theme.componentsExt?.JoggingPanel?.JoggingJoint?.Joint
|
|
165
|
+
?.arrowColor,
|
|
143
166
|
}}
|
|
144
167
|
/>
|
|
145
168
|
</IconButton>
|
|
@@ -171,14 +194,14 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
171
194
|
: theme.palette.text.primary,
|
|
172
195
|
}}
|
|
173
196
|
>
|
|
174
|
-
{formatDegrees(currentValue)}
|
|
197
|
+
{useDegree ? formatDegrees(currentValue) : formatMm(currentValue)}
|
|
175
198
|
</Typography>
|
|
176
199
|
|
|
177
200
|
<Slider
|
|
178
201
|
disabled
|
|
179
202
|
aria-label="Joint position"
|
|
180
|
-
min={
|
|
181
|
-
max={
|
|
203
|
+
min={ useDegree ? convertToDegree(lowerLimit) : lowerLimit}
|
|
204
|
+
max={ useDegree ? convertToDegree(upperLimit) : upperLimit}
|
|
182
205
|
value={currentValue || 0}
|
|
183
206
|
track={false}
|
|
184
207
|
sx={{
|
|
@@ -206,15 +229,15 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
206
229
|
},
|
|
207
230
|
}}
|
|
208
231
|
marks={
|
|
209
|
-
|
|
210
|
-
|
|
232
|
+
lowerLimit !== undefined &&
|
|
233
|
+
upperLimit !== undefined && [
|
|
211
234
|
{
|
|
212
|
-
value:
|
|
213
|
-
label: formatDegrees(
|
|
235
|
+
value: (useDegree ? convertToDegree(lowerLimit) : lowerLimit) as number,
|
|
236
|
+
label: useDegree ? formatDegrees(convertToDegree(lowerLimit),0) : formatMm(lowerLimit),
|
|
214
237
|
},
|
|
215
238
|
{
|
|
216
|
-
value:
|
|
217
|
-
label: formatDegrees(
|
|
239
|
+
value: (useDegree ? convertToDegree(upperLimit) : upperLimit) as number,
|
|
240
|
+
label: useDegree ? formatDegrees(convertToDegree(upperLimit),0) : formatMm(upperLimit),
|
|
218
241
|
},
|
|
219
242
|
]
|
|
220
243
|
}
|
|
@@ -236,8 +259,8 @@ export const JoggingJointRotationControl = externalizeComponent(
|
|
|
236
259
|
sx={{
|
|
237
260
|
pointerEvents: "none",
|
|
238
261
|
color:
|
|
239
|
-
|
|
240
|
-
|
|
262
|
+
theme.componentsExt?.JoggingPanel?.JoggingJoint?.Joint
|
|
263
|
+
?.arrowColor,
|
|
241
264
|
}}
|
|
242
265
|
/>
|
|
243
266
|
</IconButton>
|
|
@@ -40,8 +40,16 @@ export type IncrementJogInProgress = {
|
|
|
40
40
|
axis: JoggingAxis
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
export enum JointCategory {
|
|
44
|
+
REVOLUTE = "REVOLUTE",
|
|
45
|
+
PRISMATIC = "PRISMATIC",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type TabType = "cartesian" | "joint" | "debug";
|
|
49
|
+
|
|
50
|
+
|
|
43
51
|
export class JoggingStore {
|
|
44
|
-
selectedTabId:
|
|
52
|
+
selectedTabId: TabType = "cartesian";
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
55
|
* State of the jogging panel. Starts as "inactive"
|
|
@@ -298,18 +306,20 @@ export class JoggingStore {
|
|
|
298
306
|
}
|
|
299
307
|
|
|
300
308
|
get tabs() {
|
|
301
|
-
|
|
302
|
-
|
|
309
|
+
const tempTabs : {id: TabType, label: string}[] = [{
|
|
310
|
+
id: "joint",
|
|
311
|
+
label: "Joints",
|
|
312
|
+
}] ;
|
|
313
|
+
if(this.isTcpCartesianMoveable){
|
|
314
|
+
tempTabs.unshift({
|
|
303
315
|
id: "cartesian",
|
|
304
|
-
label: "
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
label: "joint",
|
|
309
|
-
},
|
|
310
|
-
] as const
|
|
316
|
+
label: "Cartesian",
|
|
317
|
+
})}
|
|
318
|
+
|
|
319
|
+
return tempTabs;
|
|
311
320
|
}
|
|
312
321
|
|
|
322
|
+
|
|
313
323
|
get incrementOptions() {
|
|
314
324
|
return incrementOptions
|
|
315
325
|
}
|
|
@@ -395,8 +405,10 @@ export class JoggingStore {
|
|
|
395
405
|
*/
|
|
396
406
|
get currentMotionType() {
|
|
397
407
|
if (
|
|
398
|
-
|
|
399
|
-
|
|
408
|
+
(
|
|
409
|
+
this.selectedTabId === "cartesian" &&
|
|
410
|
+
this.selectedCartesianMotionType === "translate"
|
|
411
|
+
) || this.jointCategory === JointCategory.PRISMATIC
|
|
400
412
|
) {
|
|
401
413
|
return "translate"
|
|
402
414
|
} else {
|
|
@@ -404,6 +416,24 @@ export class JoggingStore {
|
|
|
404
416
|
}
|
|
405
417
|
}
|
|
406
418
|
|
|
419
|
+
|
|
420
|
+
/*
|
|
421
|
+
* ToDo replace Hardcoded Models with an api request that delivers the type (will become part of DH-Parameters)
|
|
422
|
+
* Ticket already created
|
|
423
|
+
* */
|
|
424
|
+
get jointCategory(): JointCategory {
|
|
425
|
+
return this.motionGroupDescription.motion_group_model === "ABB_IRT710"
|
|
426
|
+
? JointCategory.PRISMATIC
|
|
427
|
+
: JointCategory.REVOLUTE
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
get isTcpCartesianMoveable(): boolean{
|
|
431
|
+
if(this.motionGroupDescription.motion_group_model === "ABB_IRT710"){
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
|
|
407
437
|
onTabChange(_event: React.SyntheticEvent, newValue: number) {
|
|
408
438
|
const tab = this.tabs[newValue] || this.tabs[0]!
|
|
409
439
|
this.selectedTabId = tab.id
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import {
|
|
3
|
-
import type { KinematicModel } from "@wandelbots/nova-api/v2"
|
|
1
|
+
import React, { useEffect, useMemo, useState } from "react"
|
|
2
|
+
import { JointTypeEnum } from "@wandelbots/nova-js/v2"
|
|
4
3
|
|
|
5
4
|
import { externalizeComponent } from "../../externalizeComponent"
|
|
6
5
|
import { SupportedRobot, type SupportedRobotProps } from "./SupportedRobot"
|
|
@@ -8,106 +7,46 @@ import { SupportedLinearAxis, type SupportedLinearAxisProps } from "./SupportedL
|
|
|
8
7
|
|
|
9
8
|
export type MotionGroupVisualizerProps = {
|
|
10
9
|
instanceUrl: string
|
|
11
|
-
inverseSolver
|
|
10
|
+
inverseSolver: string | null
|
|
12
11
|
} & (SupportedRobotProps | SupportedLinearAxisProps)
|
|
13
12
|
|
|
14
13
|
export const MotionGroupVisualizer: React.FC<MotionGroupVisualizerProps> = externalizeComponent((props: MotionGroupVisualizerProps) => {
|
|
15
14
|
const {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
modelFromController,
|
|
15
|
+
inverseSolver,
|
|
16
|
+
dhParameters,
|
|
19
17
|
...rest
|
|
20
18
|
} = props
|
|
21
19
|
|
|
22
|
-
const [inverseSolver, setInverseSolver] = useState<string | null | undefined>(
|
|
23
|
-
inverseSolverProp,
|
|
24
|
-
)
|
|
25
|
-
const [, forceThreeRerender] = useState<boolean>(false)
|
|
26
|
-
|
|
27
20
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
21
|
+
* Joint type to find out - in combination with inverseSolver - whether the
|
|
22
|
+
* active robot is a turn table
|
|
30
23
|
*/
|
|
31
|
-
const
|
|
32
|
-
const nova = new NovaClient({ instanceUrl })
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const kinematicModel: KinematicModel =
|
|
36
|
-
await nova.api.motionGroupModels.getMotionGroupKinematicModel(
|
|
37
|
-
modelFromController,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
setInverseSolver(kinematicModel.inverse_solver)
|
|
41
|
-
} catch (err) {
|
|
42
|
-
console.warn(
|
|
43
|
-
`Failed to fetch kinematic model from API for ${modelFromController}, falling back to local config`,
|
|
44
|
-
)
|
|
45
|
-
} finally {
|
|
46
|
-
/**
|
|
47
|
-
* The following is a workaround to force a rerender of the Three.js scene, due
|
|
48
|
-
* to a race condition (if the component gets re-initialized, the robot
|
|
49
|
-
* is rendered with the initial joint position). The forceThreeRerender tells
|
|
50
|
-
* the Three.JS to re-render with the right joint position
|
|
51
|
-
*
|
|
52
|
-
* TODO remove the three rerender function and get rid of the
|
|
53
|
-
* stale state condition
|
|
54
|
-
* https://wandelbots.atlassian.net/browse/RB-3134
|
|
55
|
-
*/
|
|
56
|
-
setTimeout(() => forceThreeRerender(true), 0)
|
|
57
|
-
}
|
|
58
|
-
}, [modelFromController, instanceUrl])
|
|
24
|
+
const [jointType, setJointType] = useState<JointTypeEnum>(JointTypeEnum.RevoluteJoint)
|
|
59
25
|
|
|
60
26
|
/**
|
|
61
|
-
*
|
|
62
|
-
* Defined, Null - carry on with the delivered value - the inverseSolver was fetched via consumer app
|
|
63
|
-
* Undefined - carry out a request to fetch the inverseSolver value
|
|
27
|
+
* Sets the joint type according to delivered dh parameter type
|
|
64
28
|
*/
|
|
65
29
|
useEffect(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (shouldKinematicBeFetched) {
|
|
70
|
-
fetchKinematicModel()
|
|
30
|
+
if (dhParameters?.length) {
|
|
31
|
+
setJointType(dhParameters[0]?.type ?? JointTypeEnum.RevoluteJoint)
|
|
71
32
|
}
|
|
72
|
-
}, [
|
|
33
|
+
}, [dhParameters])
|
|
73
34
|
|
|
74
35
|
/**
|
|
75
36
|
* The turntable models return inverseSolver = null - however these models
|
|
76
37
|
* should be rendered with SupportedRobot instead of SupportedLinearAxis
|
|
77
|
-
*
|
|
78
|
-
* TODO
|
|
79
|
-
* In the future - this hard coded check would be replaced with a new "type" property
|
|
80
|
-
* from dh parameters
|
|
81
38
|
*/
|
|
82
39
|
const isTurnTable = useMemo(() => {
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
"KUKA_DKP500_2",
|
|
86
|
-
"YASKAWA_TURN1",
|
|
87
|
-
"YASKAWA_TURN2",
|
|
88
|
-
"YASKAWA_TURN3",
|
|
89
|
-
].includes(modelFromController)
|
|
90
|
-
}, [modelFromController])
|
|
40
|
+
return !inverseSolver && jointType === "REVOLUTE_JOINT"
|
|
41
|
+
}, [inverseSolver, jointType])
|
|
91
42
|
|
|
92
43
|
if (inverseSolver || isTurnTable) {
|
|
93
44
|
return (
|
|
94
|
-
<SupportedRobot
|
|
95
|
-
instanceUrl={instanceUrl}
|
|
96
|
-
modelFromController={modelFromController}
|
|
97
|
-
{...rest}
|
|
98
|
-
/>
|
|
45
|
+
<SupportedRobot dhParameters={dhParameters} {...rest} />
|
|
99
46
|
)
|
|
100
47
|
}
|
|
101
48
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
instanceUrl={instanceUrl}
|
|
106
|
-
modelFromController={modelFromController}
|
|
107
|
-
{...rest}
|
|
108
|
-
/>
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return null
|
|
49
|
+
return (
|
|
50
|
+
<SupportedLinearAxis dhParameters={dhParameters} {...rest} />
|
|
51
|
+
)
|
|
113
52
|
})
|
package/src/core.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./components/AppHeader"
|
|
|
3
3
|
export * from "./components/CycleTimer"
|
|
4
4
|
export * from "./components/DataGrid"
|
|
5
5
|
export * from "./components/jogging/JoggingCartesianAxisControl"
|
|
6
|
-
export * from "./components/jogging/
|
|
6
|
+
export * from "./components/jogging/JoggingJointValueControl"
|
|
7
7
|
export * from "./components/jogging/JoggingPanel"
|
|
8
8
|
export { JoggingStore } from "./components/jogging/JoggingStore"
|
|
9
9
|
export * from "./components/jogging/PoseCartesianValues"
|
|
@@ -31,3 +31,4 @@ export * from "./lib/motionStateUpdate"
|
|
|
31
31
|
export * from "./lib/MotionStreamConnection"
|
|
32
32
|
export * from "./themes/themeTypes"
|
|
33
33
|
export { createNovaMuiTheme } from "./themes/theming"
|
|
34
|
+
|
|
@@ -77,7 +77,8 @@ test("jog a robot somewhat", async () => {
|
|
|
77
77
|
await jogger.rotateJoints({
|
|
78
78
|
joint: 0,
|
|
79
79
|
direction: "+",
|
|
80
|
-
|
|
80
|
+
velocityValue: 0.1,
|
|
81
|
+
velocityUnit: "rad/s",
|
|
81
82
|
})
|
|
82
83
|
|
|
83
84
|
await delay(500)
|
|
@@ -94,7 +95,8 @@ test("jog a robot somewhat", async () => {
|
|
|
94
95
|
await jogger.rotateJoints({
|
|
95
96
|
joint: 0,
|
|
96
97
|
direction: "-",
|
|
97
|
-
|
|
98
|
+
velocityValue: 0.1,
|
|
99
|
+
velocityUnit: "rad/s",
|
|
98
100
|
})
|
|
99
101
|
await delay(500)
|
|
100
102
|
await jogger.stop()
|
|
@@ -282,14 +282,18 @@ export class JoggerConnection {
|
|
|
282
282
|
async rotateJoints({
|
|
283
283
|
joint,
|
|
284
284
|
direction,
|
|
285
|
-
|
|
285
|
+
velocityValue,
|
|
286
|
+
velocityUnit
|
|
287
|
+
|
|
286
288
|
}: {
|
|
287
289
|
/** Index of the joint to rotate */
|
|
288
290
|
joint: number
|
|
289
291
|
/** Direction of rotation ("+" or "-") */
|
|
290
292
|
direction: "+" | "-"
|
|
291
|
-
/** Speed of the rotation
|
|
292
|
-
|
|
293
|
+
/** Speed of the rotation, unit is currently unused, but i wanted it there to raise awareness that not everything here is rad/s*/
|
|
294
|
+
velocityValue: number
|
|
295
|
+
velocityUnit: "mm/s" | "rad/s"
|
|
296
|
+
|
|
293
297
|
}) {
|
|
294
298
|
if (!this.joggingSocket || this.mode !== "jogging") {
|
|
295
299
|
throw new Error(
|
|
@@ -300,7 +304,7 @@ export class JoggerConnection {
|
|
|
300
304
|
const velocity = new Array(this.numJoints).fill(0)
|
|
301
305
|
|
|
302
306
|
velocity[joint] =
|
|
303
|
-
direction === "-" ? -
|
|
307
|
+
direction === "-" ? - velocityValue : velocityValue
|
|
304
308
|
|
|
305
309
|
this.joggingSocket.sendJson({
|
|
306
310
|
message_type: "JointVelocityRequest",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const t=require("./externalizeComponent-CkVWk2F_.cjs"),g=require("three"),K=require("three-stdlib"),_=require("@react-three/fiber"),M=require("@react-three/drei"),y=require("@mui/material"),ae=require("mobx-react-lite"),p=require("react"),ue=require("react-i18next"),E=require("./interpolation-C5OTEwAm.cjs"),N=require("react-error-boundary");function ce(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,s.get?s:{enumerable:!0,get:()=>e[r]})}}return n.default=e,Object.freeze(n)}const j=ce(g);function le(e){switch(e.shape_type){case"convex_hull":return new K.ConvexGeometry(e.vertices.map(r=>new j.Vector3(r[0]/1e3,r[1]/1e3,r[2]/1e3)));case"box":return new j.BoxGeometry(e.size_x/1e3,e.size_y/1e3,e.size_z/1e3);case"sphere":return new j.SphereGeometry(e.radius/1e3);case"capsule":return new j.CapsuleGeometry(e.radius/1e3,e.cylinder_height/1e3);case"cylinder":return new j.CylinderGeometry(e.radius/1e3,e.radius/1e3,e.height/1e3);case"rectangle":return new j.BoxGeometry(e.size_x/1e3,e.size_y/1e3,0);default:return console.warn(`${e.shape_type} is not supported`),new j.BufferGeometry}}function xe({name:e,collider:n,children:r}){var l,a;const s=((l=n.pose)==null?void 0:l.position)??[0,0,0],o=((a=n.pose)==null?void 0:a.orientation)??[0,0,0];return n.margin&&console.warn(`${e} margin is not supported`),t.jsxRuntimeExports.jsx("mesh",{name:e,position:new j.Vector3(s[0],s[1],s[2]).divideScalar(1e3),rotation:new j.Euler(o[0],o[1],o[2],"XYZ"),geometry:le(n.shape),children:r})}function me({name:e,colliders:n,meshChildrenProvider:r,...s}){return t.jsxRuntimeExports.jsx("group",{name:e,...s,children:Object.entries(n).map(([o,l])=>t.jsxRuntimeExports.jsx(xe,{name:o,collider:l,children:r(o,l)},o))})}function pe({scene:e,meshChildrenProvider:n}){const r=e.colliders;return t.jsxRuntimeExports.jsx("group",{children:r&&t.jsxRuntimeExports.jsx(me,{meshChildrenProvider:n,colliders:r})})}function F(){return t.jsxRuntimeExports.jsx(M.Environment,{children:t.jsxRuntimeExports.jsx(fe,{})})}function fe({positions:e=[2,0,2,0,2,0,2,0]}){return t.jsxRuntimeExports.jsxs(t.jsxRuntimeExports.Fragment,{children:[t.jsxRuntimeExports.jsx(M.Lightformer,{intensity:5,"rotation-x":Math.PI/2,position:[0,5,-9],scale:[10,10,1]}),t.jsxRuntimeExports.jsx("group",{rotation:[0,.5,0],children:t.jsxRuntimeExports.jsx("group",{children:e.map((n,r)=>t.jsxRuntimeExports.jsx(M.Lightformer,{form:"circle",intensity:5,rotation:[Math.PI/2,0,0],position:[n,4,r*4],scale:[3,1,1]},r))})}),t.jsxRuntimeExports.jsx(M.Lightformer,{intensity:40,"rotation-y":Math.PI/2,position:[-5,1,-1],scale:[20,.1,1]}),t.jsxRuntimeExports.jsx(M.Lightformer,{intensity:20,"rotation-y":-Math.PI,position:[-5,-2,-1],scale:[20,.1,1]}),t.jsxRuntimeExports.jsx(M.Lightformer,{"rotation-y":Math.PI/2,position:[-5,-1,-1],scale:[20,.5,1],intensity:5}),t.jsxRuntimeExports.jsx(M.Lightformer,{"rotation-y":-Math.PI/2,position:[10,1,0],scale:[20,1,1],intensity:10}),t.jsxRuntimeExports.jsx(M.Lightformer,{form:"ring",color:"white",intensity:5,scale:10,position:[-15,4,-18],target:[0,0,0]})]})}function de(e){if(e.length<3)return console.log("Not enough vertices to define a plane"),{isCoplanar:!1};const n=new j.Vector3(e[0].x,e[0].y,e[0].z),r=new j.Vector3(e[1].x,e[1].y,e[1].z),s=new j.Vector3(e[2].x,e[2].y,e[2].z),o=new j.Vector3().subVectors(r,n),l=new j.Vector3().subVectors(s,n),a=new j.Vector3().crossVectors(o,l).normalize();for(let x=3;x<e.length;x++){const u=new j.Vector3(e[x].x,e[x].y,e[x].z),m=new j.Vector3().subVectors(u,n),f=a.dot(m);if(Math.abs(f)>1e-6)return console.log("Vertices are not on the same plane"),{isCoplanar:!1}}return{isCoplanar:!0,normal:a}}function he({safetyZones:e,...n}){return t.jsxRuntimeExports.jsx("group",{...n,children:e.map((r,s)=>{let o=[];return r.geometry&&(r.geometry.compound?o=r.geometry.compound.child_geometries:r.geometry.convex_hull&&(o=[r.geometry])),o.map((l,a)=>{if(!l.convex_hull)return null;const x=l.convex_hull.vertices.map(f=>new j.Vector3(f.x/1e3,f.y/1e3,f.z/1e3)),u=de(x);if(u.isCoplanar&&u.normal){const i=new j.Vector3().addVectors(x[0],u.normal.multiplyScalar(1e-4));x.push(i)}let m;try{m=new K.ConvexGeometry(x)}catch(f){return console.log("Error creating ConvexGeometry:",f),null}return t.jsxRuntimeExports.jsx("mesh",{geometry:m,children:t.jsxRuntimeExports.jsx("meshStandardMaterial",{attach:"material",color:"#009f4d",opacity:.2,depthTest:!1,depthWrite:!1,transparent:!0,polygonOffset:!0,polygonOffsetFactor:-a},s)},`${s}-${a}`)})})})}function je({trajectory:e,...n}){var s;const r=((s=e.trajectory)==null?void 0:s.map(o=>o.tcp_pose?new j.Vector3(o.tcp_pose.position.x/1e3,o.tcp_pose.position.z/1e3,-o.tcp_pose.position.y/1e3):null).filter(o=>o!==null))||[];return t.jsxRuntimeExports.jsx("group",{...n,children:r.length>0&&t.jsxRuntimeExports.jsx(M.Line,{points:r,lineWidth:3,polygonOffset:!0,polygonOffsetFactor:10,polygonOffsetUnits:10})})}const G=new Map;async function S(e,n){if(G.has(e))return G.get(e);const r=(async()=>{var a;const s=n||"",o=new E.NovaClient({instanceUrl:s}),l=o.api.motionGroupModels;(a=l.axios)!=null&&a.interceptors&&l.axios.interceptors.request.use(x=>{var u;return(u=x.url)!=null&&u.includes("/glb")&&(x.responseType="blob"),x});try{const x=await o.api.motionGroupModels.getMotionGroupGlbModel(e);return URL.createObjectURL(x)}catch(x){throw console.error("Failed to fetch model:",x),x}})();return G.set(e,r),r}function $(e){function n(r){return r.children.length===0?[r]:[r,...r.children.flatMap(s=>n(s))]}return n(e).filter(r=>J(r))}function H(e){return e.name.endsWith("_FLG")}function J(e){return/_J[0-9]+$/.test(e.name)}function Re(e,n){let r;function s(o){if(H(o)){if(r)throw Error(`Found multiple flange groups in robot model ${n}; first ${r.name} then ${o.name}. Only one _FLG group is allowed.`);r=o}J(o),o.children.map(s)}if(s(e.scene),!r)throw Error(`No flange group found in robot model ${n}. Flange must be identified with a name ending in _FLG.`);return{gltf:e}}function Y({rapidlyChangingMotionState:e,dhParameters:n,onRotationChanged:r,children:s}){const o=p.useRef([]),l=p.useRef([]),a=p.useRef(null),{invalidate:x}=_.useThree();p.useEffect(()=>{const i=e.joint_position.filter(c=>c!==void 0);return a.current=new E.ValueInterpolator(i,{tension:120,friction:20,threshold:.001}),()=>{var c;(c=a.current)==null||c.destroy()}},[]),_.useFrame((i,c)=>{if(a.current){const d=a.current.update(c);m(),d||x()}});function u(i){i&&(l.current=$(i),m(),x())}function m(){var c;const i=((c=a.current)==null?void 0:c.getCurrentValues())||[];if(r)r(l.current,i);else for(const[d,R]of l.current.entries()){const h=n[d],w=h.theta||0,b=h.reverse_rotation_direction?-1:1;R.rotation.y=b*(i[d]||0)+w}}const f=p.useCallback(()=>{const i=e.joint_position.filter(c=>c!==void 0);requestAnimationFrame(()=>{var c;o.current=i,(c=a.current)==null||c.setTarget(i)})},[e]);return p.useEffect(()=>{f()},[e,f]),E.useAutorun(()=>{f()}),t.jsxRuntimeExports.jsx("group",{ref:u,children:s})}const ge="line",ye="mesh";function Ee({rapidlyChangingMotionState:e,dhParameters:n,...r}){const s=new g.Matrix4,o=p.useRef([]),l=p.useRef([]);p.useEffect(()=>{o.current=new Array(n.length).fill(null),l.current=new Array(n.length).fill(null)},[n.length]);function a(m,f){const i=new g.Vector3,c=new g.Quaternion,d=new g.Vector3;s.decompose(i,c,d);const R=i.clone(),h=new g.Matrix4().makeRotationY(m.theta+f*(m.reverse_rotation_direction?-1:1)).multiply(new g.Matrix4().makeTranslation(0,m.d/1e3,0)).multiply(new g.Matrix4().makeTranslation(m.a/1e3,0,0)).multiply(new g.Matrix4().makeRotationX(m.alpha));return s.multiply(h),s.decompose(i,c,d),{a:R,b:i}}function x(m,f,i,c){if(!n)return;const d=n[m];if(!d)return;const{a:R,b:h}=a(d,c);f.geometry.setPositions([R.toArray(),h.toArray()].flat()),i.position.set(h.x,h.y,h.z)}function u(m,f){s.identity();for(let i=0;i<Math.min(m.length,f.length);i++){const c=o.current[i],d=l.current[i];c&&d&&x(i,c,d,f[i])}}return t.jsxRuntimeExports.jsx(t.jsxRuntimeExports.Fragment,{children:t.jsxRuntimeExports.jsx(Y,{rapidlyChangingMotionState:e,dhParameters:n,onRotationChanged:u,children:t.jsxRuntimeExports.jsxs("group",{...r,name:"Scene",children:[t.jsxRuntimeExports.jsxs("mesh",{children:[t.jsxRuntimeExports.jsx("sphereGeometry",{args:[.01,32,32]}),t.jsxRuntimeExports.jsx("meshStandardMaterial",{color:"black",depthTest:!0})]}),n.map((m,f)=>{const{a:i,b:c}=a(m,e.joint_position[f]??0),d=`dhrobot_J0${f}`;return t.jsxRuntimeExports.jsxs("group",{name:d,children:[t.jsxRuntimeExports.jsx(M.Line,{ref:R=>{o.current[f]=R},name:ge,points:[i,c],color:"white",lineWidth:5}),t.jsxRuntimeExports.jsxs("mesh",{ref:R=>{l.current[f]=R},name:ye,position:c,children:[t.jsxRuntimeExports.jsx("sphereGeometry",{args:[.01,32,32]}),t.jsxRuntimeExports.jsx("meshStandardMaterial",{color:"black",depthTest:!0})]},"mesh_"+f)]},d)})]})})})}const be=console.warn;function X(){return p.useEffect(()=>{console.warn=e=>{e!=="Cannot call the manual advancement of rafz whilst frameLoop is not set as demand"&&be(e)}},[]),t.jsxRuntimeExports.jsx(t.jsxRuntimeExports.Fragment,{})}function we(e){return e.type==="Mesh"}function Me({url:e,flangeRef:n,postModelRender:r,...s}){const o=M.useGLTF(e);let l;try{l=Re(o,"robot.glb").gltf}catch(u){throw u}const a=p.useCallback(u=>{u&&r&&r()},[r]);function x(u){try{return we(u)?u.geometry?t.jsxRuntimeExports.jsx("mesh",{name:u.name,geometry:u.geometry,material:u.material,position:u.position,rotation:u.rotation},u.uuid):t.jsxRuntimeExports.jsx("group",{name:u.name,position:u.position,rotation:u.rotation},u.uuid):t.jsxRuntimeExports.jsx("group",{name:u.name,position:u.position,rotation:u.rotation,ref:H(u)?n:void 0,children:u.children.map(x)},u.uuid)}catch(m){return console.warn("Error rendering node",u.name,m),null}}return t.jsxRuntimeExports.jsx("group",{...s,dispose:null,ref:a,children:x(l.scene)})}function Q({modelURL:e,flangeRef:n,postModelRender:r,...s}){const[o,l]=p.useState(null);return p.useEffect(()=>{(async()=>{try{if(typeof e=="string")l(e);else{const x=await e;l(x)}}catch(x){console.error("Failed to resolve model URL:",x)}})()},[e]),o?t.jsxRuntimeExports.jsx(Me,{url:o,flangeRef:n,postModelRender:r,...s}):null}const Z=(e,n)=>{e.userData.isGhost||(e.traverse(r=>{if(r instanceof j.Mesh){r.material instanceof j.Material&&(r.material.colorWrite=!1);const s=r.clone(),o=r.clone();s.material=new j.MeshStandardMaterial({depthTest:!0,depthWrite:!0,colorWrite:!1,polygonOffset:!0,polygonOffsetFactor:-1,side:j.DoubleSide}),s.userData.isGhost=!0,o.material=new j.MeshStandardMaterial({color:n,opacity:.3,depthTest:!0,depthWrite:!1,transparent:!0,polygonOffset:!0,polygonOffsetFactor:-2,side:j.DoubleSide}),o.userData.isGhost=!0,r.parent&&(r.parent.add(s),r.parent.add(o))}}),e.userData.isGhost=!0)},ee=e=>{if(!e.userData.isGhost)return;const n=[];e.traverse(r=>{var s;r instanceof j.Mesh&&((s=r.userData)!=null&&s.isGhost?n.push(r):r.material instanceof j.Material&&(r.material.colorWrite=!0))}),n.forEach(r=>{r.parent&&r.parent.remove(r)}),e.userData.isGhost=!1},I=t.externalizeComponent(({rapidlyChangingMotionState:e,modelFromController:n,dhParameters:r,getModel:s=S,flangeRef:o,postModelRender:l,transparentColor:a,instanceUrl:x,...u})=>{const[m,f]=p.useState(null),i=p.useCallback(d=>{f(d)},[]);p.useEffect(()=>{m&&(a?Z(m,a):ee(m))},[m,a]);const c=t.jsxRuntimeExports.jsx(Ee,{rapidlyChangingMotionState:e,dhParameters:r,...u});return t.jsxRuntimeExports.jsxs(N.ErrorBoundary,{fallback:c,onError:d=>{console.warn(d)},children:[t.jsxRuntimeExports.jsx(p.Suspense,{fallback:c,children:t.jsxRuntimeExports.jsx("group",{ref:i,children:t.jsxRuntimeExports.jsx(Y,{rapidlyChangingMotionState:e,dhParameters:r,children:t.jsxRuntimeExports.jsx(Q,{modelURL:(()=>{const d=s(n,x);if(!d){const R=new Blob([],{type:"model/gltf-binary"}),h=new File([R],`${n}.glb`,{type:"model/gltf-binary"});return Promise.resolve(URL.createObjectURL(h))}return d})(),postModelRender:l,flangeRef:o,...u})})})}),t.jsxRuntimeExports.jsx(X,{})]})});function te({connectedMotionGroup:e,getModel:n=S,flangeRef:r,transparentColor:s,postModelRender:o,...l}){return e.dhParameters?t.jsxRuntimeExports.jsx(I,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,modelFromController:e.modelFromController||"",dhParameters:e.dhParameters,getModel:n,flangeRef:r,transparentColor:s,postModelRender:o,...l}):null}const ve=t.externalizeComponent(ae.observer(({robotName:e,programState:n,safetyState:r,operationMode:s,driveToHomeEnabled:o=!1,onDriveToHomePress:l,onDriveToHomeRelease:a,connectedMotionGroup:x,robotComponent:u=te,customContentComponent:m,className:f})=>{var z;const i=y.useTheme(),{t:c}=ue.useTranslation(),[d,R]=p.useState(!1),h=p.useRef(null),w=p.useRef(null),[b,V]=p.useState(!1),[A,oe]=p.useState({width:400,height:600}),[Te,ie]=p.useState(0);p.useEffect(()=>{const L=()=>{if(w.current){const{offsetWidth:W,offsetHeight:q}=w.current;V(W>q),oe({width:W,height:q})}};L();const O=new ResizeObserver(L);return w.current&&O.observe(w.current),()=>{O.disconnect()}},[]);const D=p.useCallback(()=>{ie(L=>L+1)},[]),C=p.useCallback(()=>{!o||!l||(R(!0),l())},[o,l]),T=p.useCallback(()=>{!o||!a||(R(!1),a())},[o,a]),U=p.useCallback(()=>{d&&a&&(R(!1),a())},[d,a]),v=b?A.width<350:A.height<200,k=b?A.height<310:A.height<450;return t.jsxRuntimeExports.jsx(y.Card,{ref:w,className:f,sx:{width:"100%",height:"100%",display:"flex",flexDirection:b?"row":"column",position:"relative",overflow:"hidden",minWidth:{xs:180,sm:220,md:250},minHeight:b?{xs:200,sm:240,md:260}:{xs:150,sm:180,md:220},border:`1px solid ${i.palette.divider}`,borderRadius:"18px",boxShadow:"none",backgroundColor:((z=i.palette.backgroundPaperElevation)==null?void 0:z[8])||"#2A2A3F",backgroundImage:"none"},children:b?t.jsxRuntimeExports.jsxs(t.jsxRuntimeExports.Fragment,{children:[t.jsxRuntimeExports.jsx(y.Box,{sx:{flex:"0 0 50%",position:"relative",height:"100%",minHeight:"100%",maxHeight:"100%",borderRadius:1,m:{xs:1.5,sm:2,md:3},mr:{xs:.75,sm:1,md:1.5},overflow:"hidden",display:v?"none":"block"},children:!v&&t.jsxRuntimeExports.jsxs(_.Canvas,{orthographic:!0,camera:{position:[3,2,3],zoom:1},shadows:!0,frameloop:"demand",style:{borderRadius:i.shape.borderRadius,width:"100%",height:"100%",background:"transparent",position:"absolute",top:0,left:0},dpr:[1,2],gl:{alpha:!0,antialias:!0},children:[t.jsxRuntimeExports.jsx(F,{}),t.jsxRuntimeExports.jsx(M.Bounds,{fit:!0,observe:!0,margin:1,maxDuration:1,children:t.jsxRuntimeExports.jsx(u,{connectedMotionGroup:x,postModelRender:D})})]})}),t.jsxRuntimeExports.jsxs(y.Box,{sx:{flex:"1",display:"flex",flexDirection:"column",justifyContent:"flex-start",width:v?"100%":"50%"},children:[t.jsxRuntimeExports.jsxs(y.Box,{sx:{p:{xs:1.5,sm:2,md:3},pb:{xs:1,sm:1.5,md:2},textAlign:"left"},children:[t.jsxRuntimeExports.jsx(y.Typography,{variant:"h6",component:"h2",sx:{mb:1},children:e}),t.jsxRuntimeExports.jsx(E.ProgramStateIndicator,{programState:n,safetyState:r,operationMode:s})]}),t.jsxRuntimeExports.jsxs(y.Box,{sx:{p:{xs:1.5,sm:2,md:3},pt:0,flex:"1",display:"flex",flexDirection:"column",justifyContent:"space-between"},children:[!k&&m&&t.jsxRuntimeExports.jsxs(y.Box,{children:[t.jsxRuntimeExports.jsx(m,{}),t.jsxRuntimeExports.jsx(y.Divider,{sx:{mt:1,mb:0,borderColor:i.palette.divider,opacity:.5}})]}),t.jsxRuntimeExports.jsx(y.Box,{sx:{mt:!k&&m?"auto":0},children:t.jsxRuntimeExports.jsx(y.Box,{sx:{display:"flex",justifyContent:"flex-start",mt:{xs:1,sm:1.5,md:2},mb:{xs:.5,sm:.75,md:1}},children:t.jsxRuntimeExports.jsx(y.Button,{ref:h,variant:"contained",color:"secondary",size:"small",disabled:!o,onMouseDown:C,onMouseUp:T,onMouseLeave:U,onTouchStart:C,onTouchEnd:T,sx:{textTransform:"none",px:1.5,py:.5},children:c("RobotCard.DriveToHome.bt")})})})]})]})]}):t.jsxRuntimeExports.jsx(t.jsxRuntimeExports.Fragment,{children:t.jsxRuntimeExports.jsxs(y.Box,{sx:{p:3,height:"100%",display:"flex",flexDirection:"column"},children:[t.jsxRuntimeExports.jsxs(y.Box,{children:[t.jsxRuntimeExports.jsx(y.Typography,{variant:"h6",component:"h2",sx:{mb:1},children:e}),t.jsxRuntimeExports.jsx(E.ProgramStateIndicator,{programState:n,safetyState:r,operationMode:s})]}),t.jsxRuntimeExports.jsx(y.Box,{sx:{flex:v?0:1,position:"relative",minHeight:v?0:{xs:120,sm:150,md:200},height:v?0:"auto",borderRadius:1,overflow:"hidden",display:v?"none":"block"},children:!v&&t.jsxRuntimeExports.jsxs(_.Canvas,{orthographic:!0,camera:{position:[3,2,3],zoom:1},shadows:!0,frameloop:"demand",style:{borderRadius:i.shape.borderRadius,width:"100%",height:"100%",background:"transparent",position:"absolute"},dpr:[1,2],gl:{alpha:!0,antialias:!0},children:[t.jsxRuntimeExports.jsx(F,{}),t.jsxRuntimeExports.jsx(M.Bounds,{fit:!0,clip:!0,observe:!0,margin:1,maxDuration:1,children:t.jsxRuntimeExports.jsx(u,{connectedMotionGroup:x,postModelRender:D})})]})}),t.jsxRuntimeExports.jsxs(y.Box,{children:[!k&&m&&t.jsxRuntimeExports.jsxs(t.jsxRuntimeExports.Fragment,{children:[t.jsxRuntimeExports.jsx(m,{}),t.jsxRuntimeExports.jsx(y.Divider,{sx:{mt:1,mb:0,borderColor:i.palette.divider,opacity:.5}})]}),t.jsxRuntimeExports.jsx(y.Box,{sx:{display:"flex",justifyContent:"flex-start",mt:!k&&m?{xs:1,sm:2,md:5}:{xs:.5,sm:1,md:2},mb:{xs:.5,sm:.75,md:1}},children:t.jsxRuntimeExports.jsx(y.Button,{ref:h,variant:"contained",color:"secondary",size:"small",disabled:!o,onMouseDown:C,onMouseUp:T,onMouseLeave:U,onTouchStart:C,onTouchEnd:T,sx:{textTransform:"none",px:1.5,py:.5},children:c("RobotCard.DriveToHome.bt")})})]})]})})})})),_e=Array(6).fill(2*Math.PI);function re({rapidlyChangingMotionState:e,dhParameters:n,onTranslationChanged:r,children:s}){const o=p.useRef([]),l=p.useRef([]),a=p.useRef(null),{invalidate:x}=_.useThree();p.useEffect(()=>{const i=e.joint_position.filter(c=>c!==void 0);return a.current=new E.ValueInterpolator(i,{tension:120,friction:20,threshold:.001}),()=>{var c;(c=a.current)==null||c.destroy()}},[]),_.useFrame((i,c)=>{if(a.current){const d=a.current.update(c);m(),d||x()}});function u(i){i&&(l.current=$(i),m(),x())}function m(){var c;const i=((c=a.current)==null?void 0:c.getCurrentValues())||[];if(r)r(l.current,i);else for(const[d,R]of l.current.entries()){const w=n[d].reverse_rotation_direction?-1:1;R.position.y=w*(i[d]||0)/1e3}}const f=p.useCallback(()=>{const i=e.joint_position.filter(c=>c!==void 0);requestAnimationFrame(()=>{var c;o.current=i,(c=a.current)==null||c.setTarget(i)})},[e]);return p.useEffect(()=>{f()},[e,f]),E.useAutorun(()=>{f()}),t.jsxRuntimeExports.jsx("group",{ref:u,children:s})}function ne({rapidlyChangingMotionState:e,dhParameters:n,...r}){const s=new g.Matrix4,o=p.useRef(null),l=p.useRef(null);function a(m){const f=new g.Matrix4;for(let R=0;R<n.length;R++){const h=n[R],w=m[R]??0,b=new g.Matrix4().makeRotationY(h.theta).multiply(new g.Matrix4().makeTranslation(h.a/1e3,(h.d+w*(h.reverse_rotation_direction?-1:1))/1e3,0)).multiply(new g.Matrix4().makeRotationX(h.alpha));f.multiply(b)}const i=new g.Vector3,c=new g.Quaternion,d=new g.Vector3;return f.decompose(i,c,d),i}const x=a(e.joint_position);function u(m,f){s.identity();let i=new g.Vector3;for(let h=0;h<n.length;h++){const w=f[h]??0,b=n[h],V=new g.Matrix4().makeRotationY(b.theta).multiply(new g.Matrix4().makeTranslation(b.a/1e3,(b.d+w*(b.reverse_rotation_direction?-1:1))/1e3,0)).multiply(new g.Matrix4().makeRotationX(b.alpha));s.multiply(V)}const c=new g.Vector3,d=new g.Quaternion,R=new g.Vector3;if(s.decompose(c,d,R),i=c,o.current&&o.current.position.set(i.x,i.y,i.z),l.current){const h=l.current.geometry;h&&h.setPositions&&h.setPositions([0,0,0,i.x,i.y,i.z])}}return t.jsxRuntimeExports.jsx(t.jsxRuntimeExports.Fragment,{children:t.jsxRuntimeExports.jsx(re,{rapidlyChangingMotionState:e,dhParameters:n,onTranslationChanged:u,children:t.jsxRuntimeExports.jsxs("group",{...r,name:"Scene",children:[t.jsxRuntimeExports.jsxs("mesh",{name:"Base",position:[0,0,0],children:[t.jsxRuntimeExports.jsx("sphereGeometry",{args:[.02,32,32]}),t.jsxRuntimeExports.jsx("meshStandardMaterial",{color:"green",depthTest:!0})]}),t.jsxRuntimeExports.jsx(M.Line,{ref:l,points:[new g.Vector3(0,0,0),x],color:"White",lineWidth:5}),t.jsxRuntimeExports.jsxs("mesh",{ref:o,name:"TCP",position:x,children:[t.jsxRuntimeExports.jsx("sphereGeometry",{args:[.025,32,32]}),t.jsxRuntimeExports.jsx("meshStandardMaterial",{color:"red",depthTest:!0})]})]})})})}const B=t.externalizeComponent(({rapidlyChangingMotionState:e,modelFromController:n,dhParameters:r,getModel:s=S,flangeRef:o,postModelRender:l,transparentColor:a,instanceUrl:x,...u})=>{const[m,f]=p.useState(null),i=p.useCallback(d=>{f(d)},[]);p.useEffect(()=>{m&&(a?Z(m,a):ee(m))},[m,a]);const c=t.jsxRuntimeExports.jsx(ne,{rapidlyChangingMotionState:e,dhParameters:r,...u});return t.jsxRuntimeExports.jsxs(N.ErrorBoundary,{fallback:c,onError:d=>{console.warn(d)},children:[t.jsxRuntimeExports.jsx(p.Suspense,{fallback:c,children:t.jsxRuntimeExports.jsx("group",{ref:i,children:t.jsxRuntimeExports.jsx(re,{rapidlyChangingMotionState:e,dhParameters:r,children:t.jsxRuntimeExports.jsx(Q,{modelURL:(()=>{const d=s(n,x);if(!d){const R=new Blob([],{type:"model/gltf-binary"}),h=new File([R],`${n}.glb`,{type:"model/gltf-binary"});return Promise.resolve(URL.createObjectURL(h))}return d})(),postModelRender:l,flangeRef:o,...u})})})}),t.jsxRuntimeExports.jsx(X,{})]})});function Se({connectedMotionGroup:e,getModel:n=S,flangeRef:r,transparentColor:s,postModelRender:o,...l}){if(!e.dhParameters)return null;const a=e.modelFromController||"";return a&&n(a)?t.jsxRuntimeExports.jsx(B,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,modelFromController:a,dhParameters:e.dhParameters,getModel:n,flangeRef:r,transparentColor:s,postModelRender:o,...l}):t.jsxRuntimeExports.jsx(ne,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,dhParameters:e.dhParameters,...l})}const P={[E.Manufacturer.Abb]:[0,0,0,0,Math.PI/2,0,0],[E.Manufacturer.Fanuc]:[0,0,0,0,-Math.PI/2,0,0],[E.Manufacturer.Yaskawa]:[0,0,0,0,-Math.PI/2,0,0],[E.Manufacturer.Kuka]:[0,-Math.PI/2,Math.PI/2,0,Math.PI/2,0,0],[E.Manufacturer.Universalrobots]:[0,-Math.PI/2,-Math.PI/2,-Math.PI/2,Math.PI/2,-Math.PI/2,0]};function se(e){const[n]=e.split("_");switch(n){case"ABB":return E.Manufacturer.Abb;case"FANUC":return E.Manufacturer.Fanuc;case"YASKAWA":return E.Manufacturer.Yaskawa;case"KUKA":return E.Manufacturer.Kuka;case"UniversalRobots":return E.Manufacturer.Universalrobots;default:return null}}function Ae(e,n){const r=se(e);return r&&r in P?P[r]:n||null}const Ce=t.externalizeComponent(e=>{const{instanceUrl:n,inverseSolver:r,modelFromController:s,...o}=e,[l,a]=p.useState(r),[,x]=p.useState(!1),u=p.useCallback(async()=>{const f=new E.NovaClient({instanceUrl:n});try{const i=await f.api.motionGroupModels.getMotionGroupKinematicModel(s);a(i.inverse_solver)}catch{console.warn(`Failed to fetch kinematic model from API for ${s}, falling back to local config`)}finally{setTimeout(()=>x(!0),0)}},[s,n]);p.useEffect(()=>{r===void 0&&!!s&&!!n&&u()},[r,s,u,n]);const m=p.useMemo(()=>["KUKA_DKP250","KUKA_DKP500_2","YASKAWA_TURN1","YASKAWA_TURN2","YASKAWA_TURN3"].includes(s),[s]);return l||m?t.jsxRuntimeExports.jsx(I,{instanceUrl:n,modelFromController:s,...o}):l===null?t.jsxRuntimeExports.jsx(B,{instanceUrl:n,modelFromController:s,...o}):null});exports.CollisionSceneRenderer=pe;exports.LinearAxis=Se;exports.MANUFACTURER_HOME_CONFIGS=P;exports.MotionGroupVisualizer=Ce;exports.PresetEnvironment=F;exports.Robot=te;exports.RobotCard=ve;exports.SafetyZonesRenderer=he;exports.SupportedLinearAxis=B;exports.SupportedRobot=I;exports.TrajectoryRenderer=je;exports.defaultAxisConfig=_e;exports.defaultGetModel=S;exports.extractManufacturer=se;exports.getDefaultHomeConfig=Ae;
|
|
2
|
-
//# sourceMappingURL=MotionGroupVisualizer-C3CB-L2z.cjs.map
|