@wandelbots/wandelbots-js-react-components 1.13.5 → 1.15.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/components/TransparentOverlay.d.ts +4 -0
- package/dist/components/TransparentOverlay.d.ts.map +1 -0
- package/dist/components/jogging/JoggingCartesianTab.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointTab.d.ts.map +1 -1
- package/dist/components/jogging/JoggingPanel.d.ts +2 -0
- package/dist/components/jogging/JoggingPanel.d.ts.map +1 -1
- package/dist/components/jogging/JoggingStore.d.ts +16 -0
- package/dist/components/jogging/JoggingStore.d.ts.map +1 -1
- package/dist/components/robots/KUKA_KR16_R2010_2.d.ts +3 -0
- package/dist/components/robots/KUKA_KR16_R2010_2.d.ts.map +1 -0
- package/dist/components/robots/SupportedRobot.d.ts.map +1 -1
- package/dist/index.cjs +30 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2923 -2610
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/TransparentOverlay.tsx +24 -0
- package/src/components/jogging/JoggingCartesianTab.tsx +1 -29
- package/src/components/jogging/JoggingJointTab.tsx +1 -20
- package/src/components/jogging/JoggingPanel.tsx +128 -83
- package/src/components/jogging/JoggingStore.tsx +83 -1
- package/src/components/robots/KUKA_KR16_R2010_2.tsx +212 -0
- package/src/components/robots/SupportedRobot.tsx +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"@mui/icons-material": "^5.16.7",
|
|
105
105
|
"@mui/lab": "^5.0.0-alpha.173",
|
|
106
106
|
"@shikijs/monaco": "^1.16.1",
|
|
107
|
-
"@wandelbots/wandelbots-js": "^1.
|
|
107
|
+
"@wandelbots/wandelbots-js": "^1.9.0",
|
|
108
108
|
"i18next-browser-languagedetector": "^8.0.0",
|
|
109
109
|
"lodash-es": "^4.17.21",
|
|
110
110
|
"mobx": "^6.13.1",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Stack } from "@mui/material"
|
|
2
|
+
import React from "react"
|
|
3
|
+
|
|
4
|
+
export const TransparentOverlay = (
|
|
5
|
+
props: React.ComponentProps<typeof Stack>,
|
|
6
|
+
) => {
|
|
7
|
+
return (
|
|
8
|
+
<Stack
|
|
9
|
+
position="absolute"
|
|
10
|
+
left={0}
|
|
11
|
+
top={0}
|
|
12
|
+
width="100%"
|
|
13
|
+
height="100%"
|
|
14
|
+
alignItems="center"
|
|
15
|
+
justifyContent="center"
|
|
16
|
+
sx={{
|
|
17
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
18
|
+
backdropFilter: "blur(10px)",
|
|
19
|
+
zIndex: 100,
|
|
20
|
+
}}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -18,7 +18,6 @@ import { JoggingVelocitySlider } from "./JoggingVelocitySlider"
|
|
|
18
18
|
import { useReaction } from "../utils/hooks"
|
|
19
19
|
import { JoggingCartesianValues } from "./JoggingCartesianValues"
|
|
20
20
|
import { JoggingJointLimitDetector } from "./JoggingJointLimitDetector"
|
|
21
|
-
import { useEffect } from "react"
|
|
22
21
|
|
|
23
22
|
type JoggingCartesianOpts = {
|
|
24
23
|
axis: "x" | "y" | "z"
|
|
@@ -50,31 +49,6 @@ export const JoggingCartesianTab = observer(
|
|
|
50
49
|
{ fireImmediately: true } as any,
|
|
51
50
|
)
|
|
52
51
|
|
|
53
|
-
useEffect(() => {
|
|
54
|
-
// Start in increment mode with no websockets open
|
|
55
|
-
store.jogger.setJoggingMode("increment")
|
|
56
|
-
|
|
57
|
-
window.addEventListener("blur", disconnectJogger)
|
|
58
|
-
|
|
59
|
-
return () => {
|
|
60
|
-
window.removeEventListener("blur", disconnectJogger)
|
|
61
|
-
}
|
|
62
|
-
}, [])
|
|
63
|
-
|
|
64
|
-
async function connectJogger() {
|
|
65
|
-
store.jogger.setJoggingMode(
|
|
66
|
-
store.activeDiscreteIncrement ? "increment" : "cartesian",
|
|
67
|
-
{
|
|
68
|
-
tcpId: store.selectedTcpId,
|
|
69
|
-
coordSystemId: store.activeCoordSystemId,
|
|
70
|
-
},
|
|
71
|
-
)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function disconnectJogger() {
|
|
75
|
-
store.jogger.setJoggingMode("increment")
|
|
76
|
-
}
|
|
77
|
-
|
|
78
52
|
async function runIncrementalCartesianJog(
|
|
79
53
|
opts: JoggingCartesianOpts,
|
|
80
54
|
increment: DiscreteIncrementOption,
|
|
@@ -111,8 +85,6 @@ export const JoggingCartesianTab = observer(
|
|
|
111
85
|
async function startCartesianJogging(opts: JoggingCartesianOpts) {
|
|
112
86
|
if (store.isLocked) return
|
|
113
87
|
|
|
114
|
-
connectJogger()
|
|
115
|
-
|
|
116
88
|
if (store.activeDiscreteIncrement) {
|
|
117
89
|
return runIncrementalCartesianJog(opts, store.activeDiscreteIncrement)
|
|
118
90
|
}
|
|
@@ -171,7 +143,7 @@ export const JoggingCartesianTab = observer(
|
|
|
171
143
|
}
|
|
172
144
|
|
|
173
145
|
return (
|
|
174
|
-
<Stack
|
|
146
|
+
<Stack>
|
|
175
147
|
{/* Show Wandelscript string for the current coords */}
|
|
176
148
|
<JoggingCartesianValues store={store} />
|
|
177
149
|
|
|
@@ -9,25 +9,6 @@ import { useEffect } from "react"
|
|
|
9
9
|
|
|
10
10
|
export const JoggingJointTab = observer(
|
|
11
11
|
({ store }: { store: JoggingStore }) => {
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
// Start in increment mode with no websockets open
|
|
14
|
-
store.jogger.setJoggingMode("increment")
|
|
15
|
-
|
|
16
|
-
window.addEventListener("blur", disconnectJogger)
|
|
17
|
-
|
|
18
|
-
return () => {
|
|
19
|
-
window.removeEventListener("blur", disconnectJogger)
|
|
20
|
-
}
|
|
21
|
-
}, [])
|
|
22
|
-
|
|
23
|
-
async function connectJogger() {
|
|
24
|
-
store.jogger.setJoggingMode("joint")
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function disconnectJogger() {
|
|
28
|
-
store.jogger.setJoggingMode("increment")
|
|
29
|
-
}
|
|
30
|
-
|
|
31
12
|
async function startJointJogging(opts: {
|
|
32
13
|
joint: number
|
|
33
14
|
direction: "-" | "+"
|
|
@@ -44,7 +25,7 @@ export const JoggingJointTab = observer(
|
|
|
44
25
|
}
|
|
45
26
|
|
|
46
27
|
return (
|
|
47
|
-
<Stack
|
|
28
|
+
<Stack>
|
|
48
29
|
<JoggingJointValues store={store} />
|
|
49
30
|
<Stack>
|
|
50
31
|
{store.jogger.motionStream.joints.map((joint) => {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { Paper, Stack, Tab, Tabs } from "@mui/material"
|
|
1
|
+
import { Button, Paper, Stack, Tab, Tabs } from "@mui/material"
|
|
2
2
|
import { observer, useLocalObservable } from "mobx-react-lite"
|
|
3
3
|
import { useEffect } from "react"
|
|
4
4
|
import { JoggingCartesianTab } from "./JoggingCartesianTab"
|
|
5
5
|
import { JoggingJointTab } from "./JoggingJointTab"
|
|
6
6
|
import { JoggingStore } from "./JoggingStore"
|
|
7
7
|
import { LoadingCover } from "../LoadingCover"
|
|
8
|
+
import { TransparentOverlay } from "../TransparentOverlay"
|
|
8
9
|
import { runInAction } from "mobx"
|
|
9
10
|
import { NovaClient } from "@wandelbots/wandelbots-js"
|
|
10
11
|
import { externalizeComponent } from "../../externalizeComponent"
|
|
11
12
|
import { isString } from "lodash-es"
|
|
13
|
+
import { useReaction } from "../utils/hooks"
|
|
12
14
|
|
|
13
15
|
export type JoggingPanelProps = {
|
|
14
16
|
/** Either an existing NovaClient or the base url of a deployed Nova instance */
|
|
@@ -19,6 +21,8 @@ export type JoggingPanelProps = {
|
|
|
19
21
|
onSetup?: (store: JoggingStore) => void
|
|
20
22
|
/** Any children will go at the bottom of the panel under the default contents */
|
|
21
23
|
children?: React.ReactNode
|
|
24
|
+
/** Set this to true to disable jogging UI temporarily e.g. when a program is executing */
|
|
25
|
+
locked?: boolean
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
/**
|
|
@@ -62,101 +66,142 @@ export const JoggingPanel = externalizeComponent(
|
|
|
62
66
|
}
|
|
63
67
|
}, [props.nova])
|
|
64
68
|
|
|
65
|
-
// Set correct jogging mode on jogger based on user selections
|
|
66
69
|
useEffect(() => {
|
|
67
|
-
|
|
70
|
+
const store = state.joggingStore
|
|
71
|
+
if (!store) return
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
if (props.locked) {
|
|
74
|
+
store.locks.add("external")
|
|
75
|
+
} else {
|
|
76
|
+
store.locks.delete("external")
|
|
77
|
+
}
|
|
78
|
+
}, [props.locked])
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
return (
|
|
81
|
+
<Stack
|
|
82
|
+
sx={{
|
|
83
|
+
maxWidth: "460px",
|
|
84
|
+
minWidth: "350px",
|
|
85
|
+
overflowY: "auto",
|
|
86
|
+
position: "relative",
|
|
87
|
+
height: "100%",
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<Paper
|
|
91
|
+
sx={{
|
|
92
|
+
height: "100%",
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
{state.joggingStore ? (
|
|
96
|
+
<JoggingPanelInner store={state.joggingStore}>
|
|
97
|
+
{props.children}
|
|
98
|
+
</JoggingPanelInner>
|
|
99
|
+
) : (
|
|
100
|
+
<LoadingCover
|
|
101
|
+
message="Loading jogging"
|
|
102
|
+
error={state.loadingError}
|
|
103
|
+
/>
|
|
104
|
+
)}
|
|
105
|
+
</Paper>
|
|
106
|
+
</Stack>
|
|
107
|
+
)
|
|
108
|
+
}),
|
|
109
|
+
)
|
|
77
110
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
const JoggingPanelInner = observer(
|
|
112
|
+
({
|
|
113
|
+
store,
|
|
114
|
+
children,
|
|
115
|
+
}: {
|
|
116
|
+
store: JoggingStore
|
|
117
|
+
children?: React.ReactNode
|
|
118
|
+
}) => {
|
|
119
|
+
// Jogger is only active as long as the tab is focused
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
window.addEventListener("blur", store.deactivate)
|
|
122
|
+
|
|
123
|
+
return () => {
|
|
124
|
+
window.removeEventListener("blur", store.deactivate)
|
|
81
125
|
}
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// Update jogging mode on jogger based on user selections
|
|
129
|
+
useReaction(
|
|
130
|
+
() => [
|
|
131
|
+
store.currentTab,
|
|
132
|
+
store.selectedTcpId,
|
|
133
|
+
store.activeCoordSystemId,
|
|
134
|
+
store.activeDiscreteIncrement,
|
|
135
|
+
],
|
|
136
|
+
() => {
|
|
137
|
+
if (store.activationState === "active") store.activate()
|
|
138
|
+
},
|
|
139
|
+
)
|
|
82
140
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
141
|
+
function renderOverlay() {
|
|
142
|
+
if (store.activationState === "inactive" && !store.activationError) {
|
|
143
|
+
return (
|
|
144
|
+
<TransparentOverlay>
|
|
145
|
+
<Button
|
|
146
|
+
color="primary"
|
|
147
|
+
variant="contained"
|
|
148
|
+
onClick={store.activate}
|
|
149
|
+
disabled={store.isLocked}
|
|
150
|
+
>
|
|
151
|
+
Activate jogging
|
|
152
|
+
</Button>
|
|
153
|
+
</TransparentOverlay>
|
|
87
154
|
)
|
|
88
|
-
} else {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
155
|
+
} else if (store.activationState === "loading" || store.activationError) {
|
|
156
|
+
return (
|
|
157
|
+
<TransparentOverlay>
|
|
158
|
+
<LoadingCover
|
|
159
|
+
message="Activating jogging"
|
|
160
|
+
error={store.activationError}
|
|
161
|
+
/>
|
|
162
|
+
</TransparentOverlay>
|
|
92
163
|
)
|
|
93
164
|
}
|
|
94
|
-
}, [
|
|
95
|
-
state.joggingStore?.currentTab,
|
|
96
|
-
state.joggingStore?.selectedTcpId,
|
|
97
|
-
state.joggingStore?.activeCoordSystemId,
|
|
98
|
-
state.joggingStore?.activeDiscreteIncrement,
|
|
99
|
-
])
|
|
100
|
-
|
|
101
|
-
if (!state.joggingStore || state.loadingError) {
|
|
102
|
-
return (
|
|
103
|
-
<JoggingPanelOuter>
|
|
104
|
-
<LoadingCover message="Loading jogging" error={state.loadingError} />
|
|
105
|
-
</JoggingPanelOuter>
|
|
106
|
-
)
|
|
107
165
|
}
|
|
108
166
|
|
|
109
|
-
|
|
167
|
+
function renderTabContent() {
|
|
168
|
+
if (store.currentTab.id === "cartesian") {
|
|
169
|
+
return (
|
|
170
|
+
<>
|
|
171
|
+
<JoggingCartesianTab store={store} />
|
|
172
|
+
{children}
|
|
173
|
+
</>
|
|
174
|
+
)
|
|
175
|
+
} else if (store.currentTab.id === "joint") {
|
|
176
|
+
return (
|
|
177
|
+
<>
|
|
178
|
+
<JoggingJointTab store={store} />
|
|
179
|
+
{children}
|
|
180
|
+
</>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
110
184
|
|
|
111
185
|
return (
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
<JoggingCartesianTab store={store} />
|
|
130
|
-
)}
|
|
131
|
-
{store.currentTab.id === "joint" && (
|
|
132
|
-
<JoggingJointTab store={store} />
|
|
133
|
-
)}
|
|
134
|
-
{props.children}
|
|
135
|
-
</Stack>
|
|
186
|
+
<Stack flexGrow={1} height="100%">
|
|
187
|
+
{/* Tab selection */}
|
|
188
|
+
<Tabs value={store.tabIndex} onChange={store.onTabChange}>
|
|
189
|
+
{store.tabs.map((tab) => (
|
|
190
|
+
<Tab
|
|
191
|
+
key={tab.id}
|
|
192
|
+
label={tab.label}
|
|
193
|
+
id={`jogging-tab-${tab.id}`}
|
|
194
|
+
aria-controls={`jogging-tab-${tab.id}`}
|
|
195
|
+
/>
|
|
196
|
+
))}
|
|
197
|
+
</Tabs>
|
|
198
|
+
|
|
199
|
+
{/* Current tab content */}
|
|
200
|
+
<Stack flexGrow={1} position="relative">
|
|
201
|
+
{renderOverlay()}
|
|
202
|
+
{renderTabContent()}
|
|
136
203
|
</Stack>
|
|
137
|
-
</
|
|
204
|
+
</Stack>
|
|
138
205
|
)
|
|
139
|
-
}
|
|
206
|
+
},
|
|
140
207
|
)
|
|
141
|
-
|
|
142
|
-
function JoggingPanelOuter({ children }: { children: React.ReactNode }) {
|
|
143
|
-
return (
|
|
144
|
-
<Stack
|
|
145
|
-
sx={{
|
|
146
|
-
maxWidth: "460px",
|
|
147
|
-
minWidth: "350px",
|
|
148
|
-
overflowY: "auto",
|
|
149
|
-
position: "relative",
|
|
150
|
-
height: "100%",
|
|
151
|
-
}}
|
|
152
|
-
>
|
|
153
|
-
<Paper
|
|
154
|
-
sx={{
|
|
155
|
-
height: "100%",
|
|
156
|
-
}}
|
|
157
|
-
>
|
|
158
|
-
{children}
|
|
159
|
-
</Paper>
|
|
160
|
-
</Stack>
|
|
161
|
-
)
|
|
162
|
-
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import keyBy from "lodash-es/keyBy"
|
|
2
2
|
import uniqueId from "lodash-es/uniqueId"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
autorun,
|
|
5
|
+
makeAutoObservable,
|
|
6
|
+
runInAction,
|
|
7
|
+
type IReactionDisposer,
|
|
8
|
+
} from "mobx"
|
|
4
9
|
import type {
|
|
5
10
|
CoordinateSystem,
|
|
6
11
|
JoggerConnection,
|
|
@@ -28,6 +33,16 @@ export type IncrementOptionId = IncrementOption["id"]
|
|
|
28
33
|
export class JoggingStore {
|
|
29
34
|
selectedTabId: "cartesian" | "joint" | "debug" = "cartesian"
|
|
30
35
|
|
|
36
|
+
/**
|
|
37
|
+
* State of the jogging panel. Starts as "inactive"
|
|
38
|
+
*/
|
|
39
|
+
activationState: "inactive" | "loading" | "active" = "inactive"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* If an error occurred connecting to the jogging websocket
|
|
43
|
+
*/
|
|
44
|
+
activationError: unknown | null = null
|
|
45
|
+
|
|
31
46
|
/** Locks to prevent UI interactions during certain operations */
|
|
32
47
|
locks = new Set<string>()
|
|
33
48
|
|
|
@@ -145,6 +160,68 @@ export class JoggingStore {
|
|
|
145
160
|
this.jogger.dispose()
|
|
146
161
|
}
|
|
147
162
|
|
|
163
|
+
async deactivate() {
|
|
164
|
+
if (this.activationState === "inactive") return
|
|
165
|
+
const websocket = this.jogger.activeWebsocket
|
|
166
|
+
|
|
167
|
+
this.activationState = "inactive"
|
|
168
|
+
this.jogger.setJoggingMode("increment")
|
|
169
|
+
|
|
170
|
+
if (websocket) {
|
|
171
|
+
await websocket.closed()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Activate the jogger with current settings */
|
|
176
|
+
async activate() {
|
|
177
|
+
const {
|
|
178
|
+
currentTab,
|
|
179
|
+
selectedTcpId,
|
|
180
|
+
activeCoordSystemId,
|
|
181
|
+
activeDiscreteIncrement,
|
|
182
|
+
jogger,
|
|
183
|
+
} = this
|
|
184
|
+
|
|
185
|
+
if (this.activationState === "loading") return
|
|
186
|
+
|
|
187
|
+
runInAction(() => {
|
|
188
|
+
this.activationState = "loading"
|
|
189
|
+
this.activationError = null
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
if (currentTab.id === "cartesian") {
|
|
193
|
+
const cartesianJoggingOpts = {
|
|
194
|
+
tcpId: selectedTcpId,
|
|
195
|
+
coordSystemId: activeCoordSystemId,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (activeDiscreteIncrement) {
|
|
199
|
+
jogger.setJoggingMode("increment", cartesianJoggingOpts)
|
|
200
|
+
} else {
|
|
201
|
+
jogger.setJoggingMode("cartesian", cartesianJoggingOpts)
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
jogger.setJoggingMode("joint")
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (jogger.activeWebsocket) {
|
|
208
|
+
try {
|
|
209
|
+
jogger.stop()
|
|
210
|
+
await jogger.activeWebsocket.nextMessage()
|
|
211
|
+
} catch (err) {
|
|
212
|
+
runInAction(() => {
|
|
213
|
+
this.activationState = "inactive"
|
|
214
|
+
this.activationError = err
|
|
215
|
+
})
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
runInAction(() => {
|
|
221
|
+
this.activationState = "active"
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
|
|
148
225
|
loadFromLocalStorage() {
|
|
149
226
|
const save = tryParseJson(localStorage.getItem("joggingToolStore"))
|
|
150
227
|
if (!save) return
|
|
@@ -241,6 +318,11 @@ export class JoggingStore {
|
|
|
241
318
|
return this.coordSystemsById[this.selectedCoordSystemId]
|
|
242
319
|
}
|
|
243
320
|
|
|
321
|
+
/**
|
|
322
|
+
* The id of the coordinate system to use for jogging.
|
|
323
|
+
* If in tool orientation, this is set to "tool", not the
|
|
324
|
+
* selected coordinate system.
|
|
325
|
+
*/
|
|
244
326
|
get activeCoordSystemId() {
|
|
245
327
|
return this.selectedOrientation === "tool"
|
|
246
328
|
? "tool"
|