@wandelbots/nova-js 3.6.1-pr.270.f77f20a → 3.7.0-pr.267.1acb341

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.
@@ -1,2035 +0,0 @@
1
- const require_LoginWithAuth0 = require("./LoginWithAuth0-oZFpwe7m.cjs");
2
- let axios = require("axios");
3
- axios = require_LoginWithAuth0.__toESM(axios, 1);
4
- let url_join = require("url-join");
5
- url_join = require_LoginWithAuth0.__toESM(url_join, 1);
6
- let mobx = require("mobx");
7
- let three = require("three");
8
- three = require_LoginWithAuth0.__toESM(three, 1);
9
- let three_src_math_Vector3_js = require("three/src/math/Vector3.js");
10
- let _wandelbots_nova_api_v1 = require("@wandelbots/nova-api/v1");
11
- let path_to_regexp = require("path-to-regexp");
12
- path_to_regexp = require_LoginWithAuth0.__toESM(path_to_regexp, 1);
13
- //#region src/lib/v1/wandelscriptUtils.ts
14
- /**
15
- * Convert a Pose object representing a motion group position
16
- * into a string which represents that pose in Wandelscript.
17
- */
18
- function poseToWandelscriptString(pose) {
19
- const position = [
20
- pose.position.x,
21
- pose.position.y,
22
- pose.position.z
23
- ];
24
- const orientation = [
25
- pose.orientation?.x ?? 0,
26
- pose.orientation?.y ?? 0,
27
- pose.orientation?.z ?? 0
28
- ];
29
- const positionValues = position.map((v) => v.toFixed(1));
30
- const rotationValues = orientation.map((v) => v.toFixed(4));
31
- return `(${positionValues.concat(rotationValues).join(", ")})`;
32
- }
33
- //#endregion
34
- //#region src/lib/v1/motionStateUpdate.ts
35
- function jointValuesEqual(oldJointValues, newJointValues, changeDeltaThreshold) {
36
- if (newJointValues.length !== oldJointValues.length) return true;
37
- for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) if (Math.abs(newJointValues[jointIndex] - oldJointValues[jointIndex]) > changeDeltaThreshold) return false;
38
- return true;
39
- }
40
- function tcpPoseEqual(oldTcp, newTcp, changeDeltaThreshold) {
41
- if (oldTcp === void 0 && newTcp || oldTcp && newTcp === void 0) return false;
42
- if (oldTcp === void 0 || newTcp === void 0) return true;
43
- let changedDelta = 0;
44
- changedDelta += Math.abs(oldTcp.orientation.x - newTcp.orientation.x);
45
- changedDelta += Math.abs(oldTcp.orientation.y - newTcp.orientation.y);
46
- changedDelta += Math.abs(oldTcp.orientation.z - newTcp.orientation.z);
47
- changedDelta += Math.abs(oldTcp.position.x - newTcp.position.x);
48
- changedDelta += Math.abs(oldTcp.position.y - newTcp.position.y);
49
- changedDelta += Math.abs(oldTcp.position.z - newTcp.position.z);
50
- if (changedDelta > changeDeltaThreshold) return false;
51
- return oldTcp.coordinate_system === newTcp.coordinate_system && oldTcp.tcp === newTcp.tcp;
52
- }
53
- //#endregion
54
- //#region src/lib/v1/ConnectedMotionGroup.ts
55
- const MOTION_DELTA_THRESHOLD$1 = 1e-4;
56
- /**
57
- * Store representing the current state of a connected motion group.
58
- */
59
- var ConnectedMotionGroup = class ConnectedMotionGroup {
60
- static async connect(nova, motionGroupId, controllers) {
61
- const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
62
- const controller = controllers.find((c) => c.controller === controllerId);
63
- const motionGroup = controller?.physical_motion_groups.find((mg) => mg.motion_group === motionGroupId);
64
- if (!controller || !motionGroup) throw new Error(`Controller ${controllerId} or motion group ${motionGroupId} not found`);
65
- const motionStateSocket = nova.openReconnectingWebsocket(`/motion-groups/${motionGroupId}/state-stream`);
66
- const firstMessage = await motionStateSocket.firstMessage();
67
- const initialMotionState = require_LoginWithAuth0.tryParseJson(firstMessage.data)?.result;
68
- if (!initialMotionState) throw new Error(`Unable to parse initial motion state message ${firstMessage.data}`);
69
- console.log(`Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\n `, initialMotionState);
70
- const isVirtual = (await nova.api.controller.getRobotController(controller.controller)).configuration.kind === "VirtualController";
71
- const mounting = await (async () => {
72
- try {
73
- return await nova.api.motionGroupInfos.getMounting(motionGroup.motion_group);
74
- } catch (err) {
75
- console.error(`Error fetching mounting for ${motionGroup.motion_group}`, err);
76
- return null;
77
- }
78
- })();
79
- const controllerStateSocket = nova.openReconnectingWebsocket(`/controllers/${controller.controller}/state-stream?response_rate=1000`);
80
- const firstControllerMessage = await controllerStateSocket.firstMessage();
81
- const initialControllerState = require_LoginWithAuth0.tryParseJson(firstControllerMessage.data)?.result;
82
- if (!initialControllerState) throw new Error(`Unable to parse initial controller state message ${firstControllerMessage.data}`);
83
- console.log(`Connected controller state websocket to controller ${controller.controller}. Initial state:\n `, initialControllerState);
84
- const { tcps } = await nova.api.motionGroupInfos.listTcps(motionGroupId);
85
- return new ConnectedMotionGroup(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, await nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId), await nova.api.motionGroupInfos.getSafetySetup(motionGroupId), mounting, initialControllerState, controllerStateSocket);
86
- }
87
- constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup, mounting, initialControllerState, controllerStateSocket) {
88
- this.nova = nova;
89
- this.controller = controller;
90
- this.motionGroup = motionGroup;
91
- this.initialMotionState = initialMotionState;
92
- this.motionStateSocket = motionStateSocket;
93
- this.isVirtual = isVirtual;
94
- this.tcps = tcps;
95
- this.motionGroupSpecification = motionGroupSpecification;
96
- this.safetySetup = safetySetup;
97
- this.mounting = mounting;
98
- this.initialControllerState = initialControllerState;
99
- this.controllerStateSocket = controllerStateSocket;
100
- this.connectedJoggingCartesianSocket = null;
101
- this.connectedJoggingJointsSocket = null;
102
- this.joggingVelocity = 10;
103
- this.activationState = "inactive";
104
- this.rapidlyChangingMotionState = initialMotionState;
105
- this.controllerState = initialControllerState;
106
- controllerStateSocket.addEventListener("message", (event) => {
107
- const data = require_LoginWithAuth0.tryParseJson(event.data)?.result;
108
- if (!data) return;
109
- (0, mobx.runInAction)(() => {
110
- this.controllerState = data;
111
- });
112
- });
113
- motionStateSocket.addEventListener("message", (event) => {
114
- const motionStateResponse = require_LoginWithAuth0.tryParseJson(event.data)?.result;
115
- if (!motionStateResponse) throw new Error(`Failed to get motion state for ${this.motionGroupId}: ${event.data}`);
116
- if (!jointValuesEqual(this.rapidlyChangingMotionState.state.joint_position.joints, motionStateResponse.state.joint_position.joints, MOTION_DELTA_THRESHOLD$1)) (0, mobx.runInAction)(() => {
117
- this.rapidlyChangingMotionState.state = motionStateResponse.state;
118
- });
119
- if (!tcpPoseEqual(this.rapidlyChangingMotionState.tcp_pose, motionStateResponse.tcp_pose, MOTION_DELTA_THRESHOLD$1)) (0, mobx.runInAction)(() => {
120
- this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
121
- });
122
- });
123
- (0, mobx.makeAutoObservable)(this);
124
- }
125
- get motionGroupId() {
126
- return this.motionGroup.motion_group;
127
- }
128
- get controllerId() {
129
- return this.controller.controller;
130
- }
131
- get modelFromController() {
132
- return this.motionGroup.model_from_controller;
133
- }
134
- get wandelscriptIdentifier() {
135
- const num = this.motionGroupId.split("@")[0];
136
- return `${this.controllerId.replaceAll("-", "_")}_${num}`;
137
- }
138
- /** Jogging velocity in radians for rotation and joint movement */
139
- get joggingVelocityRads() {
140
- return this.joggingVelocity * Math.PI / 180;
141
- }
142
- get joints() {
143
- return this.initialMotionState.state.joint_position.joints.map((_, i) => {
144
- return { index: i };
145
- });
146
- }
147
- get dhParameters() {
148
- return this.motionGroupSpecification.dh_parameters;
149
- }
150
- get safetyZones() {
151
- return this.safetySetup.safety_zones;
152
- }
153
- /** Gets the robot mounting position offset in 3D viz coordinates */
154
- get mountingPosition() {
155
- if (!this.mounting) return [
156
- 0,
157
- 0,
158
- 0
159
- ];
160
- return [
161
- this.mounting.pose.position.x / 1e3,
162
- this.mounting.pose.position.y / 1e3,
163
- this.mounting.pose.position.z / 1e3
164
- ];
165
- }
166
- /** Gets the robot mounting position rotation in 3D viz coordinates */
167
- get mountingQuaternion() {
168
- const rotationVector = new three.Vector3(this.mounting?.pose.orientation?.x || 0, this.mounting?.pose.orientation?.y || 0, this.mounting?.pose.orientation?.z || 0);
169
- const magnitude = rotationVector.length();
170
- const axis = rotationVector.normalize();
171
- return new three.Quaternion().setFromAxisAngle(axis, magnitude);
172
- }
173
- /**
174
- * Whether the controller is currently in a safety state
175
- * corresponding to an emergency stop
176
- */
177
- get isEstopActive() {
178
- return ["SAFETY_STATE_ROBOT_EMERGENCY_STOP", "SAFETY_STATE_DEVICE_EMERGENCY_STOP"].includes(this.controllerState.safety_state);
179
- }
180
- /**
181
- * Whether the controller is in a safety state
182
- * that may be non-functional for robot pad purposes
183
- */
184
- get isMoveableSafetyState() {
185
- return ["SAFETY_STATE_NORMAL", "SAFETY_STATE_REDUCED"].includes(this.controllerState.safety_state);
186
- }
187
- /**
188
- * Whether the controller is in an operation mode that allows movement
189
- */
190
- get isMoveableOperationMode() {
191
- return [
192
- "OPERATION_MODE_AUTO",
193
- "OPERATION_MODE_MANUAL",
194
- "OPERATION_MODE_MANUAL_T1",
195
- "OPERATION_MODE_MANUAL_T2"
196
- ].includes(this.controllerState.operation_mode);
197
- }
198
- /**
199
- * Whether the robot is currently active and can be moved, based on the
200
- * safety state, operation mode and servo toggle activation state.
201
- */
202
- get canBeMoved() {
203
- return this.isMoveableSafetyState && this.isMoveableOperationMode && this.activationState === "active";
204
- }
205
- async deactivate() {
206
- if (this.activationState !== "active") {
207
- console.error("Tried to deactivate while already deactivating");
208
- return;
209
- }
210
- (0, mobx.runInAction)(() => {
211
- this.activationState = "deactivating";
212
- });
213
- try {
214
- await this.nova.api.controller.setDefaultMode(this.controllerId, "MODE_MONITOR");
215
- (0, mobx.runInAction)(() => {
216
- this.activationState = "inactive";
217
- });
218
- } catch (err) {
219
- (0, mobx.runInAction)(() => {
220
- this.activationState = "active";
221
- });
222
- throw err;
223
- }
224
- }
225
- async activate() {
226
- if (this.activationState !== "inactive") {
227
- console.error("Tried to activate while already activating");
228
- return;
229
- }
230
- (0, mobx.runInAction)(() => {
231
- this.activationState = "activating";
232
- });
233
- try {
234
- await this.nova.api.controller.setDefaultMode(this.controllerId, "MODE_CONTROL");
235
- (0, mobx.runInAction)(() => {
236
- this.activationState = "active";
237
- });
238
- } catch (err) {
239
- (0, mobx.runInAction)(() => {
240
- this.activationState = "inactive";
241
- });
242
- throw err;
243
- }
244
- }
245
- toggleActivation() {
246
- if (this.activationState === "inactive") this.activate();
247
- else if (this.activationState === "active") this.deactivate();
248
- }
249
- dispose() {
250
- this.motionStateSocket.close();
251
- if (this.connectedJoggingCartesianSocket) this.connectedJoggingCartesianSocket.close();
252
- if (this.connectedJoggingJointsSocket) this.connectedJoggingJointsSocket.close();
253
- }
254
- setJoggingVelocity(velocity) {
255
- this.joggingVelocity = velocity;
256
- }
257
- };
258
- //#endregion
259
- //#region src/lib/v1/JoggerConnection.ts
260
- var JoggerConnection = class JoggerConnection {
261
- static async open(nova, motionGroupId, opts = {}) {
262
- return new JoggerConnection(await nova.connectMotionStream(motionGroupId), opts);
263
- }
264
- constructor(motionStream, opts = {}) {
265
- this.motionStream = motionStream;
266
- this.opts = opts;
267
- this.cartesianWebsocket = null;
268
- this.jointWebsocket = null;
269
- this.cartesianJoggingOpts = {};
270
- }
271
- get motionGroupId() {
272
- return this.motionStream.motionGroupId;
273
- }
274
- get nova() {
275
- return this.motionStream.nova;
276
- }
277
- get numJoints() {
278
- return this.motionStream.joints.length;
279
- }
280
- get activeJoggingMode() {
281
- if (this.cartesianWebsocket) return "cartesian";
282
- if (this.jointWebsocket) return "joint";
283
- return "increment";
284
- }
285
- get activeWebsocket() {
286
- return this.cartesianWebsocket || this.jointWebsocket;
287
- }
288
- async stop() {
289
- if (this.cartesianWebsocket) this.cartesianWebsocket.sendJson({
290
- motion_group: this.motionGroupId,
291
- position_direction: {
292
- x: 0,
293
- y: 0,
294
- z: 0
295
- },
296
- rotation_direction: {
297
- x: 0,
298
- y: 0,
299
- z: 0
300
- },
301
- position_velocity: 0,
302
- rotation_velocity: 0,
303
- tcp: this.cartesianJoggingOpts.tcpId,
304
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
305
- });
306
- if (this.jointWebsocket) this.jointWebsocket.sendJson({
307
- motion_group: this.motionGroupId,
308
- joint_velocities: new Array(this.numJoints).fill(0)
309
- });
310
- }
311
- dispose() {
312
- if (this.cartesianWebsocket) this.cartesianWebsocket.dispose();
313
- if (this.jointWebsocket) this.jointWebsocket.dispose();
314
- }
315
- setJoggingMode(mode, cartesianJoggingOpts) {
316
- console.log("Setting jogging mode to", mode);
317
- if (cartesianJoggingOpts) {
318
- if (JSON.stringify(this.cartesianJoggingOpts) !== JSON.stringify(cartesianJoggingOpts)) {
319
- if (this.cartesianWebsocket) {
320
- this.cartesianWebsocket.dispose();
321
- this.cartesianWebsocket = null;
322
- }
323
- }
324
- this.cartesianJoggingOpts = cartesianJoggingOpts;
325
- }
326
- if (mode !== "cartesian" && this.cartesianWebsocket) {
327
- this.cartesianWebsocket.dispose();
328
- this.cartesianWebsocket = null;
329
- }
330
- if (mode !== "joint" && this.jointWebsocket) {
331
- this.jointWebsocket.dispose();
332
- this.jointWebsocket = null;
333
- }
334
- if (mode === "cartesian" && !this.cartesianWebsocket) {
335
- this.cartesianWebsocket = this.nova.openReconnectingWebsocket(`/motion-groups/move-tcp`);
336
- this.cartesianWebsocket.addEventListener("message", (ev) => {
337
- const data = require_LoginWithAuth0.tryParseJson(ev.data);
338
- if (data && "error" in data) if (this.opts.onError) this.opts.onError(ev.data);
339
- else throw new Error(ev.data);
340
- });
341
- }
342
- if (mode === "joint" && !this.jointWebsocket) {
343
- this.jointWebsocket = this.nova.openReconnectingWebsocket(`/motion-groups/move-joint`);
344
- this.jointWebsocket.addEventListener("message", (ev) => {
345
- const data = require_LoginWithAuth0.tryParseJson(ev.data);
346
- if (data && "error" in data) if (this.opts.onError) this.opts.onError(ev.data);
347
- else throw new Error(ev.data);
348
- });
349
- }
350
- }
351
- /**
352
- * Start rotation of a single robot joint at the specified velocity
353
- */
354
- async startJointRotation({ joint, direction, velocityRadsPerSec }) {
355
- if (!this.jointWebsocket) throw new Error("Joint jogging websocket not connected; call setJoggingMode first");
356
- const jointVelocities = new Array(this.numJoints).fill(0);
357
- jointVelocities[joint] = direction === "-" ? -velocityRadsPerSec : velocityRadsPerSec;
358
- this.jointWebsocket.sendJson({
359
- motion_group: this.motionGroupId,
360
- joint_velocities: jointVelocities
361
- });
362
- }
363
- /**
364
- * Start the TCP moving along a specified axis at a given velocity
365
- */
366
- async startTCPTranslation({ axis, direction, velocityMmPerSec }) {
367
- if (!this.cartesianWebsocket) throw new Error("Cartesian jogging websocket not connected; call setJoggingMode first");
368
- const zeroVector = {
369
- x: 0,
370
- y: 0,
371
- z: 0
372
- };
373
- const joggingVector = Object.assign({}, zeroVector);
374
- joggingVector[axis] = direction === "-" ? -1 : 1;
375
- this.cartesianWebsocket.sendJson({
376
- motion_group: this.motionGroupId,
377
- position_direction: joggingVector,
378
- rotation_direction: zeroVector,
379
- position_velocity: velocityMmPerSec,
380
- rotation_velocity: 0,
381
- tcp: this.cartesianJoggingOpts.tcpId,
382
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
383
- });
384
- }
385
- /**
386
- * Start the TCP rotating around a specified axis at a given velocity
387
- */
388
- async startTCPRotation({ axis, direction, velocityRadsPerSec }) {
389
- if (!this.cartesianWebsocket) throw new Error("Cartesian jogging websocket not connected; call setJoggingMode first");
390
- const zeroVector = {
391
- x: 0,
392
- y: 0,
393
- z: 0
394
- };
395
- const joggingVector = Object.assign({}, zeroVector);
396
- joggingVector[axis] = direction === "-" ? -1 : 1;
397
- this.cartesianWebsocket.sendJson({
398
- motion_group: this.motionGroupId,
399
- position_direction: zeroVector,
400
- rotation_direction: joggingVector,
401
- position_velocity: 0,
402
- rotation_velocity: velocityRadsPerSec,
403
- tcp: this.cartesianJoggingOpts.tcpId,
404
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
405
- });
406
- }
407
- /**
408
- * Move the robot by a fixed distance in a single cartesian
409
- * axis, either rotating or translating relative to the TCP.
410
- * Promise resolves only after the motion has completed.
411
- */
412
- async runIncrementalCartesianMotion({ currentTcpPose, currentJoints, coordSystemId, velocityInRelevantUnits, axis, direction, motion }) {
413
- const commands = [];
414
- if (!require_LoginWithAuth0.isSameCoordinateSystem(currentTcpPose.coordinate_system, coordSystemId)) throw new Error(`Current TCP pose coordinate system ${currentTcpPose.coordinate_system} does not match target coordinate system ${coordSystemId}`);
415
- if (motion.type === "translate") {
416
- const targetTcpPosition = Object.assign({}, currentTcpPose.position);
417
- targetTcpPosition[axis] += motion.distanceMm * (direction === "-" ? -1 : 1);
418
- commands.push({
419
- settings: { limits_override: { tcp_velocity_limit: velocityInRelevantUnits } },
420
- line: {
421
- position: targetTcpPosition,
422
- orientation: currentTcpPose.orientation,
423
- coordinate_system: coordSystemId
424
- }
425
- });
426
- } else if (motion.type === "rotate") {
427
- const currentRotationVector = new three_src_math_Vector3_js.Vector3(currentTcpPose.orientation.x, currentTcpPose.orientation.y, currentTcpPose.orientation.z);
428
- const currentRotationRad = currentRotationVector.length();
429
- const currentRotationDirection = currentRotationVector.clone().normalize();
430
- const differenceRotationRad = motion.distanceRads * (direction === "-" ? -1 : 1);
431
- const differenceRotationDirection = new three_src_math_Vector3_js.Vector3(0, 0, 0);
432
- differenceRotationDirection[axis] = 1;
433
- const f1 = Math.cos(.5 * differenceRotationRad) * Math.cos(.5 * currentRotationRad);
434
- const f2 = Math.sin(.5 * differenceRotationRad) * Math.sin(.5 * currentRotationRad);
435
- const f3 = Math.sin(.5 * differenceRotationRad) * Math.cos(.5 * currentRotationRad);
436
- const f4 = Math.cos(.5 * differenceRotationRad) * Math.sin(.5 * currentRotationRad);
437
- const dotProduct = differenceRotationDirection.dot(currentRotationDirection);
438
- const crossProduct = differenceRotationDirection.clone().cross(currentRotationDirection);
439
- const newRotationRad = 2 * Math.acos(f1 - f2 * dotProduct);
440
- const f5 = newRotationRad / Math.sin(.5 * newRotationRad);
441
- const targetTcpOrientation = new three_src_math_Vector3_js.Vector3().addScaledVector(crossProduct, f2).addScaledVector(differenceRotationDirection, f3).addScaledVector(currentRotationDirection, f4).multiplyScalar(f5);
442
- commands.push({
443
- settings: { limits_override: { tcp_orientation_velocity_limit: velocityInRelevantUnits } },
444
- line: {
445
- position: currentTcpPose.position,
446
- orientation: targetTcpOrientation,
447
- coordinate_system: coordSystemId
448
- }
449
- });
450
- }
451
- const motionPlanRes = await this.nova.api.motion.planMotion({
452
- motion_group: this.motionGroupId,
453
- start_joint_position: currentJoints,
454
- tcp: this.cartesianJoggingOpts.tcpId,
455
- commands
456
- });
457
- const plannedMotion = motionPlanRes.plan_successful_response?.motion;
458
- if (!plannedMotion) throw new Error(`Failed to plan jogging increment motion ${JSON.stringify(motionPlanRes)}`);
459
- await this.nova.api.motion.streamMoveForward(plannedMotion, 100, void 0, void 0, void 0, { timeout: 1e3 * 60 });
460
- }
461
- /**
462
- * Rotate a single robot joint by a fixed number of radians
463
- * Promise resolves only after the motion has completed.
464
- */
465
- async runIncrementalJointRotation({ joint, currentJoints, velocityRadsPerSec, direction, distanceRads }) {
466
- const targetJoints = [...currentJoints.joints];
467
- targetJoints[joint] += distanceRads * (direction === "-" ? -1 : 1);
468
- const jointVelocityLimits = new Array(currentJoints.joints.length).fill(velocityRadsPerSec);
469
- const motionPlanRes = await this.nova.api.motion.planMotion({
470
- motion_group: this.motionGroupId,
471
- start_joint_position: currentJoints,
472
- commands: [{
473
- settings: { limits_override: { joint_velocity_limits: { joints: jointVelocityLimits } } },
474
- joint_ptp: { joints: targetJoints }
475
- }]
476
- });
477
- const plannedMotion = motionPlanRes.plan_successful_response?.motion;
478
- if (!plannedMotion) {
479
- console.error("Failed to plan jogging increment motion", motionPlanRes);
480
- return;
481
- }
482
- await this.nova.api.motion.streamMoveForward(plannedMotion, 100, void 0, void 0, void 0, { timeout: 1e3 * 60 });
483
- }
484
- };
485
- //#endregion
486
- //#region src/lib/v1/MotionStreamConnection.ts
487
- const MOTION_DELTA_THRESHOLD = 1e-4;
488
- function unwrapRotationVector(newRotationVectorApi, currentRotationVectorApi) {
489
- const currentRotationVector = new three.Vector3(currentRotationVectorApi.x, currentRotationVectorApi.y, currentRotationVectorApi.z);
490
- const newRotationVector = new three.Vector3(newRotationVectorApi.x, newRotationVectorApi.y, newRotationVectorApi.z);
491
- const currentAngle = currentRotationVector.length();
492
- const currentAxis = currentRotationVector.normalize();
493
- let newAngle = newRotationVector.length();
494
- let newAxis = newRotationVector.normalize();
495
- if (newAxis.dot(currentAxis) < 0) {
496
- newAngle = -newAngle;
497
- newAxis = newAxis.multiplyScalar(-1);
498
- }
499
- let angleDifference = newAngle - currentAngle;
500
- angleDifference -= 2 * Math.PI * Math.floor((angleDifference + Math.PI) / (2 * Math.PI));
501
- newAngle = currentAngle + angleDifference;
502
- return newAxis.multiplyScalar(newAngle);
503
- }
504
- /**
505
- * Store representing the current state of a connected motion group.
506
- */
507
- var MotionStreamConnection = class MotionStreamConnection {
508
- static async open(nova, motionGroupId) {
509
- const { instances: controllers } = await nova.api.controller.listControllers();
510
- const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
511
- const controller = controllers.find((c) => c.controller === controllerId);
512
- const motionGroup = controller?.physical_motion_groups.find((mg) => mg.motion_group === motionGroupId);
513
- if (!controller || !motionGroup) throw new Error(`Controller ${controllerId} or motion group ${motionGroupId} not found`);
514
- const motionStateSocket = nova.openReconnectingWebsocket(`/motion-groups/${motionGroupId}/state-stream`);
515
- const firstMessage = await motionStateSocket.firstMessage();
516
- const initialMotionState = require_LoginWithAuth0.tryParseJson(firstMessage.data)?.result;
517
- if (!initialMotionState) throw new Error(`Unable to parse initial motion state message ${firstMessage.data}`);
518
- console.log(`Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\n `, initialMotionState);
519
- return new MotionStreamConnection(nova, controller, motionGroup, initialMotionState, motionStateSocket);
520
- }
521
- constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket) {
522
- this.nova = nova;
523
- this.controller = controller;
524
- this.motionGroup = motionGroup;
525
- this.initialMotionState = initialMotionState;
526
- this.motionStateSocket = motionStateSocket;
527
- this.rapidlyChangingMotionState = initialMotionState;
528
- motionStateSocket.addEventListener("message", (event) => {
529
- const motionStateResponse = require_LoginWithAuth0.tryParseJson(event.data)?.result;
530
- if (!motionStateResponse) throw new Error(`Failed to get motion state for ${this.motionGroupId}: ${event.data}`);
531
- if (!jointValuesEqual(this.rapidlyChangingMotionState.state.joint_position.joints, motionStateResponse.state.joint_position.joints, MOTION_DELTA_THRESHOLD)) (0, mobx.runInAction)(() => {
532
- this.rapidlyChangingMotionState.state = motionStateResponse.state;
533
- });
534
- if (!tcpPoseEqual(this.rapidlyChangingMotionState.tcp_pose, motionStateResponse.tcp_pose, MOTION_DELTA_THRESHOLD)) (0, mobx.runInAction)(() => {
535
- if (this.rapidlyChangingMotionState.tcp_pose == null) this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
536
- else this.rapidlyChangingMotionState.tcp_pose = {
537
- position: motionStateResponse.tcp_pose.position,
538
- orientation: unwrapRotationVector(motionStateResponse.tcp_pose.orientation, this.rapidlyChangingMotionState.tcp_pose.orientation),
539
- tcp: motionStateResponse.tcp_pose.tcp,
540
- coordinate_system: motionStateResponse.tcp_pose.coordinate_system
541
- };
542
- });
543
- });
544
- (0, mobx.makeAutoObservable)(this);
545
- }
546
- get motionGroupId() {
547
- return this.motionGroup.motion_group;
548
- }
549
- get controllerId() {
550
- return this.controller.controller;
551
- }
552
- get modelFromController() {
553
- return this.motionGroup.model_from_controller;
554
- }
555
- get wandelscriptIdentifier() {
556
- const num = this.motionGroupId.split("@")[0];
557
- return `${this.controllerId.replaceAll("-", "_")}_${num}`;
558
- }
559
- get joints() {
560
- return this.initialMotionState.state.joint_position.joints.map((_, i) => {
561
- return { index: i };
562
- });
563
- }
564
- dispose() {
565
- this.motionStateSocket.close();
566
- }
567
- };
568
- //#endregion
569
- //#region src/lib/v1/NovaCellAPIClient.ts
570
- /**
571
- * API client providing type-safe access to all the Nova API REST endpoints
572
- * associated with a specific cell id.
573
- */
574
- var NovaCellAPIClient = class {
575
- constructor(cellId, opts) {
576
- this.cellId = cellId;
577
- this.opts = opts;
578
- this.system = this.withUnwrappedResponsesOnly(_wandelbots_nova_api_v1.SystemApi);
579
- this.cell = this.withUnwrappedResponsesOnly(_wandelbots_nova_api_v1.CellApi);
580
- this.deviceConfig = this.withCellId(_wandelbots_nova_api_v1.DeviceConfigurationApi);
581
- this.motionGroup = this.withCellId(_wandelbots_nova_api_v1.MotionGroupApi);
582
- this.motionGroupInfos = this.withCellId(_wandelbots_nova_api_v1.MotionGroupInfosApi);
583
- this.controller = this.withCellId(_wandelbots_nova_api_v1.ControllerApi);
584
- this.program = this.withCellId(_wandelbots_nova_api_v1.ProgramApi);
585
- this.programValues = this.withCellId(_wandelbots_nova_api_v1.ProgramValuesApi);
586
- this.controllerIOs = this.withCellId(_wandelbots_nova_api_v1.ControllerIOsApi);
587
- this.motionGroupKinematic = this.withCellId(_wandelbots_nova_api_v1.MotionGroupKinematicApi);
588
- this.motion = this.withCellId(_wandelbots_nova_api_v1.MotionApi);
589
- this.coordinateSystems = this.withCellId(_wandelbots_nova_api_v1.CoordinateSystemsApi);
590
- this.application = this.withCellId(_wandelbots_nova_api_v1.ApplicationApi);
591
- this.applicationGlobal = this.withUnwrappedResponsesOnly(_wandelbots_nova_api_v1.ApplicationApi);
592
- this.motionGroupJogging = this.withCellId(_wandelbots_nova_api_v1.MotionGroupJoggingApi);
593
- this.virtualRobot = this.withCellId(_wandelbots_nova_api_v1.VirtualRobotApi);
594
- this.virtualRobotSetup = this.withCellId(_wandelbots_nova_api_v1.VirtualRobotSetupApi);
595
- this.virtualRobotMode = this.withCellId(_wandelbots_nova_api_v1.VirtualRobotModeApi);
596
- this.virtualRobotBehavior = this.withCellId(_wandelbots_nova_api_v1.VirtualRobotBehaviorApi);
597
- this.libraryProgramMetadata = this.withCellId(_wandelbots_nova_api_v1.LibraryProgramMetadataApi);
598
- this.libraryProgram = this.withCellId(_wandelbots_nova_api_v1.LibraryProgramApi);
599
- this.libraryRecipeMetadata = this.withCellId(_wandelbots_nova_api_v1.LibraryRecipeMetadataApi);
600
- this.libraryRecipe = this.withCellId(_wandelbots_nova_api_v1.LibraryRecipeApi);
601
- this.storeObject = this.withCellId(_wandelbots_nova_api_v1.StoreObjectApi);
602
- this.storeCollisionComponents = this.withCellId(_wandelbots_nova_api_v1.StoreCollisionComponentsApi);
603
- this.storeCollisionScenes = this.withCellId(_wandelbots_nova_api_v1.StoreCollisionScenesApi);
604
- }
605
- /**
606
- * Some TypeScript sorcery which alters the API class methods so you don't
607
- * have to pass the cell id to every single one, and de-encapsulates the
608
- * response data
609
- */
610
- withCellId(ApiConstructor) {
611
- const apiClient = new ApiConstructor({
612
- ...this.opts,
613
- isJsonMime: (mime) => {
614
- return mime === "application/json";
615
- }
616
- }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.default.create());
617
- for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) if (key !== "constructor" && typeof apiClient[key] === "function") {
618
- const originalFunction = apiClient[key];
619
- apiClient[key] = (...args) => {
620
- return originalFunction.apply(apiClient, [this.cellId, ...args]).then((res) => res.data);
621
- };
622
- }
623
- return apiClient;
624
- }
625
- /**
626
- * As withCellId, but only does the response unwrapping
627
- */
628
- withUnwrappedResponsesOnly(ApiConstructor) {
629
- const apiClient = new ApiConstructor({
630
- ...this.opts,
631
- isJsonMime: (mime) => {
632
- return mime === "application/json";
633
- }
634
- }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.default.create());
635
- for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) if (key !== "constructor" && typeof apiClient[key] === "function") {
636
- const originalFunction = apiClient[key];
637
- apiClient[key] = (...args) => {
638
- return originalFunction.apply(apiClient, args).then((res) => res.data);
639
- };
640
- }
641
- return apiClient;
642
- }
643
- };
644
- //#endregion
645
- //#region src/lib/v1/mock/MockNovaInstance.ts
646
- /**
647
- * Ultra-simplified mock Nova server for testing stuff
648
- */
649
- var MockNovaInstance = class {
650
- constructor() {
651
- this.connections = [];
652
- }
653
- async handleAPIRequest(config) {
654
- const apiHandlers = [
655
- {
656
- method: "GET",
657
- path: "/cells/:cellId/controllers",
658
- handle() {
659
- return { instances: [{
660
- controller: "mock-ur5e",
661
- model_name: "UniversalRobots::Controller",
662
- host: "mock-ur5e",
663
- allow_software_install_on_controller: true,
664
- physical_motion_groups: [{
665
- motion_group: "0@mock-ur5e",
666
- name_from_controller: "UR5e",
667
- active: false,
668
- model_from_controller: "UniversalRobots_UR5e"
669
- }],
670
- has_error: false,
671
- error_details: ""
672
- }] };
673
- }
674
- },
675
- {
676
- method: "GET",
677
- path: "/cells/:cellId/controllers/:controllerId",
678
- handle() {
679
- return {
680
- configuration: {
681
- kind: "VirtualController",
682
- manufacturer: "universalrobots",
683
- position: "[0,-1.571,-1.571,-1.571,1.571,-1.571,0]",
684
- type: "universalrobots-ur5e"
685
- },
686
- name: "mock-ur5"
687
- };
688
- }
689
- },
690
- {
691
- method: "GET",
692
- path: "/cells/:cellId/motion-groups/:motionGroupId/specification",
693
- handle() {
694
- return {
695
- dh_parameters: [
696
- {
697
- alpha: 1.5707963267948966,
698
- theta: 0,
699
- a: 0,
700
- d: 162.25,
701
- reverse_rotation_direction: false
702
- },
703
- {
704
- alpha: 0,
705
- theta: 0,
706
- a: -425,
707
- d: 0,
708
- reverse_rotation_direction: false
709
- },
710
- {
711
- alpha: 0,
712
- theta: 0,
713
- a: -392.2,
714
- d: 0,
715
- reverse_rotation_direction: false
716
- },
717
- {
718
- alpha: 1.5707963267948966,
719
- theta: 0,
720
- a: 0,
721
- d: 133.3,
722
- reverse_rotation_direction: false
723
- },
724
- {
725
- alpha: -1.5707963267948966,
726
- theta: 0,
727
- a: 0,
728
- d: 99.7,
729
- reverse_rotation_direction: false
730
- },
731
- {
732
- alpha: 0,
733
- theta: 0,
734
- a: 0,
735
- d: 99.6,
736
- reverse_rotation_direction: false
737
- }
738
- ],
739
- mechanical_joint_limits: [
740
- {
741
- joint: "JOINTNAME_AXIS_1",
742
- lower_limit: -6.335545063018799,
743
- upper_limit: 6.335545063018799,
744
- unlimited: false
745
- },
746
- {
747
- joint: "JOINTNAME_AXIS_2",
748
- lower_limit: -6.335545063018799,
749
- upper_limit: 6.335545063018799,
750
- unlimited: false
751
- },
752
- {
753
- joint: "JOINTNAME_AXIS_3",
754
- lower_limit: -6.335545063018799,
755
- upper_limit: 6.335545063018799,
756
- unlimited: false
757
- },
758
- {
759
- joint: "JOINTNAME_AXIS_4",
760
- lower_limit: -6.335545063018799,
761
- upper_limit: 6.335545063018799,
762
- unlimited: false
763
- },
764
- {
765
- joint: "JOINTNAME_AXIS_5",
766
- lower_limit: -6.335545063018799,
767
- upper_limit: 6.335545063018799,
768
- unlimited: false
769
- },
770
- {
771
- joint: "JOINTNAME_AXIS_6",
772
- lower_limit: -6.335545063018799,
773
- upper_limit: 6.335545063018799,
774
- unlimited: false
775
- }
776
- ]
777
- };
778
- }
779
- },
780
- {
781
- method: "GET",
782
- path: "/cells/:cellId/motion-groups/:motionGroupId/safety-setup",
783
- handle() {
784
- return {
785
- safety_settings: [{
786
- safety_state: "SAFETY_NORMAL",
787
- settings: {
788
- joint_position_limits: [
789
- {
790
- joint: "JOINTNAME_AXIS_1",
791
- lower_limit: -2.96705961227417,
792
- upper_limit: 2.96705961227417,
793
- unlimited: false
794
- },
795
- {
796
- joint: "JOINTNAME_AXIS_2",
797
- lower_limit: -1.7453292608261108,
798
- upper_limit: 2.7925267219543457,
799
- unlimited: false
800
- },
801
- {
802
- joint: "JOINTNAME_AXIS_3",
803
- lower_limit: -3.3161256313323975,
804
- upper_limit: .40142571926116943,
805
- unlimited: false
806
- },
807
- {
808
- joint: "JOINTNAME_AXIS_4",
809
- lower_limit: -3.4906585216522217,
810
- upper_limit: 3.4906585216522217,
811
- unlimited: false
812
- },
813
- {
814
- joint: "JOINTNAME_AXIS_5",
815
- lower_limit: -2.4434609413146973,
816
- upper_limit: 2.4434609413146973,
817
- unlimited: false
818
- },
819
- {
820
- joint: "JOINTNAME_AXIS_6",
821
- lower_limit: -4.71238899230957,
822
- upper_limit: 4.71238899230957,
823
- unlimited: false
824
- }
825
- ],
826
- joint_velocity_limits: [
827
- {
828
- joint: "JOINTNAME_AXIS_1",
829
- limit: 3.1415927410125732
830
- },
831
- {
832
- joint: "JOINTNAME_AXIS_2",
833
- limit: 3.1415927410125732
834
- },
835
- {
836
- joint: "JOINTNAME_AXIS_3",
837
- limit: 3.4906585216522217
838
- },
839
- {
840
- joint: "JOINTNAME_AXIS_4",
841
- limit: 6.108652591705322
842
- },
843
- {
844
- joint: "JOINTNAME_AXIS_5",
845
- limit: 6.108652591705322
846
- },
847
- {
848
- joint: "JOINTNAME_AXIS_6",
849
- limit: 6.981317043304443
850
- }
851
- ],
852
- joint_acceleration_limits: [],
853
- joint_torque_limits: [],
854
- tcp_velocity_limit: 1800
855
- }
856
- }],
857
- safety_zones: [
858
- {
859
- id: 1,
860
- priority: 0,
861
- geometry: {
862
- compound: { child_geometries: [
863
- {
864
- convex_hull: { vertices: [
865
- {
866
- x: -800,
867
- y: -1330,
868
- z: -1820
869
- },
870
- {
871
- x: 1650,
872
- y: -1330,
873
- z: -1820
874
- },
875
- {
876
- x: 1650,
877
- y: 1330,
878
- z: -1820
879
- },
880
- {
881
- x: -800,
882
- y: 1330,
883
- z: -1820
884
- }
885
- ] },
886
- init_pose: {
887
- position: {
888
- x: 0,
889
- y: 0,
890
- z: 0
891
- },
892
- orientation: {
893
- x: 0,
894
- y: 0,
895
- z: 0,
896
- w: 1
897
- }
898
- },
899
- id: "box"
900
- },
901
- {
902
- convex_hull: { vertices: [
903
- {
904
- x: -800,
905
- y: -1330,
906
- z: -1820
907
- },
908
- {
909
- x: 1650,
910
- y: -1330,
911
- z: -1820
912
- },
913
- {
914
- x: 1650,
915
- y: -1330,
916
- z: 1500
917
- },
918
- {
919
- x: -800,
920
- y: -1330,
921
- z: 1500
922
- }
923
- ] },
924
- init_pose: {
925
- position: {
926
- x: 0,
927
- y: 0,
928
- z: 0
929
- },
930
- orientation: {
931
- x: 0,
932
- y: 0,
933
- z: 0,
934
- w: 1
935
- }
936
- },
937
- id: "box"
938
- },
939
- {
940
- convex_hull: { vertices: [
941
- {
942
- x: -800,
943
- y: -1330,
944
- z: -1820
945
- },
946
- {
947
- x: -800,
948
- y: 1330,
949
- z: -1820
950
- },
951
- {
952
- x: -800,
953
- y: 1330,
954
- z: 1500
955
- },
956
- {
957
- x: -800,
958
- y: -1330,
959
- z: 1500
960
- }
961
- ] },
962
- init_pose: {
963
- position: {
964
- x: 0,
965
- y: 0,
966
- z: 0
967
- },
968
- orientation: {
969
- x: 0,
970
- y: 0,
971
- z: 0,
972
- w: 1
973
- }
974
- },
975
- id: "box"
976
- },
977
- {
978
- convex_hull: { vertices: [
979
- {
980
- x: 1650,
981
- y: 1330,
982
- z: 1500
983
- },
984
- {
985
- x: -800,
986
- y: 1330,
987
- z: 1500
988
- },
989
- {
990
- x: -800,
991
- y: -1330,
992
- z: 1500
993
- },
994
- {
995
- x: 1650,
996
- y: -1330,
997
- z: 1500
998
- }
999
- ] },
1000
- init_pose: {
1001
- position: {
1002
- x: 0,
1003
- y: 0,
1004
- z: 0
1005
- },
1006
- orientation: {
1007
- x: 0,
1008
- y: 0,
1009
- z: 0,
1010
- w: 1
1011
- }
1012
- },
1013
- id: "box"
1014
- },
1015
- {
1016
- convex_hull: { vertices: [
1017
- {
1018
- x: 1650,
1019
- y: 1330,
1020
- z: 1500
1021
- },
1022
- {
1023
- x: -800,
1024
- y: 1330,
1025
- z: 1500
1026
- },
1027
- {
1028
- x: -800,
1029
- y: 1330,
1030
- z: -1820
1031
- },
1032
- {
1033
- x: 1650,
1034
- y: 1330,
1035
- z: -1820
1036
- }
1037
- ] },
1038
- init_pose: {
1039
- position: {
1040
- x: 0,
1041
- y: 0,
1042
- z: 0
1043
- },
1044
- orientation: {
1045
- x: 0,
1046
- y: 0,
1047
- z: 0,
1048
- w: 1
1049
- }
1050
- },
1051
- id: "box"
1052
- },
1053
- {
1054
- convex_hull: { vertices: [
1055
- {
1056
- x: 1650,
1057
- y: 1330,
1058
- z: 1500
1059
- },
1060
- {
1061
- x: 1650,
1062
- y: -1330,
1063
- z: 1500
1064
- },
1065
- {
1066
- x: 1650,
1067
- y: -1330,
1068
- z: -1820
1069
- },
1070
- {
1071
- x: 1650,
1072
- y: 1330,
1073
- z: -1820
1074
- }
1075
- ] },
1076
- init_pose: {
1077
- position: {
1078
- x: 0,
1079
- y: 0,
1080
- z: 0
1081
- },
1082
- orientation: {
1083
- x: 0,
1084
- y: 0,
1085
- z: 0,
1086
- w: 1
1087
- }
1088
- },
1089
- id: "box"
1090
- }
1091
- ] },
1092
- init_pose: {
1093
- position: {
1094
- x: 0,
1095
- y: 0,
1096
- z: 0
1097
- },
1098
- orientation: {
1099
- x: 0,
1100
- y: 0,
1101
- z: 0,
1102
- w: 1
1103
- }
1104
- },
1105
- id: "Cell workzone"
1106
- },
1107
- motion_group_uid: 1
1108
- },
1109
- {
1110
- id: 2,
1111
- priority: 0,
1112
- geometry: {
1113
- convex_hull: { vertices: [
1114
- {
1115
- x: 1650,
1116
- y: 1330,
1117
- z: -1850
1118
- },
1119
- {
1120
- x: 865,
1121
- y: 1330,
1122
- z: -1850
1123
- },
1124
- {
1125
- x: 865,
1126
- y: -720,
1127
- z: -1850
1128
- },
1129
- {
1130
- x: 1650,
1131
- y: -720,
1132
- z: -1850
1133
- },
1134
- {
1135
- x: 1650,
1136
- y: 1330,
1137
- z: -920
1138
- },
1139
- {
1140
- x: 865,
1141
- y: 1330,
1142
- z: -920
1143
- },
1144
- {
1145
- x: 865,
1146
- y: -720,
1147
- z: -920
1148
- },
1149
- {
1150
- x: 1650,
1151
- y: -720,
1152
- z: -920
1153
- }
1154
- ] },
1155
- init_pose: {
1156
- position: {
1157
- x: 0,
1158
- y: 0,
1159
- z: 0
1160
- },
1161
- orientation: {
1162
- x: 0,
1163
- y: 0,
1164
- z: 0,
1165
- w: 1
1166
- }
1167
- },
1168
- id: "Transport"
1169
- },
1170
- motion_group_uid: 1
1171
- },
1172
- {
1173
- id: 3,
1174
- priority: 0,
1175
- geometry: {
1176
- convex_hull: { vertices: [
1177
- {
1178
- x: 1650,
1179
- y: 1330,
1180
- z: -600
1181
- },
1182
- {
1183
- x: 865,
1184
- y: 1330,
1185
- z: -600
1186
- },
1187
- {
1188
- x: 865,
1189
- y: 430,
1190
- z: -600
1191
- },
1192
- {
1193
- x: 1650,
1194
- y: 430,
1195
- z: -600
1196
- },
1197
- {
1198
- x: 1650,
1199
- y: 1330,
1200
- z: -1250
1201
- },
1202
- {
1203
- x: 865,
1204
- y: 1330,
1205
- z: -1250
1206
- },
1207
- {
1208
- x: 865,
1209
- y: 430,
1210
- z: -1250
1211
- },
1212
- {
1213
- x: 1650,
1214
- y: 430,
1215
- z: -1250
1216
- }
1217
- ] },
1218
- init_pose: {
1219
- position: {
1220
- x: 0,
1221
- y: 0,
1222
- z: 0
1223
- },
1224
- orientation: {
1225
- x: 0,
1226
- y: 0,
1227
- z: 0,
1228
- w: 1
1229
- }
1230
- },
1231
- id: "Tunel"
1232
- },
1233
- motion_group_uid: 1
1234
- },
1235
- {
1236
- id: 4,
1237
- priority: 0,
1238
- geometry: {
1239
- convex_hull: { vertices: [
1240
- {
1241
- x: 1650,
1242
- y: -760,
1243
- z: -440
1244
- },
1245
- {
1246
- x: 900,
1247
- y: -760,
1248
- z: -440
1249
- },
1250
- {
1251
- x: 900,
1252
- y: -1330,
1253
- z: -440
1254
- },
1255
- {
1256
- x: 1650,
1257
- y: -1330,
1258
- z: -440
1259
- },
1260
- {
1261
- x: 1650,
1262
- y: -760,
1263
- z: -1800
1264
- },
1265
- {
1266
- x: 900,
1267
- y: -760,
1268
- z: -1800
1269
- },
1270
- {
1271
- x: 900,
1272
- y: -1330,
1273
- z: -1800
1274
- },
1275
- {
1276
- x: 1650,
1277
- y: -1330,
1278
- z: -1800
1279
- }
1280
- ] },
1281
- init_pose: {
1282
- position: {
1283
- x: 0,
1284
- y: 0,
1285
- z: 0
1286
- },
1287
- orientation: {
1288
- x: 0,
1289
- y: 0,
1290
- z: 0,
1291
- w: 1
1292
- }
1293
- },
1294
- id: "Fanuc controller"
1295
- },
1296
- motion_group_uid: 1
1297
- },
1298
- {
1299
- id: 6,
1300
- priority: 0,
1301
- geometry: {
1302
- convex_hull: { vertices: [
1303
- {
1304
- x: -200,
1305
- y: -200,
1306
- z: -1900
1307
- },
1308
- {
1309
- x: 200,
1310
- y: -200,
1311
- z: -1900
1312
- },
1313
- {
1314
- x: 200,
1315
- y: 200,
1316
- z: -1900
1317
- },
1318
- {
1319
- x: -200,
1320
- y: 200,
1321
- z: -1900
1322
- },
1323
- {
1324
- x: -200,
1325
- y: -200,
1326
- z: -350
1327
- },
1328
- {
1329
- x: 200,
1330
- y: -200,
1331
- z: -350
1332
- },
1333
- {
1334
- x: 200,
1335
- y: 200,
1336
- z: -350
1337
- },
1338
- {
1339
- x: -200,
1340
- y: 200,
1341
- z: -350
1342
- }
1343
- ] },
1344
- init_pose: {
1345
- position: {
1346
- x: 0,
1347
- y: 0,
1348
- z: 0
1349
- },
1350
- orientation: {
1351
- x: 0,
1352
- y: 0,
1353
- z: 0,
1354
- w: 1
1355
- }
1356
- },
1357
- id: "Robot base"
1358
- },
1359
- motion_group_uid: 1
1360
- }
1361
- ],
1362
- robot_model_geometries: [
1363
- {
1364
- link_index: 1,
1365
- geometry: {
1366
- sphere: { radius: 270 },
1367
- init_pose: {
1368
- position: {
1369
- x: -70,
1370
- y: -70,
1371
- z: -50
1372
- },
1373
- orientation: {
1374
- x: 0,
1375
- y: 0,
1376
- z: 0,
1377
- w: 1
1378
- }
1379
- },
1380
- id: "link1_sphere"
1381
- }
1382
- },
1383
- {
1384
- link_index: 2,
1385
- geometry: {
1386
- capsule: {
1387
- radius: 160,
1388
- cylinder_height: 800
1389
- },
1390
- init_pose: {
1391
- position: {
1392
- x: -450,
1393
- y: 40,
1394
- z: 170
1395
- },
1396
- orientation: {
1397
- x: 0,
1398
- y: -Math.SQRT1_2,
1399
- z: 0,
1400
- w: Math.SQRT1_2
1401
- }
1402
- },
1403
- id: "link2_capsule"
1404
- }
1405
- },
1406
- {
1407
- link_index: 3,
1408
- geometry: {
1409
- sphere: { radius: 270 },
1410
- init_pose: {
1411
- position: {
1412
- x: -110,
1413
- y: 10,
1414
- z: -100
1415
- },
1416
- orientation: {
1417
- x: 0,
1418
- y: 0,
1419
- z: 0,
1420
- w: 1
1421
- }
1422
- },
1423
- id: "link3_sphere"
1424
- }
1425
- },
1426
- {
1427
- link_index: 4,
1428
- geometry: {
1429
- capsule: {
1430
- radius: 110,
1431
- cylinder_height: 600
1432
- },
1433
- init_pose: {
1434
- position: {
1435
- x: 0,
1436
- y: 300,
1437
- z: 40
1438
- },
1439
- orientation: {
1440
- x: -Math.SQRT1_2,
1441
- y: 0,
1442
- z: 0,
1443
- w: Math.SQRT1_2
1444
- }
1445
- },
1446
- id: "link4_capsule"
1447
- }
1448
- },
1449
- {
1450
- link_index: 5,
1451
- geometry: {
1452
- sphere: { radius: 75 },
1453
- init_pose: {
1454
- position: {
1455
- x: 0,
1456
- y: 0,
1457
- z: -50
1458
- },
1459
- orientation: {
1460
- x: 0,
1461
- y: 0,
1462
- z: 0,
1463
- w: 1
1464
- }
1465
- },
1466
- id: "link5_sphere"
1467
- }
1468
- }
1469
- ],
1470
- tool_geometries: []
1471
- };
1472
- }
1473
- },
1474
- {
1475
- method: "GET",
1476
- path: "/cells/:cellId/coordinate-systems",
1477
- handle() {
1478
- return { coordinatesystems: [{
1479
- coordinate_system: "",
1480
- name: "world",
1481
- reference_uid: "",
1482
- position: {
1483
- x: 0,
1484
- y: 0,
1485
- z: 0
1486
- },
1487
- rotation: {
1488
- angles: [
1489
- 0,
1490
- 0,
1491
- 0
1492
- ],
1493
- type: "ROTATION_VECTOR"
1494
- }
1495
- }] };
1496
- }
1497
- },
1498
- {
1499
- method: "GET",
1500
- path: "/cells/:cellId/motion-groups/:motionGroupId/tcps",
1501
- handle() {
1502
- return { tcps: [{
1503
- id: "Flange",
1504
- readable_name: "Default-Flange",
1505
- position: {
1506
- x: 0,
1507
- y: 0,
1508
- z: 0
1509
- },
1510
- rotation: {
1511
- angles: [
1512
- 0,
1513
- 0,
1514
- 0,
1515
- 0
1516
- ],
1517
- type: "ROTATION_VECTOR"
1518
- }
1519
- }, {
1520
- id: "complex-tcp-position",
1521
- readable_name: "Complex TCP Position",
1522
- position: {
1523
- x: -200,
1524
- y: 300,
1525
- z: 150
1526
- },
1527
- rotation: {
1528
- angles: [
1529
- -.12139440409113832,
1530
- -.06356210998212003,
1531
- -.2023240068185639,
1532
- 0
1533
- ],
1534
- type: "ROTATION_VECTOR"
1535
- }
1536
- }] };
1537
- }
1538
- }
1539
- ];
1540
- const method = config.method?.toUpperCase() || "GET";
1541
- const path = `/cells${config.url?.split("/cells")[1]?.split("?")[0]}`;
1542
- for (const handler of apiHandlers) {
1543
- const match = path_to_regexp.match(handler.path)(path || "");
1544
- if (method === handler.method && match) {
1545
- const json = handler.handle();
1546
- return {
1547
- status: 200,
1548
- statusText: "Success",
1549
- data: JSON.stringify(json),
1550
- headers: {},
1551
- config,
1552
- request: { responseURL: config.url }
1553
- };
1554
- }
1555
- }
1556
- throw new axios.AxiosError(`No mock handler matched this request: ${method} ${path}`, "404", config);
1557
- }
1558
- handleWebsocketConnection(socket) {
1559
- this.connections.push(socket);
1560
- setTimeout(() => {
1561
- socket.dispatchEvent(new Event("open"));
1562
- console.log("Websocket connection opened from", socket.url);
1563
- if (socket.url.includes("/state-stream")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify(defaultMotionState) }));
1564
- if (socket.url.includes("/move-joint")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify({ result: {
1565
- motion_group: "0@ur",
1566
- state: {
1567
- controller: "ur",
1568
- operation_mode: "OPERATION_MODE_AUTO",
1569
- safety_state: "SAFETY_STATE_NORMAL",
1570
- timestamp: "2024-09-18T12:48:26.096266444Z",
1571
- velocity_override: 100,
1572
- motion_groups: [{
1573
- motion_group: "0@ur",
1574
- controller: "ur",
1575
- joint_position: { joints: [
1576
- 1.3492152690887451,
1577
- -1.5659207105636597,
1578
- 1.6653711795806885,
1579
- -1.0991662740707397,
1580
- -1.829018235206604,
1581
- 1.264623761177063
1582
- ] },
1583
- joint_velocity: { joints: [
1584
- 0,
1585
- 0,
1586
- 0,
1587
- 0,
1588
- 0,
1589
- 0
1590
- ] },
1591
- flange_pose: {
1592
- position: {
1593
- x: 6.437331889439328,
1594
- y: -628.4123774830913,
1595
- z: 577.0569957147832
1596
- },
1597
- orientation: {
1598
- x: -1.683333649797158,
1599
- y: -1.9783363827298732,
1600
- z: -.4928031860165713
1601
- },
1602
- coordinate_system: ""
1603
- },
1604
- tcp_pose: {
1605
- position: {
1606
- x: 6.437331889439328,
1607
- y: -628.4123774830913,
1608
- z: 577.0569957147832
1609
- },
1610
- orientation: {
1611
- x: -1.683333649797158,
1612
- y: -1.9783363827298732,
1613
- z: -.4928031860165713
1614
- },
1615
- coordinate_system: "",
1616
- tcp: "Flange"
1617
- },
1618
- velocity: {
1619
- linear: {
1620
- x: 0,
1621
- y: 0,
1622
- z: 0
1623
- },
1624
- angular: {
1625
- x: -0,
1626
- y: 0,
1627
- z: 0
1628
- },
1629
- coordinate_system: ""
1630
- },
1631
- force: {
1632
- force: {
1633
- x: 0,
1634
- y: 0,
1635
- z: 0
1636
- },
1637
- moment: {
1638
- x: 0,
1639
- y: 0,
1640
- z: 0
1641
- },
1642
- coordinate_system: ""
1643
- },
1644
- joint_limit_reached: { limit_reached: [
1645
- false,
1646
- false,
1647
- false,
1648
- false,
1649
- false,
1650
- false
1651
- ] },
1652
- joint_current: { joints: [
1653
- 0,
1654
- 0,
1655
- 0,
1656
- 0,
1657
- 0,
1658
- 0
1659
- ] },
1660
- sequence_number: "671259"
1661
- }],
1662
- sequence_number: "671259"
1663
- },
1664
- movement_state: "MOVEMENT_STATE_MOVING"
1665
- } }) }));
1666
- if (socket.url.includes("/move-tcp")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify({ result: {
1667
- motion_group: "0@ur",
1668
- state: {
1669
- controller: "ur",
1670
- operation_mode: "OPERATION_MODE_AUTO",
1671
- safety_state: "SAFETY_STATE_NORMAL",
1672
- timestamp: "2024-09-18T12:43:12.188335774Z",
1673
- velocity_override: 100,
1674
- motion_groups: [{
1675
- motion_group: "0@ur",
1676
- controller: "ur",
1677
- joint_position: { joints: [
1678
- 1.3352527618408203,
1679
- -1.5659207105636597,
1680
- 1.6653711795806885,
1681
- -1.110615611076355,
1682
- -1.829018235206604,
1683
- 1.264623761177063
1684
- ] },
1685
- joint_velocity: { joints: [
1686
- 0,
1687
- 0,
1688
- 0,
1689
- 0,
1690
- 0,
1691
- 0
1692
- ] },
1693
- flange_pose: {
1694
- position: {
1695
- x: -2.763015284002938,
1696
- y: -630.2151479701106,
1697
- z: 577.524509114342
1698
- },
1699
- orientation: {
1700
- x: -1.704794877102097,
1701
- y: -1.9722372952861567,
1702
- z: -.4852079204210754
1703
- },
1704
- coordinate_system: ""
1705
- },
1706
- tcp_pose: {
1707
- position: {
1708
- x: -2.763015284002938,
1709
- y: -630.2151479701106,
1710
- z: 577.524509114342
1711
- },
1712
- orientation: {
1713
- x: -1.704794877102097,
1714
- y: -1.9722372952861567,
1715
- z: -.4852079204210754
1716
- },
1717
- coordinate_system: "",
1718
- tcp: "Flange"
1719
- },
1720
- velocity: {
1721
- linear: {
1722
- x: 0,
1723
- y: 0,
1724
- z: 0
1725
- },
1726
- angular: {
1727
- x: -0,
1728
- y: 0,
1729
- z: 0
1730
- },
1731
- coordinate_system: ""
1732
- },
1733
- force: {
1734
- force: {
1735
- x: 0,
1736
- y: 0,
1737
- z: 0
1738
- },
1739
- moment: {
1740
- x: 0,
1741
- y: 0,
1742
- z: 0
1743
- },
1744
- coordinate_system: ""
1745
- },
1746
- joint_limit_reached: { limit_reached: [
1747
- false,
1748
- false,
1749
- false,
1750
- false,
1751
- false,
1752
- false
1753
- ] },
1754
- joint_current: { joints: [
1755
- 0,
1756
- 0,
1757
- 0,
1758
- 0,
1759
- 0,
1760
- 0
1761
- ] },
1762
- sequence_number: "627897"
1763
- }],
1764
- sequence_number: "627897"
1765
- },
1766
- movement_state: "MOVEMENT_STATE_MOVING"
1767
- } }) }));
1768
- }, 10);
1769
- }
1770
- handleWebsocketMessage(socket, message) {
1771
- console.log(`Received message on ${socket.url}`, message);
1772
- }
1773
- };
1774
- const defaultMotionState = { result: {
1775
- state: {
1776
- motion_group: "0@universalrobots-ur5e",
1777
- controller: "universalrobots-ur5e",
1778
- joint_position: { joints: [
1779
- 1.1699999570846558,
1780
- -1.5700000524520874,
1781
- 1.3600000143051147,
1782
- 1.0299999713897705,
1783
- 1.2899999618530273,
1784
- 1.2799999713897705
1785
- ] },
1786
- joint_velocity: { joints: [
1787
- 0,
1788
- 0,
1789
- 0,
1790
- 0,
1791
- 0,
1792
- 0
1793
- ] },
1794
- flange_pose: {
1795
- position: {
1796
- x: 1.3300010259703043,
1797
- y: -409.2680714682808,
1798
- z: 531.0203477065281
1799
- },
1800
- orientation: {
1801
- x: 1.7564919306270736,
1802
- y: -1.7542521568325058,
1803
- z: .7326972590614671
1804
- },
1805
- coordinate_system: ""
1806
- },
1807
- tcp_pose: {
1808
- position: {
1809
- x: 1.3300010259703043,
1810
- y: -409.2680714682808,
1811
- z: 531.0203477065281
1812
- },
1813
- orientation: {
1814
- x: 1.7564919306270736,
1815
- y: -1.7542521568325058,
1816
- z: .7326972590614671
1817
- },
1818
- coordinate_system: "",
1819
- tcp: "Flange"
1820
- },
1821
- velocity: {
1822
- linear: {
1823
- x: 0,
1824
- y: 0,
1825
- z: 0
1826
- },
1827
- angular: {
1828
- x: 0,
1829
- y: 0,
1830
- z: 0
1831
- },
1832
- coordinate_system: ""
1833
- },
1834
- force: {
1835
- force: {
1836
- x: 0,
1837
- y: 0,
1838
- z: 0
1839
- },
1840
- moment: {
1841
- x: 0,
1842
- y: 0,
1843
- z: 0
1844
- },
1845
- coordinate_system: ""
1846
- },
1847
- joint_limit_reached: { limit_reached: [
1848
- false,
1849
- false,
1850
- false,
1851
- false,
1852
- false,
1853
- false
1854
- ] },
1855
- joint_current: { joints: [
1856
- 0,
1857
- 0,
1858
- 0,
1859
- 0,
1860
- 0,
1861
- 0
1862
- ] },
1863
- sequence_number: "1"
1864
- },
1865
- tcp_pose: {
1866
- position: {
1867
- x: 302.90748476115556,
1868
- y: -152.87065869452337,
1869
- z: 424.0454619321661
1870
- },
1871
- orientation: {
1872
- x: 2.3403056115045353,
1873
- y: -1.1706836379431356,
1874
- z: .9772511964246311
1875
- },
1876
- coordinate_system: "",
1877
- tcp: "Flange"
1878
- }
1879
- } };
1880
- //#endregion
1881
- //#region src/lib/v1/NovaClient.ts
1882
- /**
1883
- * Client for connecting to a Nova instance and controlling robots.
1884
- * @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.
1885
- */
1886
- var NovaClient = class {
1887
- constructor(config) {
1888
- this.authPromise = null;
1889
- this.accessToken = null;
1890
- const cellId = config.cellId ?? "cell";
1891
- this.config = {
1892
- cellId,
1893
- ...config
1894
- };
1895
- this.accessToken = config.accessToken || require_LoginWithAuth0.availableStorage.getString("wbjs.access_token") || null;
1896
- if (this.config.instanceUrl === "https://mock.example.com") this.mock = new MockNovaInstance();
1897
- this.instanceUrl = require_LoginWithAuth0.parseNovaInstanceUrl(this.config.instanceUrl);
1898
- const axiosInstance = axios.default.create({
1899
- baseURL: (0, url_join.default)(this.config.instanceUrl, "/api/v1"),
1900
- headers: typeof window !== "undefined" && window.location.origin.includes("localhost") ? {} : { "X-Wandelbots-Client": "Wandelbots-Nova-JS-SDK" }
1901
- });
1902
- axiosInstance.interceptors.request.use(async (request) => {
1903
- if (!request.headers.Authorization) {
1904
- if (this.accessToken) request.headers.Authorization = `Bearer ${this.accessToken}`;
1905
- else if (this.config.username && this.config.password) request.headers.Authorization = `Basic ${btoa(`${config.username}:${config.password}`)}`;
1906
- }
1907
- return request;
1908
- });
1909
- if (typeof window !== "undefined") axiosInstance.interceptors.response.use((r) => r, async (error) => {
1910
- if ((0, axios.isAxiosError)(error)) {
1911
- if (error.response?.status === 401) try {
1912
- await this.renewAuthentication();
1913
- if (error.config) {
1914
- if (this.accessToken) error.config.headers.Authorization = `Bearer ${this.accessToken}`;
1915
- else delete error.config.headers.Authorization;
1916
- return axiosInstance.request(error.config);
1917
- }
1918
- } catch (err) {
1919
- return Promise.reject(err);
1920
- }
1921
- else if (error.response?.status === 503) {
1922
- if ((await fetch(window.location.href)).status === 503) window.location.reload();
1923
- }
1924
- }
1925
- return Promise.reject(error);
1926
- });
1927
- this.api = new NovaCellAPIClient(cellId, {
1928
- ...config,
1929
- basePath: (0, url_join.default)(this.instanceUrl.href, "/api/v1"),
1930
- isJsonMime: (mime) => {
1931
- return mime === "application/json";
1932
- },
1933
- baseOptions: {
1934
- ...this.mock ? { adapter: (config) => {
1935
- return this.mock.handleAPIRequest(config);
1936
- } } : {},
1937
- ...config.baseOptions
1938
- },
1939
- axiosInstance
1940
- });
1941
- }
1942
- async renewAuthentication() {
1943
- if (this.authPromise) return;
1944
- const storedToken = require_LoginWithAuth0.availableStorage.getString("wbjs.access_token");
1945
- if (storedToken && this.accessToken !== storedToken) {
1946
- this.accessToken = storedToken;
1947
- return;
1948
- }
1949
- this.authPromise = require_LoginWithAuth0.loginWithAuth0(this.instanceUrl);
1950
- try {
1951
- this.accessToken = await this.authPromise;
1952
- if (this.accessToken) require_LoginWithAuth0.availableStorage.setString("wbjs.access_token", this.accessToken);
1953
- else require_LoginWithAuth0.availableStorage.delete("wbjs.access_token");
1954
- } finally {
1955
- this.authPromise = null;
1956
- }
1957
- }
1958
- makeWebsocketURL(path) {
1959
- const url = new URL((0, url_join.default)(this.instanceUrl.href, `/api/v1/cells/${this.config.cellId}`, path));
1960
- url.protocol = url.protocol.replace("http", "ws");
1961
- url.protocol = url.protocol.replace("https", "wss");
1962
- if (this.accessToken) url.searchParams.append("token", this.accessToken);
1963
- else if (this.config.username && this.config.password) {
1964
- url.username = this.config.username;
1965
- url.password = this.config.password;
1966
- }
1967
- return url.toString();
1968
- }
1969
- /**
1970
- * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.
1971
- * If you explicitly want to reconnect an existing websocket, call `reconnect`
1972
- * on the returned object.
1973
- */
1974
- openReconnectingWebsocket(path) {
1975
- return new require_LoginWithAuth0.AutoReconnectingWebsocket(this.makeWebsocketURL(path), { mock: this.mock });
1976
- }
1977
- /**
1978
- * Connect to the motion state websocket(s) for a given motion group
1979
- */
1980
- async connectMotionStream(motionGroupId) {
1981
- return await MotionStreamConnection.open(this, motionGroupId);
1982
- }
1983
- /**
1984
- * Connect to the jogging websocket(s) for a given motion group
1985
- */
1986
- async connectJogger(motionGroupId) {
1987
- return await JoggerConnection.open(this, motionGroupId);
1988
- }
1989
- async connectMotionGroups(motionGroupIds) {
1990
- const { instances } = await this.api.controller.listControllers();
1991
- return Promise.all(motionGroupIds.map((motionGroupId) => ConnectedMotionGroup.connect(this, motionGroupId, instances)));
1992
- }
1993
- async connectMotionGroup(motionGroupId) {
1994
- return (await this.connectMotionGroups([motionGroupId]))[0];
1995
- }
1996
- };
1997
- //#endregion
1998
- Object.defineProperty(exports, "ConnectedMotionGroup", {
1999
- enumerable: true,
2000
- get: function() {
2001
- return ConnectedMotionGroup;
2002
- }
2003
- });
2004
- Object.defineProperty(exports, "JoggerConnection", {
2005
- enumerable: true,
2006
- get: function() {
2007
- return JoggerConnection;
2008
- }
2009
- });
2010
- Object.defineProperty(exports, "MotionStreamConnection", {
2011
- enumerable: true,
2012
- get: function() {
2013
- return MotionStreamConnection;
2014
- }
2015
- });
2016
- Object.defineProperty(exports, "NovaCellAPIClient", {
2017
- enumerable: true,
2018
- get: function() {
2019
- return NovaCellAPIClient;
2020
- }
2021
- });
2022
- Object.defineProperty(exports, "NovaClient", {
2023
- enumerable: true,
2024
- get: function() {
2025
- return NovaClient;
2026
- }
2027
- });
2028
- Object.defineProperty(exports, "poseToWandelscriptString", {
2029
- enumerable: true,
2030
- get: function() {
2031
- return poseToWandelscriptString;
2032
- }
2033
- });
2034
-
2035
- //# sourceMappingURL=NovaClient-B-QdK0HR.cjs.map