@wandelbots/wandelbots-js-react-components 2.59.0-pr.dev-fix-flaky-task.488.1957fef → 2.59.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/README.md +10 -107
- package/dist/auth0-spa-js.production.esm-1QXzndwB.js +950 -0
- package/dist/auth0-spa-js.production.esm-1QXzndwB.js.map +1 -0
- package/dist/auth0-spa-js.production.esm-BLRAk7Yh.cjs +5 -0
- package/dist/auth0-spa-js.production.esm-BLRAk7Yh.cjs.map +1 -0
- package/dist/components/3d-viewport/CoordinateSystemTransform.d.ts +1 -1
- package/dist/components/3d-viewport/CoordinateSystemTransform.d.ts.map +1 -1
- package/dist/components/3d-viewport/SafetyZonesRenderer.d.ts.map +1 -1
- package/dist/components/3d-viewport/collider/ColliderCollection.d.ts +1 -1
- package/dist/components/3d-viewport/collider/ColliderCollection.d.ts.map +1 -1
- package/dist/components/3d-viewport/collider/ColliderElement.d.ts +1 -1
- package/dist/components/3d-viewport/collider/ColliderElement.d.ts.map +1 -1
- package/dist/components/3d-viewport/collider/CollisionSceneRenderer.d.ts +1 -1
- package/dist/components/3d-viewport/collider/CollisionSceneRenderer.d.ts.map +1 -1
- package/dist/components/3d-viewport/collider/colliderShapeToBufferGeometry.d.ts +1 -1
- package/dist/components/3d-viewport/collider/colliderShapeToBufferGeometry.d.ts.map +1 -1
- package/dist/components/ProgramStateIndicator.d.ts +3 -3
- package/dist/components/ProgramStateIndicator.d.ts.map +1 -1
- package/dist/components/RobotCard.d.ts +4 -5
- package/dist/components/RobotCard.d.ts.map +1 -1
- package/dist/components/jogging/JoggingCartesianTab.d.ts.map +1 -1
- package/dist/components/jogging/JoggingOptions.d.ts.map +1 -1
- package/dist/components/jogging/JoggingPanel.d.ts +1 -1
- package/dist/components/jogging/JoggingPanel.d.ts.map +1 -1
- package/dist/components/jogging/JoggingStore.d.ts +5 -10
- package/dist/components/jogging/JoggingStore.d.ts.map +1 -1
- package/dist/components/jogging/PoseCartesianValues.d.ts +2 -2
- package/dist/components/jogging/PoseCartesianValues.d.ts.map +1 -1
- package/dist/components/jogging/PoseJointValues.d.ts +2 -1
- package/dist/components/jogging/PoseJointValues.d.ts.map +1 -1
- package/dist/components/robots/DHRobot.d.ts.map +1 -1
- package/dist/components/robots/GenericRobot.d.ts +2 -2
- package/dist/components/robots/GenericRobot.d.ts.map +1 -1
- package/dist/components/robots/Robot.d.ts +2 -4
- package/dist/components/robots/Robot.d.ts.map +1 -1
- package/dist/components/robots/RobotAnimator.d.ts +2 -2
- package/dist/components/robots/RobotAnimator.d.ts.map +1 -1
- package/dist/components/robots/SupportedRobot.d.ts +4 -4
- package/dist/components/robots/SupportedRobot.d.ts.map +1 -1
- package/dist/components/robots/manufacturerHomePositions.d.ts +1 -1
- package/dist/components/robots/manufacturerHomePositions.d.ts.map +1 -1
- package/dist/components/robots/robotModelLogic.d.ts +1 -11
- package/dist/components/robots/robotModelLogic.d.ts.map +1 -1
- package/dist/components/safetyBar/ControllerTypeIndicator.d.ts.map +1 -1
- package/dist/components/safetyBar/OperationModeIndicator.d.ts +2 -2
- package/dist/components/safetyBar/OperationModeIndicator.d.ts.map +1 -1
- package/dist/components/safetyBar/SafetyBar.d.ts +3 -3
- package/dist/components/safetyBar/SafetyBar.d.ts.map +1 -1
- package/dist/components/safetyBar/SafetyStateIndicator.d.ts +2 -2
- package/dist/components/safetyBar/SafetyStateIndicator.d.ts.map +1 -1
- package/dist/components/utils/errorHandling.d.ts.map +1 -1
- package/dist/index.cjs +160 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +39 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36825 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -70
- package/src/components/3d-viewport/CoordinateSystemTransform.tsx +1 -1
- package/src/components/3d-viewport/SafetyZonesRenderer.tsx +2 -1
- package/src/components/3d-viewport/collider/ColliderCollection.tsx +1 -1
- package/src/components/3d-viewport/collider/ColliderElement.tsx +1 -1
- package/src/components/3d-viewport/collider/CollisionSceneRenderer.tsx +1 -1
- package/src/components/3d-viewport/collider/colliderShapeToBufferGeometry.ts +1 -1
- package/src/components/AppHeader.md +1 -1
- package/src/components/ProgramStateIndicator.tsx +6 -3
- package/src/components/RobotCard.tsx +8 -5
- package/src/components/jogging/JoggingCartesianTab.tsx +11 -13
- package/src/components/jogging/JoggingJointLimitDetector.tsx +2 -2
- package/src/components/jogging/JoggingJointTab.tsx +4 -4
- package/src/components/jogging/JoggingOptions.tsx +5 -6
- package/src/components/jogging/JoggingPanel.tsx +3 -6
- package/src/components/jogging/JoggingStore.ts +39 -66
- package/src/components/jogging/PoseCartesianValues.tsx +4 -3
- package/src/components/jogging/PoseJointValues.tsx +4 -3
- package/src/components/robots/DHRobot.tsx +3 -2
- package/src/components/robots/GenericRobot.tsx +36 -97
- package/src/components/robots/Robot.tsx +2 -4
- package/src/components/robots/RobotAnimator.test.tsx +22 -7
- package/src/components/robots/RobotAnimator.tsx +14 -9
- package/src/components/robots/SupportedRobot.tsx +9 -14
- package/src/components/robots/manufacturerHomePositions.ts +1 -1
- package/src/components/robots/robotModelLogic.ts +6 -75
- package/src/components/safetyBar/ControllerTypeIndicator.tsx +2 -4
- package/src/components/safetyBar/OperationModeIndicator.tsx +5 -7
- package/src/components/safetyBar/SafetyBar.tsx +6 -3
- package/src/components/safetyBar/SafetyStateIndicator.tsx +7 -9
- package/src/components/utils/errorHandling.ts +0 -4
- package/src/i18n/locales/de/translations.json +0 -3
- package/src/i18n/locales/en/translations.json +0 -3
- package/src/index.ts +43 -4
- package/dist/3d.cjs.js +0 -2
- package/dist/3d.cjs.js.map +0 -1
- package/dist/3d.d.ts +0 -11
- package/dist/3d.d.ts.map +0 -1
- package/dist/3d.es.js +0 -16
- package/dist/3d.es.js.map +0 -1
- package/dist/LoadingCover-6gWr11KP.js +0 -88
- package/dist/LoadingCover-6gWr11KP.js.map +0 -1
- package/dist/LoadingCover-CukpS_aj.cjs +0 -2
- package/dist/LoadingCover-CukpS_aj.cjs.map +0 -1
- package/dist/WandelscriptEditor-7eN-Yw7m.js +0 -140
- package/dist/WandelscriptEditor-7eN-Yw7m.js.map +0 -1
- package/dist/WandelscriptEditor-D6_vS5Uk.cjs +0 -2
- package/dist/WandelscriptEditor-D6_vS5Uk.cjs.map +0 -1
- package/dist/auth0-spa-js.production.esm-BMSlxZC5.js +0 -3877
- package/dist/auth0-spa-js.production.esm-BMSlxZC5.js.map +0 -1
- package/dist/auth0-spa-js.production.esm-DZ6lsBvD.cjs +0 -5
- package/dist/auth0-spa-js.production.esm-DZ6lsBvD.cjs.map +0 -1
- package/dist/components/jogging/JoggingBlocked.d.ts +0 -7
- package/dist/components/jogging/JoggingBlocked.d.ts.map +0 -1
- package/dist/components/utils/errorHandling.test.d.ts +0 -2
- package/dist/components/utils/errorHandling.test.d.ts.map +0 -1
- package/dist/core.cjs.js +0 -2
- package/dist/core.cjs.js.map +0 -1
- package/dist/core.d.ts +0 -33
- package/dist/core.d.ts.map +0 -1
- package/dist/core.es.js +0 -54
- package/dist/core.es.js.map +0 -1
- package/dist/externalizeComponent-CkVWk2F_.cjs +0 -24
- package/dist/externalizeComponent-CkVWk2F_.cjs.map +0 -1
- package/dist/externalizeComponent-Dc3fViZA.js +0 -489
- package/dist/externalizeComponent-Dc3fViZA.js.map +0 -1
- package/dist/index.cjs.js +0 -2
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js +0 -69
- package/dist/index.es.js.map +0 -1
- package/dist/interpolation-DAXKfoDS.cjs +0 -20
- package/dist/interpolation-DAXKfoDS.cjs.map +0 -1
- package/dist/interpolation-DcPbemBD.js +0 -6924
- package/dist/interpolation-DcPbemBD.js.map +0 -1
- package/dist/lib/ConnectedMotionGroup.d.ts +0 -90
- package/dist/lib/ConnectedMotionGroup.d.ts.map +0 -1
- package/dist/lib/JoggerConnection.d.ts +0 -113
- package/dist/lib/JoggerConnection.d.ts.map +0 -1
- package/dist/lib/JoggerConnection.test.d.ts +0 -2
- package/dist/lib/JoggerConnection.test.d.ts.map +0 -1
- package/dist/lib/MotionStreamConnection.d.ts +0 -24
- package/dist/lib/MotionStreamConnection.d.ts.map +0 -1
- package/dist/lib/MotionStreamConnection.test.d.ts +0 -2
- package/dist/lib/MotionStreamConnection.test.d.ts.map +0 -1
- package/dist/lib/motionStateUpdate.d.ts +0 -7
- package/dist/lib/motionStateUpdate.d.ts.map +0 -1
- package/dist/lib/motionStateUpdate.test.d.ts +0 -2
- package/dist/lib/motionStateUpdate.test.d.ts.map +0 -1
- package/dist/manufacturerHomePositions-BD6C5qZJ.js +0 -1040
- package/dist/manufacturerHomePositions-BD6C5qZJ.js.map +0 -1
- package/dist/manufacturerHomePositions-DRNjU1pU.cjs +0 -2
- package/dist/manufacturerHomePositions-DRNjU1pU.cjs.map +0 -1
- package/dist/theming-CPShzNuV.cjs +0 -115
- package/dist/theming-CPShzNuV.cjs.map +0 -1
- package/dist/theming-Hr605E6v.js +0 -22336
- package/dist/theming-Hr605E6v.js.map +0 -1
- package/dist/wandelscript.cjs.js +0 -2
- package/dist/wandelscript.cjs.js.map +0 -1
- package/dist/wandelscript.d.ts +0 -2
- package/dist/wandelscript.d.ts.map +0 -1
- package/dist/wandelscript.es.js +0 -5
- package/dist/wandelscript.es.js.map +0 -1
- package/src/3d.ts +0 -15
- package/src/components/jogging/JoggingBlocked.tsx +0 -37
- package/src/components/utils/errorHandling.test.ts +0 -41
- package/src/core.ts +0 -33
- package/src/env.d.ts +0 -3
- package/src/lib/ConnectedMotionGroup.ts +0 -444
- package/src/lib/JoggerConnection.test.ts +0 -120
- package/src/lib/JoggerConnection.ts +0 -674
- package/src/lib/MotionStreamConnection.test.ts +0 -23
- package/src/lib/MotionStreamConnection.ts +0 -189
- package/src/lib/motionStateUpdate.test.ts +0 -28
- package/src/lib/motionStateUpdate.ts +0 -117
- package/src/wandelscript.ts +0 -2
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { tryParseJson } from "@wandelbots/nova-js"
|
|
2
2
|
import type {
|
|
3
3
|
CoordinateSystem,
|
|
4
|
-
|
|
4
|
+
JoggerConnection,
|
|
5
|
+
MotionGroupSpecification,
|
|
5
6
|
RobotTcp,
|
|
6
|
-
} from "@wandelbots/nova-js/
|
|
7
|
+
} from "@wandelbots/nova-js/v1"
|
|
7
8
|
import { countBy } from "lodash-es"
|
|
8
9
|
import keyBy from "lodash-es/keyBy"
|
|
9
10
|
import uniqueId from "lodash-es/uniqueId"
|
|
10
11
|
import { autorun, makeAutoObservable, type IReactionDisposer } from "mobx"
|
|
11
|
-
import type {
|
|
12
|
-
JoggerConnection,
|
|
13
|
-
JoggerOrientation,
|
|
14
|
-
Vector3Simple,
|
|
15
|
-
} from "../../lib/JoggerConnection"
|
|
16
12
|
|
|
17
13
|
const discreteIncrementOptions = [
|
|
18
14
|
{ id: "0.1", mm: 0.1, degrees: 0.05 },
|
|
@@ -59,9 +55,6 @@ export class JoggingStore {
|
|
|
59
55
|
/** Locks to prevent UI interactions during certain operations */
|
|
60
56
|
locks = new Set<string>()
|
|
61
57
|
|
|
62
|
-
/** Block jogging UI interactions when connection is taken by another jogger */
|
|
63
|
-
blocked: boolean = false
|
|
64
|
-
|
|
65
58
|
/**
|
|
66
59
|
* Id of selected coordinate system from among those defined on the API side
|
|
67
60
|
*/
|
|
@@ -112,7 +105,7 @@ export class JoggingStore {
|
|
|
112
105
|
maxRotationVelocityDegPerSec: number = 60
|
|
113
106
|
|
|
114
107
|
/** Whether to show the coordinate system select dropdown in the UI */
|
|
115
|
-
showCoordSystemSelect: boolean =
|
|
108
|
+
showCoordSystemSelect: boolean = true
|
|
116
109
|
|
|
117
110
|
/** Whether to show the TCP select dropdown in the UI */
|
|
118
111
|
showTcpSelect: boolean = true
|
|
@@ -145,34 +138,34 @@ export class JoggingStore {
|
|
|
145
138
|
const { nova } = jogger
|
|
146
139
|
|
|
147
140
|
// Find out what TCPs this motion group has (we need it for jogging)
|
|
148
|
-
const [coordinatesystems,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
141
|
+
const [motionGroupSpec, { coordinatesystems }, { tcps }] =
|
|
142
|
+
await Promise.all([
|
|
143
|
+
nova.api.motionGroupInfos.getMotionGroupSpecification(
|
|
144
|
+
jogger.motionGroupId,
|
|
145
|
+
),
|
|
146
|
+
|
|
147
|
+
// Fetch coord systems so user can select between them
|
|
148
|
+
nova.api.coordinateSystems.listCoordinateSystems("ROTATION_VECTOR"),
|
|
149
|
+
|
|
150
|
+
// Same for TCPs
|
|
151
|
+
nova.api.motionGroupInfos.listTcps(
|
|
152
|
+
jogger.motionGroupId,
|
|
153
|
+
"ROTATION_VECTOR",
|
|
154
|
+
),
|
|
155
|
+
])
|
|
156
|
+
|
|
157
|
+
return new JoggingStore(
|
|
158
|
+
jogger,
|
|
159
|
+
motionGroupSpec,
|
|
160
|
+
coordinatesystems || [],
|
|
161
|
+
tcps || [],
|
|
162
|
+
)
|
|
170
163
|
}
|
|
171
164
|
|
|
172
165
|
constructor(
|
|
173
166
|
readonly jogger: JoggerConnection,
|
|
167
|
+
readonly motionGroupSpec: MotionGroupSpecification,
|
|
174
168
|
readonly coordSystems: CoordinateSystem[],
|
|
175
|
-
readonly motionGroupDescription: MotionGroupDescription,
|
|
176
169
|
readonly tcps: RobotTcp[],
|
|
177
170
|
) {
|
|
178
171
|
// TODO workaround for default coord system on backend having a canonical id
|
|
@@ -186,21 +179,13 @@ export class JoggingStore {
|
|
|
186
179
|
this.selectedCoordSystemId = coordSystems[0]?.coordinate_system || "world"
|
|
187
180
|
this.selectedTcpId = tcps[0]?.id || ""
|
|
188
181
|
|
|
189
|
-
// Make all properties observable and actions auto-bound
|
|
190
182
|
makeAutoObservable(this, {}, { autoBind: true })
|
|
191
183
|
|
|
192
|
-
// Register blocked watching
|
|
193
|
-
this.jogger.onBlocked = () => {
|
|
194
|
-
this.block()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
184
|
// Load user settings from local storage if available
|
|
198
185
|
this.loadFromLocalStorage()
|
|
199
186
|
|
|
200
187
|
// Automatically save user settings to local storage when save changes
|
|
201
188
|
this.disposers.push(autorun(() => this.saveToLocalStorage()))
|
|
202
|
-
|
|
203
|
-
// Assign joggingStore to window
|
|
204
189
|
;(window as any).joggingStore = this
|
|
205
190
|
}
|
|
206
191
|
|
|
@@ -216,31 +201,30 @@ export class JoggingStore {
|
|
|
216
201
|
}
|
|
217
202
|
|
|
218
203
|
async deactivate() {
|
|
219
|
-
|
|
220
|
-
|
|
204
|
+
const websocket = this.jogger.activeWebsocket
|
|
205
|
+
|
|
206
|
+
this.jogger.setJoggingMode("increment")
|
|
207
|
+
|
|
208
|
+
if (websocket) {
|
|
209
|
+
await websocket.closed()
|
|
221
210
|
}
|
|
222
211
|
}
|
|
223
212
|
|
|
224
213
|
/** Activate the jogger with current settings */
|
|
225
214
|
async activate() {
|
|
226
215
|
if (this.currentTab.id === "cartesian") {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
) {
|
|
231
|
-
this.jogger.setOptions({
|
|
232
|
-
tcp: this.selectedTcpId,
|
|
233
|
-
orientation: this.selectedOrientation as JoggerOrientation,
|
|
234
|
-
})
|
|
216
|
+
const cartesianJoggingOpts = {
|
|
217
|
+
tcpId: this.selectedTcpId,
|
|
218
|
+
coordSystemId: this.activeCoordSystemId,
|
|
235
219
|
}
|
|
236
220
|
|
|
237
221
|
if (this.activeDiscreteIncrement) {
|
|
238
|
-
this.jogger.setJoggingMode("
|
|
222
|
+
this.jogger.setJoggingMode("increment", cartesianJoggingOpts)
|
|
239
223
|
} else {
|
|
240
|
-
this.jogger.setJoggingMode("
|
|
224
|
+
this.jogger.setJoggingMode("cartesian", cartesianJoggingOpts)
|
|
241
225
|
}
|
|
242
226
|
} else {
|
|
243
|
-
this.jogger.setJoggingMode("
|
|
227
|
+
this.jogger.setJoggingMode("joint")
|
|
244
228
|
}
|
|
245
229
|
|
|
246
230
|
return this.jogger
|
|
@@ -449,17 +433,6 @@ export class JoggingStore {
|
|
|
449
433
|
this.locks.delete(id)
|
|
450
434
|
}
|
|
451
435
|
|
|
452
|
-
block() {
|
|
453
|
-
this.blocked = true
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
unblock() {
|
|
457
|
-
this.blocked = false
|
|
458
|
-
if (this.jogger.mode === "jogging") {
|
|
459
|
-
this.jogger.initializeJoggingWebsocket()
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
436
|
/** Lock the UI until the given async callback resolves */
|
|
464
437
|
async withMotionLock(fn: () => Promise<void>) {
|
|
465
438
|
const lockId = uniqueId()
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Button, Stack } from "@mui/material"
|
|
2
|
-
import { poseToWandelscriptString
|
|
2
|
+
import { poseToWandelscriptString } from "@wandelbots/nova-js"
|
|
3
|
+
import type { TcpPose } from "@wandelbots/nova-js/v1"
|
|
3
4
|
import { observer } from "mobx-react-lite"
|
|
4
5
|
import { useState } from "react"
|
|
5
6
|
import { externalizeComponent } from "../../externalizeComponent"
|
|
6
7
|
import { CopyableText } from "../CopyableText"
|
|
7
8
|
|
|
8
9
|
export type PoseCartesianValuesProps = {
|
|
9
|
-
tcpPose:
|
|
10
|
+
tcpPose: TcpPose
|
|
10
11
|
showCopyButton?: boolean
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -43,7 +44,7 @@ export const PoseCartesianValues = externalizeComponent(
|
|
|
43
44
|
onClick={handleCopy}
|
|
44
45
|
sx={{ flexShrink: 0 }}
|
|
45
46
|
>
|
|
46
|
-
{copyMessage ? copyMessage : "Copy"}
|
|
47
|
+
{ copyMessage ? copyMessage : "Copy"}
|
|
47
48
|
</Button>
|
|
48
49
|
)}
|
|
49
50
|
</Stack>
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Button, Stack } from "@mui/material"
|
|
2
|
+
import type { Joints } from "@wandelbots/nova-api/v1"
|
|
2
3
|
import { observer } from "mobx-react-lite"
|
|
3
4
|
import { useState } from "react"
|
|
4
5
|
import { externalizeComponent } from "../../externalizeComponent"
|
|
5
6
|
import { CopyableText } from "../CopyableText"
|
|
6
7
|
|
|
7
8
|
export type PoseJointValuesProps = {
|
|
8
|
-
joints:
|
|
9
|
+
joints: Joints
|
|
9
10
|
showCopyButton?: boolean
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export const PoseJointValues = externalizeComponent(
|
|
13
14
|
observer(({ joints, showCopyButton = false }: PoseJointValuesProps) => {
|
|
14
15
|
const [copyMessage, setCopyMessage] = useState<string | null>(null)
|
|
15
|
-
const poseString = `[${joints.map((j: number) => parseFloat(j.toFixed(4))).join(", ")}]`
|
|
16
|
+
const poseString = `[${joints.joints.map((j: number) => parseFloat(j.toFixed(4))).join(", ")}]`
|
|
16
17
|
|
|
17
18
|
const handleCopy = async () => {
|
|
18
19
|
try {
|
|
@@ -42,7 +43,7 @@ export const PoseJointValues = externalizeComponent(
|
|
|
42
43
|
onClick={handleCopy}
|
|
43
44
|
sx={{ flexShrink: 0 }}
|
|
44
45
|
>
|
|
45
|
-
{copyMessage ? copyMessage : "Copy"}
|
|
46
|
+
{ copyMessage ? copyMessage : "Copy"}
|
|
46
47
|
</Button>
|
|
47
48
|
)}
|
|
48
49
|
</Stack>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Line } from "@react-three/drei"
|
|
2
|
-
import type { DHParameter } from "@wandelbots/nova-
|
|
2
|
+
import type { DHParameter } from "@wandelbots/nova-api/v1"
|
|
3
3
|
import React, { useRef } from "react"
|
|
4
4
|
import type * as THREE from "three"
|
|
5
5
|
import { Matrix4, Quaternion, Vector3 } from "three"
|
|
@@ -113,7 +113,8 @@ export function DHRobot({
|
|
|
113
113
|
{dhParameters!.map((param, index) => {
|
|
114
114
|
const { a, b } = getLinePoints(
|
|
115
115
|
param,
|
|
116
|
-
rapidlyChangingMotionState.joint_position[index] ??
|
|
116
|
+
rapidlyChangingMotionState.state.joint_position.joints[index] ??
|
|
117
|
+
0,
|
|
117
118
|
)
|
|
118
119
|
const jointName = `dhrobot_J0${index}`
|
|
119
120
|
return (
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useGLTF } from "@react-three/drei"
|
|
2
2
|
import type { ThreeElements } from "@react-three/fiber"
|
|
3
|
-
import React, { useCallback
|
|
3
|
+
import React, { useCallback } from "react"
|
|
4
4
|
import type { Group, Mesh } from "three"
|
|
5
5
|
import { type Object3D } from "three"
|
|
6
6
|
import { isFlange, parseRobotModel } from "./robotModelLogic"
|
|
7
7
|
|
|
8
8
|
export type RobotModelProps = {
|
|
9
|
-
modelURL: string
|
|
9
|
+
modelURL: string
|
|
10
10
|
/**
|
|
11
11
|
* Called after a robot model has been loaded and
|
|
12
12
|
* rendered into the threejs scene
|
|
@@ -19,25 +19,16 @@ function isMesh(node: Object3D): node is Mesh {
|
|
|
19
19
|
return node.type === "Mesh"
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} & ThreeElements["group"]) {
|
|
33
|
-
const gltfResult = useGLTF(url)
|
|
34
|
-
let gltf
|
|
35
|
-
try {
|
|
36
|
-
const parsed = parseRobotModel(gltfResult, 'robot.glb')
|
|
37
|
-
gltf = parsed.gltf
|
|
38
|
-
} catch (err) {
|
|
39
|
-
throw err;
|
|
40
|
-
}
|
|
22
|
+
export function GenericRobot({
|
|
23
|
+
modelURL,
|
|
24
|
+
flangeRef,
|
|
25
|
+
postModelRender,
|
|
26
|
+
...props
|
|
27
|
+
}: RobotModelProps) {
|
|
28
|
+
const { gltf } = parseRobotModel(
|
|
29
|
+
useGLTF(modelURL),
|
|
30
|
+
modelURL.split("/").pop() || modelURL,
|
|
31
|
+
)
|
|
41
32
|
|
|
42
33
|
const groupRef: React.RefCallback<Group> = useCallback(
|
|
43
34
|
(group) => {
|
|
@@ -45,45 +36,33 @@ function LoadedRobotModel({
|
|
|
45
36
|
postModelRender()
|
|
46
37
|
}
|
|
47
38
|
},
|
|
48
|
-
[
|
|
39
|
+
[modelURL],
|
|
49
40
|
)
|
|
50
41
|
|
|
51
42
|
function renderNode(node: Object3D): React.ReactNode {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
key={node.uuid}
|
|
76
|
-
position={node.position}
|
|
77
|
-
rotation={node.rotation}
|
|
78
|
-
ref={isFlange(node) ? flangeRef : undefined}
|
|
79
|
-
>
|
|
80
|
-
{node.children.map(renderNode)}
|
|
81
|
-
</group>
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
} catch (e) {
|
|
85
|
-
console.warn('Error rendering node', node.name, e)
|
|
86
|
-
return null
|
|
43
|
+
if (isMesh(node)) {
|
|
44
|
+
return (
|
|
45
|
+
<mesh
|
|
46
|
+
name={node.name}
|
|
47
|
+
key={node.uuid}
|
|
48
|
+
geometry={node.geometry}
|
|
49
|
+
material={node.material}
|
|
50
|
+
position={node.position}
|
|
51
|
+
rotation={node.rotation}
|
|
52
|
+
/>
|
|
53
|
+
)
|
|
54
|
+
} else {
|
|
55
|
+
return (
|
|
56
|
+
<group
|
|
57
|
+
name={node.name}
|
|
58
|
+
key={node.uuid}
|
|
59
|
+
position={node.position}
|
|
60
|
+
rotation={node.rotation}
|
|
61
|
+
ref={isFlange(node) ? flangeRef : undefined}
|
|
62
|
+
>
|
|
63
|
+
{node.children.map(renderNode)}
|
|
64
|
+
</group>
|
|
65
|
+
)
|
|
87
66
|
}
|
|
88
67
|
}
|
|
89
68
|
|
|
@@ -93,43 +72,3 @@ function LoadedRobotModel({
|
|
|
93
72
|
</group>
|
|
94
73
|
)
|
|
95
74
|
}
|
|
96
|
-
|
|
97
|
-
export function GenericRobot({
|
|
98
|
-
modelURL,
|
|
99
|
-
flangeRef,
|
|
100
|
-
postModelRender,
|
|
101
|
-
...props
|
|
102
|
-
}: RobotModelProps) {
|
|
103
|
-
const [resolvedURL, setResolvedURL] = useState<string | null>(null)
|
|
104
|
-
|
|
105
|
-
useEffect(() => {
|
|
106
|
-
const resolveURL = async () => {
|
|
107
|
-
try {
|
|
108
|
-
if (typeof modelURL === 'string') {
|
|
109
|
-
setResolvedURL(modelURL)
|
|
110
|
-
} else {
|
|
111
|
-
const url = await modelURL
|
|
112
|
-
setResolvedURL(url)
|
|
113
|
-
}
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error('Failed to resolve model URL:', error)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
resolveURL()
|
|
120
|
-
}, [modelURL])
|
|
121
|
-
|
|
122
|
-
// Don't render until we have a resolved URL
|
|
123
|
-
if (!resolvedURL) {
|
|
124
|
-
return null // Loading state
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return (
|
|
128
|
-
<LoadedRobotModel
|
|
129
|
-
url={resolvedURL}
|
|
130
|
-
flangeRef={flangeRef}
|
|
131
|
-
postModelRender={postModelRender}
|
|
132
|
-
{...props}
|
|
133
|
-
/>
|
|
134
|
-
)
|
|
135
|
-
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { ThreeElements } from "@react-three/fiber"
|
|
2
2
|
|
|
3
|
+
import type { ConnectedMotionGroup } from "@wandelbots/nova-js/v1"
|
|
3
4
|
import type { Group } from "three"
|
|
4
|
-
import type { ConnectedMotionGroup } from "../../lib/ConnectedMotionGroup"
|
|
5
5
|
import { defaultGetModel } from "./robotModelLogic"
|
|
6
6
|
import { SupportedRobot } from "./SupportedRobot"
|
|
7
7
|
|
|
8
8
|
export type RobotProps = {
|
|
9
9
|
connectedMotionGroup: ConnectedMotionGroup
|
|
10
|
-
getModel?: (modelFromController: string) =>
|
|
10
|
+
getModel?: (modelFromController: string) => string
|
|
11
11
|
flangeRef?: React.Ref<Group>
|
|
12
12
|
transparentColor?: string
|
|
13
13
|
postModelRender?: () => void
|
|
@@ -51,5 +51,3 @@ export function Robot({
|
|
|
51
51
|
/>
|
|
52
52
|
)
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
export { defaultGetModel }
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
DHParameter,
|
|
3
|
+
MotionGroupStateResponse,
|
|
4
|
+
} from "@wandelbots/nova-api/v1"
|
|
2
5
|
import { describe, expect, it, vi } from "vitest"
|
|
3
6
|
import RobotAnimator from "./RobotAnimator"
|
|
4
7
|
|
|
@@ -23,8 +26,12 @@ describe("RobotAnimator", () => {
|
|
|
23
26
|
|
|
24
27
|
it("should handle props with different numbers of joints", () => {
|
|
25
28
|
// Test that the component accepts different numbers of DH parameters
|
|
26
|
-
const mockMotionState4Joints:
|
|
27
|
-
|
|
29
|
+
const mockMotionState4Joints: MotionGroupStateResponse = {
|
|
30
|
+
state: {
|
|
31
|
+
joint_position: {
|
|
32
|
+
joints: [0.1, 0.2, 0.3, 0.4],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
28
35
|
} as any
|
|
29
36
|
|
|
30
37
|
const mockDHParameters4Joints: DHParameter[] = [
|
|
@@ -34,8 +41,12 @@ describe("RobotAnimator", () => {
|
|
|
34
41
|
{ theta: 0, reverse_rotation_direction: false },
|
|
35
42
|
]
|
|
36
43
|
|
|
37
|
-
const mockMotionState7Joints:
|
|
38
|
-
|
|
44
|
+
const mockMotionState7Joints: MotionGroupStateResponse = {
|
|
45
|
+
state: {
|
|
46
|
+
joint_position: {
|
|
47
|
+
joints: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
39
50
|
} as any
|
|
40
51
|
|
|
41
52
|
const mockDHParameters7Joints: DHParameter[] = Array(7).fill({
|
|
@@ -52,7 +63,9 @@ describe("RobotAnimator", () => {
|
|
|
52
63
|
}
|
|
53
64
|
// Verify props are correctly typed
|
|
54
65
|
expect(props4.dhParameters).toHaveLength(4)
|
|
55
|
-
expect(
|
|
66
|
+
expect(
|
|
67
|
+
props4.rapidlyChangingMotionState.state.joint_position.joints,
|
|
68
|
+
).toHaveLength(4)
|
|
56
69
|
}).not.toThrow()
|
|
57
70
|
|
|
58
71
|
expect(() => {
|
|
@@ -62,7 +75,9 @@ describe("RobotAnimator", () => {
|
|
|
62
75
|
children: null,
|
|
63
76
|
}
|
|
64
77
|
expect(props7.dhParameters).toHaveLength(7)
|
|
65
|
-
expect(
|
|
78
|
+
expect(
|
|
79
|
+
props7.rapidlyChangingMotionState.state.joint_position.joints,
|
|
80
|
+
).toHaveLength(7)
|
|
66
81
|
}).not.toThrow()
|
|
67
82
|
})
|
|
68
83
|
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { useFrame, useThree } from "@react-three/fiber"
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type {
|
|
3
|
+
DHParameter,
|
|
4
|
+
MotionGroupStateResponse,
|
|
5
|
+
} from "@wandelbots/nova-api/v1"
|
|
6
|
+
import React, { useCallback, useEffect, useRef } from "react"
|
|
4
7
|
import type { Group, Object3D } from "three"
|
|
5
8
|
import { useAutorun } from "../utils/hooks"
|
|
6
9
|
import { ValueInterpolator } from "../utils/interpolation"
|
|
7
10
|
import { collectJoints } from "./robotModelLogic"
|
|
8
11
|
|
|
9
12
|
type RobotAnimatorProps = {
|
|
10
|
-
rapidlyChangingMotionState:
|
|
13
|
+
rapidlyChangingMotionState: MotionGroupStateResponse
|
|
11
14
|
dhParameters: DHParameter[]
|
|
12
15
|
onRotationChanged?: (joints: Object3D[], jointValues: number[]) => void
|
|
13
16
|
children: React.ReactNode
|
|
@@ -26,9 +29,10 @@ export default function RobotAnimator({
|
|
|
26
29
|
|
|
27
30
|
// Initialize interpolator
|
|
28
31
|
useEffect(() => {
|
|
29
|
-
const initialJointValues =
|
|
30
|
-
(
|
|
31
|
-
|
|
32
|
+
const initialJointValues =
|
|
33
|
+
rapidlyChangingMotionState.state.joint_position.joints.filter(
|
|
34
|
+
(item) => item !== undefined,
|
|
35
|
+
)
|
|
32
36
|
|
|
33
37
|
interpolatorRef.current = new ValueInterpolator(initialJointValues, {
|
|
34
38
|
tension: 120, // Controls spring stiffness - higher values create faster, more responsive motion
|
|
@@ -82,9 +86,10 @@ export default function RobotAnimator({
|
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
const updateJoints = useCallback(() => {
|
|
85
|
-
const newJointValues =
|
|
86
|
-
(
|
|
87
|
-
|
|
89
|
+
const newJointValues =
|
|
90
|
+
rapidlyChangingMotionState.state.joint_position.joints.filter(
|
|
91
|
+
(item) => item !== undefined,
|
|
92
|
+
)
|
|
88
93
|
|
|
89
94
|
requestAnimationFrame(() => {
|
|
90
95
|
jointValues.current = newJointValues
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ThreeElements } from "@react-three/fiber"
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
DHParameter,
|
|
4
|
+
MotionGroupStateResponse,
|
|
5
|
+
} from "@wandelbots/nova-api/v1"
|
|
3
6
|
import { Suspense, useCallback, useEffect, useState } from "react"
|
|
4
7
|
import { DHRobot } from "./DHRobot"
|
|
5
8
|
|
|
@@ -13,16 +16,16 @@ import { applyGhostStyle, removeGhostStyle } from "./ghostStyle"
|
|
|
13
16
|
import { defaultGetModel } from "./robotModelLogic"
|
|
14
17
|
|
|
15
18
|
export type DHRobotProps = {
|
|
16
|
-
rapidlyChangingMotionState:
|
|
19
|
+
rapidlyChangingMotionState: MotionGroupStateResponse
|
|
17
20
|
dhParameters: Array<DHParameter>
|
|
18
21
|
} & ThreeElements["group"]
|
|
19
22
|
|
|
20
23
|
export type SupportedRobotProps = {
|
|
21
|
-
rapidlyChangingMotionState:
|
|
24
|
+
rapidlyChangingMotionState: MotionGroupStateResponse
|
|
22
25
|
modelFromController: string
|
|
23
26
|
dhParameters: DHParameter[]
|
|
24
27
|
flangeRef?: React.Ref<THREE.Group>
|
|
25
|
-
getModel?: (modelFromController: string) =>
|
|
28
|
+
getModel?: (modelFromController: string) => string
|
|
26
29
|
postModelRender?: () => void
|
|
27
30
|
transparentColor?: string
|
|
28
31
|
} & ThreeElements["group"]
|
|
@@ -67,7 +70,7 @@ export const SupportedRobot = externalizeComponent(
|
|
|
67
70
|
fallback={dhrobot}
|
|
68
71
|
onError={(err) => {
|
|
69
72
|
// Missing model; show the fallback for now
|
|
70
|
-
console.
|
|
73
|
+
console.error(err)
|
|
71
74
|
}}
|
|
72
75
|
>
|
|
73
76
|
<Suspense fallback={dhrobot}>
|
|
@@ -77,15 +80,7 @@ export const SupportedRobot = externalizeComponent(
|
|
|
77
80
|
dhParameters={dhParameters}
|
|
78
81
|
>
|
|
79
82
|
<GenericRobot
|
|
80
|
-
modelURL={(
|
|
81
|
-
const result = getModel(modelFromController)
|
|
82
|
-
if (!result) {
|
|
83
|
-
const mockBlob = new Blob([], { type: 'model/gltf-binary' })
|
|
84
|
-
const mockFile = new File([mockBlob], `${modelFromController}.glb`, { type: 'model/gltf-binary' })
|
|
85
|
-
return Promise.resolve(URL.createObjectURL(mockFile))
|
|
86
|
-
}
|
|
87
|
-
return result
|
|
88
|
-
})()}
|
|
83
|
+
modelURL={getModel(modelFromController)}
|
|
89
84
|
postModelRender={postModelRender}
|
|
90
85
|
flangeRef={flangeRef}
|
|
91
86
|
{...props}
|