@wandelbots/nova-js 1.17.1-pr.feat-added-v2-client.64.9ac2247

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.
Files changed (95) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +202 -0
  3. package/dist/LoginWithAuth0.d.ts +7 -0
  4. package/dist/LoginWithAuth0.d.ts.map +1 -0
  5. package/dist/chunk-V3NJLR6P.js +336 -0
  6. package/dist/chunk-V3NJLR6P.js.map +1 -0
  7. package/dist/index.cjs +390 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.ts +6 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +54 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/AutoReconnectingWebsocket.d.ts +43 -0
  14. package/dist/lib/AutoReconnectingWebsocket.d.ts.map +1 -0
  15. package/dist/lib/availableStorage.d.ts +15 -0
  16. package/dist/lib/availableStorage.d.ts.map +1 -0
  17. package/dist/lib/converters.d.ts +26 -0
  18. package/dist/lib/converters.d.ts.map +1 -0
  19. package/dist/lib/errorHandling.d.ts +4 -0
  20. package/dist/lib/errorHandling.d.ts.map +1 -0
  21. package/dist/lib/v1/ConnectedMotionGroup.d.ts +77 -0
  22. package/dist/lib/v1/ConnectedMotionGroup.d.ts.map +1 -0
  23. package/dist/lib/v1/JoggerConnection.d.ts +94 -0
  24. package/dist/lib/v1/JoggerConnection.d.ts.map +1 -0
  25. package/dist/lib/v1/MotionStreamConnection.d.ts +25 -0
  26. package/dist/lib/v1/MotionStreamConnection.d.ts.map +1 -0
  27. package/dist/lib/v1/NovaCellAPIClient.d.ts +66 -0
  28. package/dist/lib/v1/NovaCellAPIClient.d.ts.map +1 -0
  29. package/dist/lib/v1/NovaClient.d.ts +67 -0
  30. package/dist/lib/v1/NovaClient.d.ts.map +1 -0
  31. package/dist/lib/v1/ProgramStateConnection.d.ts +53 -0
  32. package/dist/lib/v1/ProgramStateConnection.d.ts.map +1 -0
  33. package/dist/lib/v1/getLatestTrajectories.d.ts +4 -0
  34. package/dist/lib/v1/getLatestTrajectories.d.ts.map +1 -0
  35. package/dist/lib/v1/index.cjs +3957 -0
  36. package/dist/lib/v1/index.cjs.map +1 -0
  37. package/dist/lib/v1/index.d.ts +9 -0
  38. package/dist/lib/v1/index.d.ts.map +1 -0
  39. package/dist/lib/v1/index.js +3662 -0
  40. package/dist/lib/v1/index.js.map +1 -0
  41. package/dist/lib/v1/mock/MockNovaInstance.d.ts +13 -0
  42. package/dist/lib/v1/mock/MockNovaInstance.d.ts.map +1 -0
  43. package/dist/lib/v1/motionStateUpdate.d.ts +4 -0
  44. package/dist/lib/v1/motionStateUpdate.d.ts.map +1 -0
  45. package/dist/lib/v2/ConnectedMotionGroup.d.ts +41 -0
  46. package/dist/lib/v2/ConnectedMotionGroup.d.ts.map +1 -0
  47. package/dist/lib/v2/JoggerConnection.d.ts +53 -0
  48. package/dist/lib/v2/JoggerConnection.d.ts.map +1 -0
  49. package/dist/lib/v2/MotionStreamConnection.d.ts +25 -0
  50. package/dist/lib/v2/MotionStreamConnection.d.ts.map +1 -0
  51. package/dist/lib/v2/NovaCellAPIClient.d.ts +64 -0
  52. package/dist/lib/v2/NovaCellAPIClient.d.ts.map +1 -0
  53. package/dist/lib/v2/NovaClient.d.ts +67 -0
  54. package/dist/lib/v2/NovaClient.d.ts.map +1 -0
  55. package/dist/lib/v2/ProgramStateConnection.d.ts +53 -0
  56. package/dist/lib/v2/ProgramStateConnection.d.ts.map +1 -0
  57. package/dist/lib/v2/index.cjs +2239 -0
  58. package/dist/lib/v2/index.cjs.map +1 -0
  59. package/dist/lib/v2/index.d.ts +8 -0
  60. package/dist/lib/v2/index.d.ts.map +1 -0
  61. package/dist/lib/v2/index.js +1947 -0
  62. package/dist/lib/v2/index.js.map +1 -0
  63. package/dist/lib/v2/mock/MockNovaInstance.d.ts +13 -0
  64. package/dist/lib/v2/mock/MockNovaInstance.d.ts.map +1 -0
  65. package/dist/lib/v2/motionStateUpdate.d.ts +4 -0
  66. package/dist/lib/v2/motionStateUpdate.d.ts.map +1 -0
  67. package/dist/lib/v2/vectorUtils.d.ts +7 -0
  68. package/dist/lib/v2/vectorUtils.d.ts.map +1 -0
  69. package/package.json +67 -0
  70. package/src/LoginWithAuth0.ts +90 -0
  71. package/src/index.ts +5 -0
  72. package/src/lib/AutoReconnectingWebsocket.ts +163 -0
  73. package/src/lib/availableStorage.ts +46 -0
  74. package/src/lib/converters.ts +74 -0
  75. package/src/lib/errorHandling.ts +26 -0
  76. package/src/lib/v1/ConnectedMotionGroup.ts +419 -0
  77. package/src/lib/v1/JoggerConnection.ts +480 -0
  78. package/src/lib/v1/MotionStreamConnection.ts +202 -0
  79. package/src/lib/v1/NovaCellAPIClient.ts +180 -0
  80. package/src/lib/v1/NovaClient.ts +232 -0
  81. package/src/lib/v1/ProgramStateConnection.ts +267 -0
  82. package/src/lib/v1/getLatestTrajectories.ts +36 -0
  83. package/src/lib/v1/index.ts +8 -0
  84. package/src/lib/v1/mock/MockNovaInstance.ts +1302 -0
  85. package/src/lib/v1/motionStateUpdate.ts +55 -0
  86. package/src/lib/v2/ConnectedMotionGroup.ts +216 -0
  87. package/src/lib/v2/JoggerConnection.ts +207 -0
  88. package/src/lib/v2/MotionStreamConnection.ts +201 -0
  89. package/src/lib/v2/NovaCellAPIClient.ts +174 -0
  90. package/src/lib/v2/NovaClient.ts +230 -0
  91. package/src/lib/v2/ProgramStateConnection.ts +255 -0
  92. package/src/lib/v2/index.ts +7 -0
  93. package/src/lib/v2/mock/MockNovaInstance.ts +982 -0
  94. package/src/lib/v2/motionStateUpdate.ts +55 -0
  95. package/src/lib/v2/vectorUtils.ts +36 -0
@@ -0,0 +1,2239 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
38
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
39
+ // If the importer is in node compatibility mode or this is not an ESM
40
+ // file that has been converted to a CommonJS file using a Babel-
41
+ // compatible transform (i.e. "__esModule" has not been set), then set
42
+ // "default" to the CommonJS "module.exports" for node compatibility.
43
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
44
+ mod
45
+ ));
46
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
47
+ var __async = (__this, __arguments, generator) => {
48
+ return new Promise((resolve, reject) => {
49
+ var fulfilled = (value) => {
50
+ try {
51
+ step(generator.next(value));
52
+ } catch (e) {
53
+ reject(e);
54
+ }
55
+ };
56
+ var rejected = (value) => {
57
+ try {
58
+ step(generator.throw(value));
59
+ } catch (e) {
60
+ reject(e);
61
+ }
62
+ };
63
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
64
+ step((generator = generator.apply(__this, __arguments)).next());
65
+ });
66
+ };
67
+
68
+ // src/lib/v2/index.ts
69
+ var v2_exports = {};
70
+ __export(v2_exports, {
71
+ ConnectedMotionGroup: () => ConnectedMotionGroup,
72
+ JoggerConnection: () => JoggerConnection,
73
+ MotionStreamConnection: () => MotionStreamConnection,
74
+ NovaCellAPIClient: () => NovaCellAPIClient,
75
+ NovaClient: () => NovaClient,
76
+ ProgramState: () => ProgramState,
77
+ ProgramStateConnection: () => ProgramStateConnection
78
+ });
79
+ module.exports = __toCommonJS(v2_exports);
80
+ __reExport(v2_exports, require("@wandelbots/nova-api/v2"), module.exports);
81
+
82
+ // src/lib/v2/ConnectedMotionGroup.ts
83
+ var import_axios = require("axios");
84
+ var import_mobx = require("mobx");
85
+
86
+ // src/lib/converters.ts
87
+ function tryParseJson(json) {
88
+ try {
89
+ return JSON.parse(json);
90
+ } catch (e) {
91
+ return void 0;
92
+ }
93
+ }
94
+
95
+ // src/lib/v2/motionStateUpdate.ts
96
+ function jointValuesEqual(oldJointValues, newJointValues, changeDeltaThreshold) {
97
+ if (newJointValues.length !== oldJointValues.length) {
98
+ return true;
99
+ }
100
+ for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {
101
+ if (Math.abs(newJointValues[jointIndex] - oldJointValues[jointIndex]) > changeDeltaThreshold) {
102
+ return false;
103
+ }
104
+ }
105
+ return true;
106
+ }
107
+ function tcpPoseEqual(oldTcp, newTcp, changeDeltaThreshold) {
108
+ if (oldTcp === void 0 && newTcp || oldTcp && newTcp === void 0) {
109
+ return false;
110
+ }
111
+ if (oldTcp === void 0 || newTcp === void 0) {
112
+ return true;
113
+ }
114
+ let changedDelta = 0;
115
+ changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0]);
116
+ changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1]);
117
+ changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2]);
118
+ changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0]);
119
+ changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1]);
120
+ changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2]);
121
+ if (changedDelta > changeDeltaThreshold) {
122
+ return false;
123
+ }
124
+ return oldTcp.coordinate_system === newTcp.coordinate_system && oldTcp.tcp === newTcp.tcp;
125
+ }
126
+
127
+ // src/lib/v2/ConnectedMotionGroup.ts
128
+ var MOTION_DELTA_THRESHOLD = 1e-4;
129
+ var ConnectedMotionGroup = class _ConnectedMotionGroup {
130
+ constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup) {
131
+ this.nova = nova;
132
+ this.controller = controller;
133
+ this.motionGroup = motionGroup;
134
+ this.initialMotionState = initialMotionState;
135
+ this.motionStateSocket = motionStateSocket;
136
+ this.isVirtual = isVirtual;
137
+ this.tcps = tcps;
138
+ this.motionGroupSpecification = motionGroupSpecification;
139
+ this.safetySetup = safetySetup;
140
+ this.connectedJoggingCartesianSocket = null;
141
+ this.connectedJoggingJointsSocket = null;
142
+ // tmp
143
+ this.joggingVelocity = 10;
144
+ this.rapidlyChangingMotionState = initialMotionState;
145
+ motionStateSocket.addEventListener("message", (event) => {
146
+ var _a;
147
+ const motionStateResponse = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result;
148
+ if (!motionStateResponse) {
149
+ throw new Error(
150
+ `Failed to get motion state for ${this.motionGroupId}: ${event.data}`
151
+ );
152
+ }
153
+ if (!jointValuesEqual(
154
+ this.rapidlyChangingMotionState.joint_position.joints,
155
+ motionStateResponse.joint_position.joints,
156
+ MOTION_DELTA_THRESHOLD
157
+ )) {
158
+ (0, import_mobx.runInAction)(() => {
159
+ this.rapidlyChangingMotionState = motionStateResponse;
160
+ });
161
+ }
162
+ if (!tcpPoseEqual(
163
+ this.rapidlyChangingMotionState.tcp_pose,
164
+ motionStateResponse.tcp_pose,
165
+ MOTION_DELTA_THRESHOLD
166
+ )) {
167
+ (0, import_mobx.runInAction)(() => {
168
+ this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
169
+ });
170
+ }
171
+ });
172
+ (0, import_mobx.makeAutoObservable)(this);
173
+ }
174
+ static connect(nova, motionGroupId, controllers) {
175
+ return __async(this, null, function* () {
176
+ var _a;
177
+ const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
178
+ const controller = controllers.find((c) => c.controller === controllerId);
179
+ const motionGroup = controller == null ? void 0 : controller.motion_groups.find(
180
+ (mg) => mg.motion_group === motionGroupId
181
+ );
182
+ if (!controller || !motionGroup) {
183
+ throw new Error(
184
+ `Controller ${controllerId} or motion group ${motionGroupId} not found`
185
+ );
186
+ }
187
+ const motionStateSocket = nova.openReconnectingWebsocket(
188
+ `/motion-groups/${motionGroupId}/state-stream`
189
+ );
190
+ const firstMessage = yield motionStateSocket.firstMessage();
191
+ const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result;
192
+ if (!initialMotionState) {
193
+ throw new Error(
194
+ `Unable to parse initial motion state message ${firstMessage.data}`
195
+ );
196
+ }
197
+ console.log(
198
+ `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:
199
+ `,
200
+ initialMotionState
201
+ );
202
+ let isVirtual = false;
203
+ try {
204
+ const opMode = yield nova.api.virtualRobotMode.getOperationMode(controllerId);
205
+ if (opMode) isVirtual = true;
206
+ } catch (err) {
207
+ if (err instanceof import_axios.AxiosError) {
208
+ console.log(
209
+ `Received ${err.status} from getOperationMode, concluding that ${controllerId} is physical`
210
+ );
211
+ } else {
212
+ throw err;
213
+ }
214
+ }
215
+ const { tcps } = yield nova.api.motionGroupInfos.listTcps(motionGroupId);
216
+ const motionGroupSpecification = yield nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId);
217
+ const safetySetup = yield nova.api.motionGroupInfos.getSafetySetup(motionGroupId);
218
+ return new _ConnectedMotionGroup(
219
+ nova,
220
+ controller,
221
+ motionGroup,
222
+ initialMotionState,
223
+ motionStateSocket,
224
+ isVirtual,
225
+ tcps,
226
+ motionGroupSpecification,
227
+ safetySetup
228
+ );
229
+ });
230
+ }
231
+ get motionGroupId() {
232
+ return this.motionGroup.motion_group;
233
+ }
234
+ get controllerId() {
235
+ return this.controller.controller;
236
+ }
237
+ get modelFromController() {
238
+ return this.motionGroup.model_from_controller;
239
+ }
240
+ get wandelscriptIdentifier() {
241
+ const num = this.motionGroupId.split("@")[0];
242
+ return `${this.controllerId.replaceAll("-", "_")}_${num}`;
243
+ }
244
+ /** Jogging velocity in radians for rotation and joint movement */
245
+ get joggingVelocityRads() {
246
+ return this.joggingVelocity * Math.PI / 180;
247
+ }
248
+ get joints() {
249
+ return this.initialMotionState.joint_position.joints.map((_, i) => {
250
+ return {
251
+ index: i
252
+ };
253
+ });
254
+ }
255
+ get dhParameters() {
256
+ return this.motionGroupSpecification.dh_parameters;
257
+ }
258
+ get safetyZones() {
259
+ return this.safetySetup.safety_zones;
260
+ }
261
+ dispose() {
262
+ this.motionStateSocket.close();
263
+ if (this.connectedJoggingCartesianSocket)
264
+ this.connectedJoggingCartesianSocket.close();
265
+ if (this.connectedJoggingJointsSocket)
266
+ this.connectedJoggingJointsSocket.close();
267
+ }
268
+ setJoggingVelocity(velocity) {
269
+ this.joggingVelocity = velocity;
270
+ }
271
+ };
272
+
273
+ // src/lib/v2/vectorUtils.ts
274
+ var THREE = __toESM(require("three"), 1);
275
+ function axisToIndex(axis) {
276
+ switch (axis) {
277
+ case "x":
278
+ return 0;
279
+ case "y":
280
+ return 1;
281
+ case "z":
282
+ return 2;
283
+ }
284
+ }
285
+ function vector3ToArray(vector) {
286
+ return [vector.x, vector.y, vector.z];
287
+ }
288
+
289
+ // src/lib/v2/JoggerConnection.ts
290
+ var JoggerConnection = class _JoggerConnection {
291
+ constructor(nova, cell, motionGroupId, motionGroupState, opts) {
292
+ this.nova = nova;
293
+ this.cell = cell;
294
+ this.motionGroupId = motionGroupId;
295
+ this.motionGroupState = motionGroupState;
296
+ this.opts = opts;
297
+ // Currently a separate websocket is needed for each mode, pester API people
298
+ // to merge these for simplicity
299
+ this.joggingWebsocket = null;
300
+ this.lastVelocityRequest = null;
301
+ this.lastResponse = null;
302
+ this.joggingWebsocket = nova.openReconnectingWebsocket(
303
+ `/cells/${cell}/execution/jogging`
304
+ );
305
+ this.joggingWebsocket.addEventListener("message", (ev) => {
306
+ const data = tryParseJson(ev.data);
307
+ if (data && "error" in data) {
308
+ if (this.opts.onError) {
309
+ this.opts.onError(ev.data);
310
+ } else {
311
+ throw new Error(ev.data);
312
+ }
313
+ }
314
+ });
315
+ this.joggingWebsocket.addEventListener("message", (ev) => {
316
+ const data = tryParseJson(ev.data);
317
+ if (data && "error" in data) {
318
+ if (this.opts.onError) {
319
+ this.opts.onError(ev.data);
320
+ } else {
321
+ throw new Error(ev.data);
322
+ }
323
+ }
324
+ });
325
+ }
326
+ static open(nova, cell, motionGroupId, opts) {
327
+ return __async(this, null, function* () {
328
+ const motionGroupState = yield nova.api.motionGroupInfos.getCurrentMotionGroupState(motionGroupId);
329
+ return new _JoggerConnection(
330
+ nova,
331
+ cell,
332
+ motionGroupId,
333
+ motionGroupState,
334
+ opts
335
+ );
336
+ });
337
+ }
338
+ get jointCount() {
339
+ var _a;
340
+ return (_a = this.motionGroupState.joint_current) == null ? void 0 : _a.joints.length;
341
+ }
342
+ get activeWebsocket() {
343
+ return this.joggingWebsocket;
344
+ }
345
+ stop() {
346
+ return __async(this, null, function* () {
347
+ var _a, _b;
348
+ if (!this.joggingWebsocket) {
349
+ return;
350
+ }
351
+ if (((_a = this.lastVelocityRequest) == null ? void 0 : _a.message_type) === "JointVelocityRequest") {
352
+ this.joggingWebsocket.sendJson({
353
+ message_type: "JointVelocityRequest",
354
+ velocity: {
355
+ joints: Array.from(new Array(this.jointCount).keys()).map(() => 0)
356
+ }
357
+ });
358
+ }
359
+ if (((_b = this.lastVelocityRequest) == null ? void 0 : _b.message_type) === "TcpVelocityRequest") {
360
+ this.joggingWebsocket.sendJson({
361
+ message_type: "TcpVelocityRequest",
362
+ rotation: [0, 0, 0],
363
+ translation: [0, 0, 0]
364
+ });
365
+ }
366
+ });
367
+ }
368
+ dispose() {
369
+ if (this.joggingWebsocket) {
370
+ this.joggingWebsocket.dispose();
371
+ }
372
+ }
373
+ /**
374
+ * Start rotation of a single robot joint at the specified velocity
375
+ */
376
+ startJointRotation(_0) {
377
+ return __async(this, arguments, function* ({
378
+ joint,
379
+ velocityRadsPerSec
380
+ }) {
381
+ if (!this.joggingWebsocket) {
382
+ throw new Error(
383
+ "Joint jogging websocket not connected. Wait for reconnect or open new jogging connection"
384
+ );
385
+ }
386
+ const jointVelocities = new Array(this.jointCount).fill(0);
387
+ jointVelocities[joint] = velocityRadsPerSec;
388
+ this.joggingWebsocket.sendJson({
389
+ message_type: "JointVelocityRequest",
390
+ velocity: {
391
+ joints: jointVelocities
392
+ }
393
+ });
394
+ });
395
+ }
396
+ /**
397
+ * Start the TCP moving along a specified axis at a given velocity
398
+ */
399
+ startTCPTranslation(_0) {
400
+ return __async(this, arguments, function* ({
401
+ axis,
402
+ velocityMmPerSec,
403
+ useToolCoordinateSystem
404
+ }) {
405
+ if (!this.joggingWebsocket) {
406
+ throw new Error(
407
+ "Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection"
408
+ );
409
+ }
410
+ const joggingVector = [0, 0, 0];
411
+ joggingVector[axisToIndex(axis)] = velocityMmPerSec;
412
+ this.joggingWebsocket.sendJson({
413
+ message_type: "TcpVelocityRequest",
414
+ translation: joggingVector,
415
+ rotation: [0, 0, 0],
416
+ use_tool_coordinate_system: useToolCoordinateSystem
417
+ });
418
+ });
419
+ }
420
+ /**
421
+ * Start the TCP rotating around a specified axis at a given velocity
422
+ */
423
+ startTCPRotation(_0) {
424
+ return __async(this, arguments, function* ({
425
+ axis,
426
+ velocityRadsPerSec,
427
+ useToolCoordinateSystem
428
+ }) {
429
+ if (!this.joggingWebsocket) {
430
+ throw new Error(
431
+ "Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection"
432
+ );
433
+ }
434
+ const joggingVector = [0, 0, 0];
435
+ joggingVector[axisToIndex(axis)] = velocityRadsPerSec;
436
+ this.joggingWebsocket.sendJson({
437
+ message_type: "TcpVelocityRequest",
438
+ rotation: joggingVector,
439
+ translation: [0, 0, 0],
440
+ use_tool_coordinate_system: useToolCoordinateSystem
441
+ });
442
+ });
443
+ }
444
+ };
445
+
446
+ // src/lib/v2/MotionStreamConnection.ts
447
+ var import_mobx2 = require("mobx");
448
+ var THREE2 = __toESM(require("three"), 1);
449
+ var MOTION_DELTA_THRESHOLD2 = 1e-4;
450
+ function unwrapRotationVector(newRotationVectorApi, currentRotationVectorApi) {
451
+ const currentRotationVector = new THREE2.Vector3(
452
+ currentRotationVectorApi[0],
453
+ currentRotationVectorApi[1],
454
+ currentRotationVectorApi[2]
455
+ );
456
+ const newRotationVector = new THREE2.Vector3(
457
+ newRotationVectorApi[0],
458
+ newRotationVectorApi[1],
459
+ newRotationVectorApi[2]
460
+ );
461
+ const currentAngle = currentRotationVector.length();
462
+ const currentAxis = currentRotationVector.normalize();
463
+ let newAngle = newRotationVector.length();
464
+ let newAxis = newRotationVector.normalize();
465
+ if (newAxis.dot(currentAxis) < 0) {
466
+ newAngle = -newAngle;
467
+ newAxis = newAxis.multiplyScalar(-1);
468
+ }
469
+ let angleDifference = newAngle - currentAngle;
470
+ angleDifference -= 2 * Math.PI * Math.floor((angleDifference + Math.PI) / (2 * Math.PI));
471
+ newAngle = currentAngle + angleDifference;
472
+ return vector3ToArray(newAxis.multiplyScalar(newAngle));
473
+ }
474
+ var MotionStreamConnection = class _MotionStreamConnection {
475
+ constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket) {
476
+ this.nova = nova;
477
+ this.controller = controller;
478
+ this.motionGroup = motionGroup;
479
+ this.initialMotionState = initialMotionState;
480
+ this.motionStateSocket = motionStateSocket;
481
+ this.rapidlyChangingMotionState = initialMotionState;
482
+ motionStateSocket.addEventListener("message", (event) => {
483
+ var _a;
484
+ const motionState = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result;
485
+ if (!motionState) {
486
+ throw new Error(
487
+ `Failed to get motion state for ${this.motionGroupId}: ${event.data}`
488
+ );
489
+ }
490
+ if (!jointValuesEqual(
491
+ this.rapidlyChangingMotionState.joint_position.joints,
492
+ motionState.joint_position.joints,
493
+ MOTION_DELTA_THRESHOLD2
494
+ )) {
495
+ (0, import_mobx2.runInAction)(() => {
496
+ this.rapidlyChangingMotionState = motionState;
497
+ });
498
+ }
499
+ if (!tcpPoseEqual(
500
+ this.rapidlyChangingMotionState.tcp_pose,
501
+ motionState.tcp_pose,
502
+ MOTION_DELTA_THRESHOLD2
503
+ )) {
504
+ (0, import_mobx2.runInAction)(() => {
505
+ if (this.rapidlyChangingMotionState.tcp_pose == void 0) {
506
+ this.rapidlyChangingMotionState.tcp_pose = motionState.tcp_pose;
507
+ } else {
508
+ this.rapidlyChangingMotionState.tcp_pose = {
509
+ position: motionState.tcp_pose.position,
510
+ orientation: unwrapRotationVector(
511
+ motionState.tcp_pose.orientation,
512
+ this.rapidlyChangingMotionState.tcp_pose.orientation
513
+ ),
514
+ tcp: motionState.tcp_pose.tcp,
515
+ coordinate_system: motionState.tcp_pose.coordinate_system
516
+ };
517
+ }
518
+ });
519
+ }
520
+ });
521
+ (0, import_mobx2.makeAutoObservable)(this);
522
+ }
523
+ static open(nova, motionGroupId) {
524
+ return __async(this, null, function* () {
525
+ var _a;
526
+ const { controllers } = yield nova.api.controller.listControllers();
527
+ const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
528
+ const controller = controllers.find((c) => c.controller === controllerId);
529
+ const motionGroup = controller == null ? void 0 : controller.motion_groups.find(
530
+ (mg) => mg.motion_group === motionGroupId
531
+ );
532
+ if (!controller || !motionGroup) {
533
+ throw new Error(
534
+ `Controller ${controllerId} or motion group ${motionGroupId} not found`
535
+ );
536
+ }
537
+ const motionStateSocket = nova.openReconnectingWebsocket(
538
+ `/motion-groups/${motionGroupId}/state-stream`
539
+ );
540
+ const firstMessage = yield motionStateSocket.firstMessage();
541
+ console.log("got first message", firstMessage);
542
+ const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result;
543
+ if (!initialMotionState) {
544
+ throw new Error(
545
+ `Unable to parse initial motion state message ${firstMessage.data}`
546
+ );
547
+ }
548
+ console.log(
549
+ `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:
550
+ `,
551
+ initialMotionState
552
+ );
553
+ return new _MotionStreamConnection(
554
+ nova,
555
+ controller,
556
+ motionGroup,
557
+ initialMotionState,
558
+ motionStateSocket
559
+ );
560
+ });
561
+ }
562
+ get motionGroupId() {
563
+ return this.motionGroup.motion_group;
564
+ }
565
+ get controllerId() {
566
+ return this.controller.controller;
567
+ }
568
+ get modelFromController() {
569
+ return this.motionGroup.model_from_controller;
570
+ }
571
+ get wandelscriptIdentifier() {
572
+ const num = this.motionGroupId.split("@")[0];
573
+ return `${this.controllerId.replaceAll("-", "_")}_${num}`;
574
+ }
575
+ get joints() {
576
+ return this.initialMotionState.joint_position.joints.map((_, i) => {
577
+ return {
578
+ index: i
579
+ };
580
+ });
581
+ }
582
+ dispose() {
583
+ this.motionStateSocket.close();
584
+ }
585
+ };
586
+
587
+ // src/lib/v2/NovaCellAPIClient.ts
588
+ var import_v2 = require("@wandelbots/nova-api/v2");
589
+ var import_axios2 = __toESM(require("axios"), 1);
590
+ var NovaCellAPIClient = class {
591
+ constructor(cellId, opts) {
592
+ this.cellId = cellId;
593
+ this.opts = opts;
594
+ this.system = this.withUnwrappedResponsesOnly(import_v2.SystemApi);
595
+ this.cell = this.withUnwrappedResponsesOnly(import_v2.CellApi);
596
+ this.motionGroup = this.withCellId(import_v2.MotionGroupApi);
597
+ this.motionGroupInfos = this.withCellId(import_v2.MotionGroupInfoApi);
598
+ this.controller = this.withCellId(import_v2.ControllerApi);
599
+ this.program = this.withCellId(import_v2.ProgramApi);
600
+ this.programOperator = this.withCellId(import_v2.ProgramOperatorApi);
601
+ this.programLibraryMetadata = this.withCellId(import_v2.ProgramLibraryMetadataApi);
602
+ this.programLibrary = this.withCellId(import_v2.ProgramLibraryApi);
603
+ this.controllerIOs = this.withCellId(import_v2.ControllerInputsOutputsApi);
604
+ this.motionGroupKinematic = this.withCellId(import_v2.MotionGroupKinematicsApi);
605
+ this.trajectoryPlanning = this.withCellId(import_v2.TrajectoryPlanningApi);
606
+ this.trajectoryExecution = this.withCellId(import_v2.TrajectoryExecutionApi);
607
+ this.coordinateSystems = this.withCellId(import_v2.CoordinateSystemsApi);
608
+ this.application = this.withCellId(import_v2.ApplicationApi);
609
+ this.applicationGlobal = this.withUnwrappedResponsesOnly(import_v2.ApplicationApi);
610
+ this.jogging = this.withCellId(import_v2.JoggingApi);
611
+ this.virtualRobot = this.withCellId(import_v2.VirtualRobotApi);
612
+ this.virtualRobotSetup = this.withCellId(import_v2.VirtualRobotSetupApi);
613
+ this.virtualRobotMode = this.withCellId(import_v2.VirtualRobotModeApi);
614
+ this.virtualRobotBehavior = this.withCellId(import_v2.VirtualRobotBehaviorApi);
615
+ this.storeObject = this.withCellId(import_v2.StoreObjectApi);
616
+ this.storeCollisionComponents = this.withCellId(
617
+ import_v2.StoreCollisionComponentsApi
618
+ );
619
+ this.storeCollisionScenes = this.withCellId(import_v2.StoreCollisionScenesApi);
620
+ }
621
+ /**
622
+ * Some TypeScript sorcery which alters the API class methods so you don't
623
+ * have to pass the cell id to every single one, and de-encapsulates the
624
+ * response data
625
+ */
626
+ withCellId(ApiConstructor) {
627
+ var _a, _b;
628
+ const apiClient = new ApiConstructor(
629
+ __spreadProps(__spreadValues({}, this.opts), {
630
+ isJsonMime: (mime) => {
631
+ return mime === "application/json";
632
+ }
633
+ }),
634
+ (_a = this.opts.basePath) != null ? _a : "",
635
+ (_b = this.opts.axiosInstance) != null ? _b : import_axios2.default.create()
636
+ );
637
+ for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) {
638
+ if (key !== "constructor" && typeof apiClient[key] === "function") {
639
+ const originalFunction = apiClient[key];
640
+ apiClient[key] = (...args) => {
641
+ return originalFunction.apply(apiClient, [this.cellId, ...args]).then((res) => res.data);
642
+ };
643
+ }
644
+ }
645
+ return apiClient;
646
+ }
647
+ /**
648
+ * As withCellId, but only does the response unwrapping
649
+ */
650
+ withUnwrappedResponsesOnly(ApiConstructor) {
651
+ var _a, _b;
652
+ const apiClient = new ApiConstructor(
653
+ __spreadProps(__spreadValues({}, this.opts), {
654
+ isJsonMime: (mime) => {
655
+ return mime === "application/json";
656
+ }
657
+ }),
658
+ (_a = this.opts.basePath) != null ? _a : "",
659
+ (_b = this.opts.axiosInstance) != null ? _b : import_axios2.default.create()
660
+ );
661
+ for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) {
662
+ if (key !== "constructor" && typeof apiClient[key] === "function") {
663
+ const originalFunction = apiClient[key];
664
+ apiClient[key] = (...args) => {
665
+ return originalFunction.apply(apiClient, args).then((res) => res.data);
666
+ };
667
+ }
668
+ }
669
+ return apiClient;
670
+ }
671
+ };
672
+
673
+ // src/lib/v2/NovaClient.ts
674
+ var import_axios4 = __toESM(require("axios"), 1);
675
+ var import_url_join = __toESM(require("url-join"), 1);
676
+
677
+ // src/LoginWithAuth0.ts
678
+ var DOMAIN_SUFFIX = "wandelbots.io";
679
+ var auth0ConfigMap = {
680
+ dev: {
681
+ domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,
682
+ clientId: "fLbJD0RLp5r2Dpucm5j8BjwMR6Hunfha"
683
+ },
684
+ stg: {
685
+ domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,
686
+ clientId: "joVDeD9e786WzFNSGCqoVq7HNkWt5j6s"
687
+ },
688
+ prod: {
689
+ domain: `https://auth.portal.${DOMAIN_SUFFIX}`,
690
+ clientId: "J7WJUi38xVQdJAEBNRT9Xw1b0fXDb4J2"
691
+ }
692
+ };
693
+ var getAuth0Config = (instanceUrl) => {
694
+ if (instanceUrl.includes(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev;
695
+ if (instanceUrl.includes(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg;
696
+ if (instanceUrl.includes(DOMAIN_SUFFIX)) return auth0ConfigMap.prod;
697
+ throw new Error(
698
+ "Unsupported instance URL. Cannot determine Auth0 configuration."
699
+ );
700
+ };
701
+ var loginWithAuth0 = (instanceUrl) => __async(void 0, null, function* () {
702
+ var _a;
703
+ if (typeof window === "undefined") {
704
+ throw new Error(
705
+ `Access token must be set to use NovaClient when not in a browser environment.`
706
+ );
707
+ }
708
+ const auth0Config = getAuth0Config(instanceUrl);
709
+ if (new URL(instanceUrl).origin === window.location.origin) {
710
+ window.location.reload();
711
+ throw new Error(
712
+ "Failed to reload page to get auth details, please refresh manually"
713
+ );
714
+ }
715
+ const { Auth0Client } = yield import("@auth0/auth0-spa-js");
716
+ const auth0Client = new Auth0Client({
717
+ domain: auth0Config.domain,
718
+ clientId: (_a = auth0Config.clientId) != null ? _a : "",
719
+ useRefreshTokens: false,
720
+ authorizationParams: {
721
+ audience: "nova-api",
722
+ redirect_uri: window.location.origin
723
+ }
724
+ });
725
+ if (window.location.search.includes("code=") && window.location.search.includes("state=")) {
726
+ const { appState } = yield auth0Client.handleRedirectCallback();
727
+ window.history.replaceState(
728
+ {},
729
+ document.title,
730
+ (appState == null ? void 0 : appState.returnTo) || window.location.pathname
731
+ );
732
+ } else {
733
+ yield auth0Client.loginWithRedirect();
734
+ }
735
+ const accessToken = yield auth0Client.getTokenSilently();
736
+ return accessToken;
737
+ });
738
+
739
+ // src/lib/AutoReconnectingWebsocket.ts
740
+ var import_reconnecting_websocket = __toESM(require("reconnecting-websocket"), 1);
741
+ var AutoReconnectingWebsocket = class extends import_reconnecting_websocket.default {
742
+ constructor(targetUrl, opts = {}) {
743
+ console.log("Opening websocket to", targetUrl);
744
+ super(() => this.targetUrl || targetUrl, void 0, {
745
+ startClosed: true
746
+ });
747
+ this.opts = opts;
748
+ this.disposed = false;
749
+ Object.defineProperty(this, "url", {
750
+ get() {
751
+ return this.targetUrl;
752
+ }
753
+ });
754
+ this.targetUrl = targetUrl;
755
+ this.addEventListener("open", () => {
756
+ console.log(`Websocket to ${this.url} opened`);
757
+ });
758
+ this.addEventListener("message", (ev) => {
759
+ if (!this.receivedFirstMessage) {
760
+ this.receivedFirstMessage = ev;
761
+ }
762
+ });
763
+ this.addEventListener("close", () => {
764
+ console.log(`Websocket to ${this.url} closed`);
765
+ });
766
+ const origReconnect = this.reconnect;
767
+ this.reconnect = () => {
768
+ if (this.opts.mock) {
769
+ this.opts.mock.handleWebsocketConnection(this);
770
+ } else {
771
+ origReconnect.apply(this);
772
+ }
773
+ };
774
+ this.reconnect();
775
+ }
776
+ changeUrl(targetUrl) {
777
+ this.receivedFirstMessage = void 0;
778
+ this.targetUrl = targetUrl;
779
+ this.reconnect();
780
+ }
781
+ sendJson(data) {
782
+ if (this.opts.mock) {
783
+ this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data));
784
+ } else {
785
+ this.send(JSON.stringify(data));
786
+ }
787
+ }
788
+ /**
789
+ * Permanently close this websocket and indicate that
790
+ * this object should not be used again.
791
+ **/
792
+ dispose() {
793
+ this.close();
794
+ this.disposed = true;
795
+ if (this.opts.onDispose) {
796
+ this.opts.onDispose();
797
+ }
798
+ }
799
+ /**
800
+ * Returns a promise that resolves once the websocket
801
+ * is in the OPEN state. */
802
+ opened() {
803
+ return __async(this, null, function* () {
804
+ return new Promise((resolve, reject) => {
805
+ if (this.readyState === WebSocket.OPEN) {
806
+ resolve();
807
+ } else {
808
+ this.addEventListener("open", () => resolve());
809
+ this.addEventListener("error", reject);
810
+ }
811
+ });
812
+ });
813
+ }
814
+ /**
815
+ * Returns a promise that resolves once the websocket
816
+ * is in the CLOSED state. */
817
+ closed() {
818
+ return __async(this, null, function* () {
819
+ return new Promise((resolve, reject) => {
820
+ if (this.readyState === WebSocket.CLOSED) {
821
+ resolve();
822
+ } else {
823
+ this.addEventListener("close", () => resolve());
824
+ this.addEventListener("error", reject);
825
+ }
826
+ });
827
+ });
828
+ }
829
+ /**
830
+ * Returns a promise that resolves when the first message
831
+ * is received from the websocket. Resolves immediately if
832
+ * the first message has already been received.
833
+ */
834
+ firstMessage() {
835
+ return __async(this, null, function* () {
836
+ if (this.receivedFirstMessage) {
837
+ return this.receivedFirstMessage;
838
+ }
839
+ return new Promise((resolve, reject) => {
840
+ const onMessage = (ev) => {
841
+ this.receivedFirstMessage = ev;
842
+ this.removeEventListener("message", onMessage);
843
+ this.removeEventListener("error", onError);
844
+ resolve(ev);
845
+ };
846
+ const onError = (ev) => {
847
+ this.removeEventListener("message", onMessage);
848
+ this.removeEventListener("error", onError);
849
+ reject(ev);
850
+ };
851
+ this.addEventListener("message", onMessage);
852
+ this.addEventListener("error", onError);
853
+ });
854
+ });
855
+ }
856
+ /**
857
+ * Returns a promise that resolves when the next message
858
+ * is received from the websocket.
859
+ */
860
+ nextMessage() {
861
+ return __async(this, null, function* () {
862
+ return new Promise((resolve, reject) => {
863
+ const onMessage = (ev) => {
864
+ this.removeEventListener("message", onMessage);
865
+ this.removeEventListener("error", onError);
866
+ resolve(ev);
867
+ };
868
+ const onError = (ev) => {
869
+ this.removeEventListener("message", onMessage);
870
+ this.removeEventListener("error", onError);
871
+ reject(ev);
872
+ };
873
+ this.addEventListener("message", onMessage);
874
+ this.addEventListener("error", onError);
875
+ });
876
+ });
877
+ }
878
+ };
879
+
880
+ // src/lib/availableStorage.ts
881
+ var AvailableStorage = class {
882
+ constructor() {
883
+ this.available = typeof window !== "undefined" && !!window.localStorage;
884
+ }
885
+ getJSON(key) {
886
+ if (!this.available) return null;
887
+ const result = window.localStorage.getItem(key);
888
+ if (result === null) return null;
889
+ try {
890
+ return JSON.parse(result);
891
+ } catch (err) {
892
+ return null;
893
+ }
894
+ }
895
+ setJSON(key, obj) {
896
+ if (!this.available) return null;
897
+ window.localStorage.setItem(key, JSON.stringify(obj));
898
+ }
899
+ delete(key) {
900
+ if (!this.available) return null;
901
+ window.localStorage.removeItem(key);
902
+ }
903
+ setString(key, value) {
904
+ if (!this.available) return null;
905
+ window.localStorage.setItem(key, value);
906
+ }
907
+ getString(key) {
908
+ if (!this.available) return null;
909
+ return window.localStorage.getItem(key);
910
+ }
911
+ };
912
+ var availableStorage = new AvailableStorage();
913
+
914
+ // src/lib/v2/mock/MockNovaInstance.ts
915
+ var import_axios3 = require("axios");
916
+ var pathToRegexp = __toESM(require("path-to-regexp"), 1);
917
+ var MockNovaInstance = class {
918
+ constructor() {
919
+ this.connections = [];
920
+ }
921
+ handleAPIRequest(config) {
922
+ return __async(this, null, function* () {
923
+ var _a, _b, _c;
924
+ const apiHandlers = [
925
+ {
926
+ method: "GET",
927
+ path: "/cells/:cellId/controllers",
928
+ handle() {
929
+ return {
930
+ controllers: [
931
+ {
932
+ controller: "mock-ur5e",
933
+ model_name: "UniversalRobots::Controller",
934
+ host: "mock-ur5e",
935
+ allow_software_install_on_controller: true,
936
+ motion_groups: [
937
+ {
938
+ motion_group: "0@mock-ur5e",
939
+ name_from_controller: "UR5e",
940
+ active: false,
941
+ model_from_controller: "UniversalRobots_UR5e"
942
+ }
943
+ ],
944
+ has_error: false,
945
+ error_details: ""
946
+ }
947
+ ]
948
+ };
949
+ }
950
+ },
951
+ {
952
+ method: "GET",
953
+ path: "/cells/:cellId/controllers/:controllerId",
954
+ handle() {
955
+ return {
956
+ configuration: {
957
+ kind: "VirtualController",
958
+ manufacturer: "universalrobots",
959
+ position: "[0,-1.571,-1.571,-1.571,1.571,-1.571,0]",
960
+ type: "universalrobots-ur5e"
961
+ },
962
+ name: "mock-ur5"
963
+ };
964
+ }
965
+ },
966
+ {
967
+ method: "GET",
968
+ path: "/cells/:cellId/motion-groups/:motionGroupId/specification",
969
+ handle() {
970
+ return {
971
+ dh_parameters: [
972
+ {
973
+ alpha: 1.5707963267948966,
974
+ theta: 0,
975
+ a: 0,
976
+ d: 162.25,
977
+ reverse_rotation_direction: false
978
+ },
979
+ {
980
+ alpha: 0,
981
+ theta: 0,
982
+ a: -425,
983
+ d: 0,
984
+ reverse_rotation_direction: false
985
+ },
986
+ {
987
+ alpha: 0,
988
+ theta: 0,
989
+ a: -392.2,
990
+ d: 0,
991
+ reverse_rotation_direction: false
992
+ },
993
+ {
994
+ alpha: 1.5707963267948966,
995
+ theta: 0,
996
+ a: 0,
997
+ d: 133.3,
998
+ reverse_rotation_direction: false
999
+ },
1000
+ {
1001
+ alpha: -1.5707963267948966,
1002
+ theta: 0,
1003
+ a: 0,
1004
+ d: 99.7,
1005
+ reverse_rotation_direction: false
1006
+ },
1007
+ {
1008
+ alpha: 0,
1009
+ theta: 0,
1010
+ a: 0,
1011
+ d: 99.6,
1012
+ reverse_rotation_direction: false
1013
+ }
1014
+ ],
1015
+ mechanical_joint_limits: [
1016
+ {
1017
+ joint: "JOINTNAME_AXIS_1",
1018
+ lower_limit: -6.335545063018799,
1019
+ upper_limit: 6.335545063018799,
1020
+ unlimited: false
1021
+ },
1022
+ {
1023
+ joint: "JOINTNAME_AXIS_2",
1024
+ lower_limit: -6.335545063018799,
1025
+ upper_limit: 6.335545063018799,
1026
+ unlimited: false
1027
+ },
1028
+ {
1029
+ joint: "JOINTNAME_AXIS_3",
1030
+ lower_limit: -6.335545063018799,
1031
+ upper_limit: 6.335545063018799,
1032
+ unlimited: false
1033
+ },
1034
+ {
1035
+ joint: "JOINTNAME_AXIS_4",
1036
+ lower_limit: -6.335545063018799,
1037
+ upper_limit: 6.335545063018799,
1038
+ unlimited: false
1039
+ },
1040
+ {
1041
+ joint: "JOINTNAME_AXIS_5",
1042
+ lower_limit: -6.335545063018799,
1043
+ upper_limit: 6.335545063018799,
1044
+ unlimited: false
1045
+ },
1046
+ {
1047
+ joint: "JOINTNAME_AXIS_6",
1048
+ lower_limit: -6.335545063018799,
1049
+ upper_limit: 6.335545063018799,
1050
+ unlimited: false
1051
+ }
1052
+ ]
1053
+ };
1054
+ }
1055
+ },
1056
+ {
1057
+ method: "GET",
1058
+ path: "/cells/:cellId/motion-groups/:motionGroupId/safety-setup",
1059
+ handle() {
1060
+ return {
1061
+ safety_settings: [
1062
+ {
1063
+ safety_state: "SAFETY_NORMAL",
1064
+ settings: {
1065
+ joint_position_limits: [
1066
+ {
1067
+ joint: "JOINTNAME_AXIS_1",
1068
+ lower_limit: -2.96705961227417,
1069
+ upper_limit: 2.96705961227417,
1070
+ unlimited: false
1071
+ },
1072
+ {
1073
+ joint: "JOINTNAME_AXIS_2",
1074
+ lower_limit: -1.7453292608261108,
1075
+ upper_limit: 2.7925267219543457,
1076
+ unlimited: false
1077
+ },
1078
+ {
1079
+ joint: "JOINTNAME_AXIS_3",
1080
+ lower_limit: -3.3161256313323975,
1081
+ upper_limit: 0.40142571926116943,
1082
+ unlimited: false
1083
+ },
1084
+ {
1085
+ joint: "JOINTNAME_AXIS_4",
1086
+ lower_limit: -3.4906585216522217,
1087
+ upper_limit: 3.4906585216522217,
1088
+ unlimited: false
1089
+ },
1090
+ {
1091
+ joint: "JOINTNAME_AXIS_5",
1092
+ lower_limit: -2.4434609413146973,
1093
+ upper_limit: 2.4434609413146973,
1094
+ unlimited: false
1095
+ },
1096
+ {
1097
+ joint: "JOINTNAME_AXIS_6",
1098
+ lower_limit: -4.71238899230957,
1099
+ upper_limit: 4.71238899230957,
1100
+ unlimited: false
1101
+ }
1102
+ ],
1103
+ joint_velocity_limits: [
1104
+ {
1105
+ joint: "JOINTNAME_AXIS_1",
1106
+ limit: 3.1415927410125732
1107
+ },
1108
+ {
1109
+ joint: "JOINTNAME_AXIS_2",
1110
+ limit: 3.1415927410125732
1111
+ },
1112
+ {
1113
+ joint: "JOINTNAME_AXIS_3",
1114
+ limit: 3.4906585216522217
1115
+ },
1116
+ {
1117
+ joint: "JOINTNAME_AXIS_4",
1118
+ limit: 6.108652591705322
1119
+ },
1120
+ {
1121
+ joint: "JOINTNAME_AXIS_5",
1122
+ limit: 6.108652591705322
1123
+ },
1124
+ {
1125
+ joint: "JOINTNAME_AXIS_6",
1126
+ limit: 6.981317043304443
1127
+ }
1128
+ ],
1129
+ joint_acceleration_limits: [],
1130
+ joint_torque_limits: [],
1131
+ tcp_velocity_limit: 1800
1132
+ }
1133
+ }
1134
+ ],
1135
+ safety_zones: [
1136
+ {
1137
+ id: 1,
1138
+ priority: 0,
1139
+ geometry: {
1140
+ compound: {
1141
+ child_geometries: [
1142
+ {
1143
+ convex_hull: {
1144
+ vertices: [
1145
+ { vertex: [-800, -1330, -1820] },
1146
+ { vertex: [1650, -1330, -1820] },
1147
+ { vertex: [1650, 1330, -1820] },
1148
+ { vertex: [-800, 1330, -1820] }
1149
+ ]
1150
+ },
1151
+ init_pose: {
1152
+ position: [0, 0, 0],
1153
+ orientation: [0, 0, 0, 1]
1154
+ },
1155
+ id: "box"
1156
+ },
1157
+ {
1158
+ convex_hull: {
1159
+ vertices: [
1160
+ {
1161
+ vertex: [-800, -1330, -1820]
1162
+ },
1163
+ {
1164
+ vertex: [1650, -1330, -1820]
1165
+ },
1166
+ {
1167
+ vertex: [1650, -1330, 1500]
1168
+ },
1169
+ {
1170
+ vertex: [-800, -1330, 1500]
1171
+ }
1172
+ ]
1173
+ },
1174
+ init_pose: {
1175
+ position: [0, 0, 0],
1176
+ orientation: [0, 0, 0, 1]
1177
+ },
1178
+ id: "box"
1179
+ },
1180
+ {
1181
+ convex_hull: {
1182
+ vertices: [
1183
+ {
1184
+ vertex: [-800, -1330, -1820]
1185
+ },
1186
+ {
1187
+ vertex: [-800, 1330, -1820]
1188
+ },
1189
+ {
1190
+ vertex: [-800, 1330, 1500]
1191
+ },
1192
+ {
1193
+ vertex: [-800, -1330, 1500]
1194
+ }
1195
+ ]
1196
+ },
1197
+ init_pose: {
1198
+ position: [0, 0, 0],
1199
+ orientation: [0, 0, 0, 1]
1200
+ },
1201
+ id: "box"
1202
+ },
1203
+ {
1204
+ convex_hull: {
1205
+ vertices: [
1206
+ {
1207
+ vertex: [1650, 1330, 1500]
1208
+ },
1209
+ {
1210
+ vertex: [-800, 1330, 1500]
1211
+ },
1212
+ {
1213
+ vertex: [-800, -1330, 1500]
1214
+ },
1215
+ {
1216
+ vertex: [1650, -1330, 1500]
1217
+ }
1218
+ ]
1219
+ },
1220
+ init_pose: {
1221
+ position: [0, 0, 0],
1222
+ orientation: [0, 0, 0, 1]
1223
+ },
1224
+ id: "box"
1225
+ },
1226
+ {
1227
+ convex_hull: {
1228
+ vertices: [
1229
+ {
1230
+ vertex: [1650, 1330, 1500]
1231
+ },
1232
+ {
1233
+ vertex: [-800, 1330, 1500]
1234
+ },
1235
+ {
1236
+ vertex: [-800, 1330, -1820]
1237
+ },
1238
+ {
1239
+ vertex: [1650, 1330, -1820]
1240
+ }
1241
+ ]
1242
+ },
1243
+ init_pose: {
1244
+ position: [0, 0, 0],
1245
+ orientation: [0, 0, 0, 1]
1246
+ },
1247
+ id: "box"
1248
+ },
1249
+ {
1250
+ convex_hull: {
1251
+ vertices: [
1252
+ {
1253
+ vertex: [1650, 1330, 1500]
1254
+ },
1255
+ {
1256
+ vertex: [1650, -1330, 1500]
1257
+ },
1258
+ {
1259
+ vertex: [1650, -1330, -1820]
1260
+ },
1261
+ {
1262
+ vertex: [1650, 1330, -1820]
1263
+ }
1264
+ ]
1265
+ },
1266
+ init_pose: {
1267
+ position: [0, 0, 0],
1268
+ orientation: [0, 0, 0, 1]
1269
+ },
1270
+ id: "box"
1271
+ }
1272
+ ]
1273
+ },
1274
+ init_pose: {
1275
+ position: [0, 0, 0],
1276
+ orientation: [0, 0, 0, 1]
1277
+ },
1278
+ id: "Cell workzone"
1279
+ },
1280
+ motion_group_uid: 1
1281
+ },
1282
+ {
1283
+ id: 2,
1284
+ priority: 0,
1285
+ geometry: {
1286
+ convex_hull: {
1287
+ vertices: [
1288
+ {
1289
+ vertex: [1650, 1330, -1850]
1290
+ },
1291
+ {
1292
+ vertex: [865, 1330, -1850]
1293
+ },
1294
+ {
1295
+ vertex: [865, -720, -1850]
1296
+ },
1297
+ {
1298
+ vertex: [1650, -720, -1850]
1299
+ },
1300
+ {
1301
+ vertex: [1650, 1330, -920]
1302
+ },
1303
+ {
1304
+ vertex: [865, 1330, -920]
1305
+ },
1306
+ {
1307
+ vertex: [865, -720, -920]
1308
+ },
1309
+ {
1310
+ vertex: [1650, -720, -920]
1311
+ }
1312
+ ]
1313
+ },
1314
+ init_pose: {
1315
+ position: [0, 0, 0],
1316
+ orientation: [0, 0, 0, 1]
1317
+ },
1318
+ id: "Transport"
1319
+ },
1320
+ motion_group_uid: 1
1321
+ },
1322
+ {
1323
+ id: 3,
1324
+ priority: 0,
1325
+ geometry: {
1326
+ convex_hull: {
1327
+ vertices: [
1328
+ {
1329
+ vertex: [1650, 1330, -600]
1330
+ },
1331
+ {
1332
+ vertex: [865, 1330, -600]
1333
+ },
1334
+ {
1335
+ vertex: [865, 430, -600]
1336
+ },
1337
+ {
1338
+ vertex: [1650, 430, -600]
1339
+ },
1340
+ {
1341
+ vertex: [1650, 1330, -1250]
1342
+ },
1343
+ {
1344
+ vertex: [865, 1330, -1250]
1345
+ },
1346
+ {
1347
+ vertex: [865, 430, -1250]
1348
+ },
1349
+ {
1350
+ vertex: [1650, 430, -1250]
1351
+ }
1352
+ ]
1353
+ },
1354
+ init_pose: {
1355
+ position: [0, 0, 0],
1356
+ orientation: [0, 0, 0, 1]
1357
+ },
1358
+ id: "Tunel"
1359
+ },
1360
+ motion_group_uid: 1
1361
+ },
1362
+ {
1363
+ id: 4,
1364
+ priority: 0,
1365
+ geometry: {
1366
+ convex_hull: {
1367
+ vertices: [
1368
+ {
1369
+ vertex: [1650, -760, -440]
1370
+ },
1371
+ {
1372
+ vertex: [900, -760, -440]
1373
+ },
1374
+ {
1375
+ vertex: [900, -1330, -440]
1376
+ },
1377
+ {
1378
+ vertex: [1650, -1330, -440]
1379
+ },
1380
+ {
1381
+ vertex: [1650, -760, -1800]
1382
+ },
1383
+ {
1384
+ vertex: [900, -760, -1800]
1385
+ },
1386
+ {
1387
+ vertex: [900, -1330, -1800]
1388
+ },
1389
+ {
1390
+ vertex: [1650, -1330, -1800]
1391
+ }
1392
+ ]
1393
+ },
1394
+ init_pose: {
1395
+ position: [0, 0, 0],
1396
+ orientation: [0, 0, 0, 1]
1397
+ },
1398
+ id: "Fanuc controller"
1399
+ },
1400
+ motion_group_uid: 1
1401
+ },
1402
+ {
1403
+ id: 6,
1404
+ priority: 0,
1405
+ geometry: {
1406
+ convex_hull: {
1407
+ vertices: [
1408
+ {
1409
+ vertex: [-200, -200, -1900]
1410
+ },
1411
+ {
1412
+ vertex: [200, -200, -1900]
1413
+ },
1414
+ {
1415
+ vertex: [200, 200, -1900]
1416
+ },
1417
+ {
1418
+ vertex: [-200, 200, -1900]
1419
+ },
1420
+ {
1421
+ vertex: [-200, -200, -350]
1422
+ },
1423
+ {
1424
+ vertex: [200, -200, -350]
1425
+ },
1426
+ {
1427
+ vertex: [200, 200, -350]
1428
+ },
1429
+ {
1430
+ vertex: [-200, 200, -350]
1431
+ }
1432
+ ]
1433
+ },
1434
+ init_pose: {
1435
+ position: [0, 0, 0],
1436
+ orientation: [0, 0, 0, 1]
1437
+ },
1438
+ id: "Robot base"
1439
+ },
1440
+ motion_group_uid: 1
1441
+ }
1442
+ ],
1443
+ robot_model_geometries: [
1444
+ {
1445
+ link_index: 1,
1446
+ geometry: {
1447
+ sphere: {
1448
+ radius: 270
1449
+ },
1450
+ init_pose: {
1451
+ position: [-70, -70, -50],
1452
+ orientation: [0, 0, 0, 1]
1453
+ },
1454
+ id: "link1_sphere"
1455
+ }
1456
+ },
1457
+ {
1458
+ link_index: 2,
1459
+ geometry: {
1460
+ capsule: {
1461
+ radius: 160,
1462
+ cylinder_height: 800
1463
+ },
1464
+ init_pose: {
1465
+ position: [-450, 40, 170],
1466
+ orientation: [
1467
+ 0,
1468
+ -0.7071067811865475,
1469
+ 0,
1470
+ 0.7071067811865476
1471
+ ]
1472
+ },
1473
+ id: "link2_capsule"
1474
+ }
1475
+ },
1476
+ {
1477
+ link_index: 3,
1478
+ geometry: {
1479
+ sphere: {
1480
+ radius: 270
1481
+ },
1482
+ init_pose: {
1483
+ position: [-110, 10, -100],
1484
+ orientation: [0, 0, 0, 1]
1485
+ },
1486
+ id: "link3_sphere"
1487
+ }
1488
+ },
1489
+ {
1490
+ link_index: 4,
1491
+ geometry: {
1492
+ capsule: {
1493
+ radius: 110,
1494
+ cylinder_height: 600
1495
+ },
1496
+ init_pose: {
1497
+ position: [0, 300, 40],
1498
+ orientation: [
1499
+ -0.7071067811865475,
1500
+ 0,
1501
+ 0,
1502
+ 0.7071067811865476
1503
+ ]
1504
+ },
1505
+ id: "link4_capsule"
1506
+ }
1507
+ },
1508
+ {
1509
+ link_index: 5,
1510
+ geometry: {
1511
+ sphere: {
1512
+ radius: 75
1513
+ },
1514
+ init_pose: {
1515
+ position: [0, 0, -50],
1516
+ orientation: [0, 0, 0, 1]
1517
+ },
1518
+ id: "link5_sphere"
1519
+ }
1520
+ }
1521
+ ],
1522
+ tool_geometries: []
1523
+ };
1524
+ }
1525
+ },
1526
+ {
1527
+ method: "GET",
1528
+ path: "/cells/:cellId/coordinate-systems",
1529
+ handle() {
1530
+ return {
1531
+ coordinatesystems: [
1532
+ {
1533
+ coordinate_system: "",
1534
+ name: "world",
1535
+ reference_uid: "",
1536
+ position: [0, 0, 0],
1537
+ rotation: {
1538
+ angles: [0, 0, 0],
1539
+ type: "ROTATION_VECTOR"
1540
+ }
1541
+ }
1542
+ ]
1543
+ };
1544
+ }
1545
+ },
1546
+ {
1547
+ method: "GET",
1548
+ path: "/cells/:cellId/motion-groups/:motionGroupId/tcps",
1549
+ handle() {
1550
+ return {
1551
+ tcps: [
1552
+ {
1553
+ id: "Flange",
1554
+ readable_name: "Default-Flange",
1555
+ position: [0, 0, 0],
1556
+ rotation: {
1557
+ angles: [0, 0, 0, 0],
1558
+ type: "ROTATION_VECTOR"
1559
+ }
1560
+ },
1561
+ {
1562
+ id: "complex-tcp-position",
1563
+ readable_name: "Complex TCP Position",
1564
+ position: [-200, 300, 150],
1565
+ rotation: {
1566
+ angles: [
1567
+ -0.12139440409113832,
1568
+ -0.06356210998212003,
1569
+ -0.2023240068185639,
1570
+ 0
1571
+ ],
1572
+ type: "ROTATION_VECTOR"
1573
+ }
1574
+ }
1575
+ ]
1576
+ };
1577
+ }
1578
+ }
1579
+ ];
1580
+ const method = ((_a = config.method) == null ? void 0 : _a.toUpperCase()) || "GET";
1581
+ const path = "/cells" + ((_c = (_b = config.url) == null ? void 0 : _b.split("/cells")[1]) == null ? void 0 : _c.split("?")[0]);
1582
+ for (const handler of apiHandlers) {
1583
+ const match2 = pathToRegexp.match(handler.path)(path || "");
1584
+ if (method === handler.method && match2) {
1585
+ const json = handler.handle();
1586
+ return {
1587
+ status: 200,
1588
+ statusText: "Success",
1589
+ data: JSON.stringify(json),
1590
+ headers: {},
1591
+ config,
1592
+ request: {
1593
+ responseURL: config.url
1594
+ }
1595
+ };
1596
+ }
1597
+ }
1598
+ throw new import_axios3.AxiosError(
1599
+ `No mock handler matched this request: ${method} ${path}`,
1600
+ "404",
1601
+ config
1602
+ );
1603
+ });
1604
+ }
1605
+ handleWebsocketConnection(socket) {
1606
+ this.connections.push(socket);
1607
+ setTimeout(() => {
1608
+ socket.dispatchEvent(new Event("open"));
1609
+ console.log("Websocket connection opened from", socket.url);
1610
+ if (socket.url.includes("/state-stream")) {
1611
+ socket.dispatchEvent(
1612
+ new MessageEvent("message", {
1613
+ data: JSON.stringify(defaultMotionState)
1614
+ })
1615
+ );
1616
+ }
1617
+ if (socket.url.includes("/move-joint")) {
1618
+ socket.dispatchEvent(
1619
+ new MessageEvent("message", {
1620
+ data: JSON.stringify({
1621
+ result: {
1622
+ motion_group: "0@ur",
1623
+ state: {
1624
+ controller: "ur",
1625
+ operation_mode: "OPERATION_MODE_AUTO",
1626
+ safety_state: "SAFETY_STATE_NORMAL",
1627
+ timestamp: "2024-09-18T12:48:26.096266444Z",
1628
+ velocity_override: 100,
1629
+ motion_groups: [
1630
+ {
1631
+ motion_group: "0@ur",
1632
+ controller: "ur",
1633
+ joint_position: {
1634
+ joints: [
1635
+ 1.3492152690887451,
1636
+ -1.5659207105636597,
1637
+ 1.6653711795806885,
1638
+ -1.0991662740707397,
1639
+ -1.829018235206604,
1640
+ 1.264623761177063
1641
+ ]
1642
+ },
1643
+ joint_velocity: {
1644
+ joints: [0, 0, 0, 0, 0, 0]
1645
+ },
1646
+ flange_pose: {
1647
+ position: [
1648
+ 6.437331889439328,
1649
+ -628.4123774830913,
1650
+ 577.0569957147832
1651
+ ],
1652
+ orientation: {
1653
+ x: -1.683333649797158,
1654
+ y: -1.9783363827298732,
1655
+ z: -0.4928031860165713
1656
+ },
1657
+ coordinate_system: ""
1658
+ },
1659
+ tcp_pose: {
1660
+ position: [
1661
+ 6.437331889439328,
1662
+ -628.4123774830913,
1663
+ 577.0569957147832
1664
+ ],
1665
+ orientation: {
1666
+ x: -1.683333649797158,
1667
+ y: -1.9783363827298732,
1668
+ z: -0.4928031860165713
1669
+ },
1670
+ coordinate_system: "",
1671
+ tcp: "Flange"
1672
+ },
1673
+ velocity: {
1674
+ linear: {
1675
+ x: 0,
1676
+ y: 0,
1677
+ z: 0
1678
+ },
1679
+ angular: {
1680
+ x: -0,
1681
+ y: 0,
1682
+ z: 0
1683
+ },
1684
+ coordinate_system: ""
1685
+ },
1686
+ force: {
1687
+ force: {
1688
+ x: 0,
1689
+ y: 0,
1690
+ z: 0
1691
+ },
1692
+ moment: {
1693
+ x: 0,
1694
+ y: 0,
1695
+ z: 0
1696
+ },
1697
+ coordinate_system: ""
1698
+ },
1699
+ joint_limit_reached: {
1700
+ limit_reached: [
1701
+ false,
1702
+ false,
1703
+ false,
1704
+ false,
1705
+ false,
1706
+ false
1707
+ ]
1708
+ },
1709
+ joint_current: {
1710
+ joints: [0, 0, 0, 0, 0, 0]
1711
+ },
1712
+ sequence_number: "671259"
1713
+ }
1714
+ ],
1715
+ sequence_number: "671259"
1716
+ },
1717
+ movement_state: "MOVEMENT_STATE_MOVING"
1718
+ }
1719
+ })
1720
+ })
1721
+ );
1722
+ }
1723
+ if (socket.url.includes("/move-tcp")) {
1724
+ socket.dispatchEvent(
1725
+ new MessageEvent("message", {
1726
+ data: JSON.stringify({
1727
+ result: {
1728
+ motion_group: "0@ur",
1729
+ state: {
1730
+ controller: "ur",
1731
+ operation_mode: "OPERATION_MODE_AUTO",
1732
+ safety_state: "SAFETY_STATE_NORMAL",
1733
+ timestamp: "2024-09-18T12:43:12.188335774Z",
1734
+ velocity_override: 100,
1735
+ motion_groups: [
1736
+ {
1737
+ motion_group: "0@ur",
1738
+ controller: "ur",
1739
+ joint_position: {
1740
+ joints: [
1741
+ 1.3352527618408203,
1742
+ -1.5659207105636597,
1743
+ 1.6653711795806885,
1744
+ -1.110615611076355,
1745
+ -1.829018235206604,
1746
+ 1.264623761177063
1747
+ ]
1748
+ },
1749
+ joint_velocity: {
1750
+ joints: [0, 0, 0, 0, 0, 0]
1751
+ },
1752
+ flange_pose: {
1753
+ position: [
1754
+ -2.763015284002938,
1755
+ -630.2151479701106,
1756
+ 577.524509114342
1757
+ ],
1758
+ orientation: {
1759
+ x: -1.704794877102097,
1760
+ y: -1.9722372952861567,
1761
+ z: -0.4852079204210754
1762
+ },
1763
+ coordinate_system: ""
1764
+ },
1765
+ tcp_pose: {
1766
+ position: [
1767
+ -2.763015284002938,
1768
+ -630.2151479701106,
1769
+ 577.524509114342
1770
+ ],
1771
+ orientation: {
1772
+ x: -1.704794877102097,
1773
+ y: -1.9722372952861567,
1774
+ z: -0.4852079204210754
1775
+ },
1776
+ coordinate_system: "",
1777
+ tcp: "Flange"
1778
+ },
1779
+ velocity: {
1780
+ linear: {
1781
+ x: 0,
1782
+ y: 0,
1783
+ z: 0
1784
+ },
1785
+ angular: {
1786
+ x: -0,
1787
+ y: 0,
1788
+ z: 0
1789
+ },
1790
+ coordinate_system: ""
1791
+ },
1792
+ force: {
1793
+ force: {
1794
+ x: 0,
1795
+ y: 0,
1796
+ z: 0
1797
+ },
1798
+ moment: {
1799
+ x: 0,
1800
+ y: 0,
1801
+ z: 0
1802
+ },
1803
+ coordinate_system: ""
1804
+ },
1805
+ joint_limit_reached: {
1806
+ limit_reached: [
1807
+ false,
1808
+ false,
1809
+ false,
1810
+ false,
1811
+ false,
1812
+ false
1813
+ ]
1814
+ },
1815
+ joint_current: {
1816
+ joints: [0, 0, 0, 0, 0, 0]
1817
+ },
1818
+ sequence_number: "627897"
1819
+ }
1820
+ ],
1821
+ sequence_number: "627897"
1822
+ },
1823
+ movement_state: "MOVEMENT_STATE_MOVING"
1824
+ }
1825
+ })
1826
+ })
1827
+ );
1828
+ }
1829
+ }, 10);
1830
+ }
1831
+ handleWebsocketMessage(socket, message) {
1832
+ console.log(`Received message on ${socket.url}`, message);
1833
+ }
1834
+ };
1835
+ var defaultMotionState = {
1836
+ result: {
1837
+ motion_group: "0@universalrobots-ur5e",
1838
+ controller: "universalrobots-ur5e",
1839
+ joint_position: {
1840
+ joints: [
1841
+ 1.1699999570846558,
1842
+ -1.5700000524520874,
1843
+ 1.3600000143051147,
1844
+ 1.0299999713897705,
1845
+ 1.2899999618530273,
1846
+ 1.2799999713897705
1847
+ ]
1848
+ },
1849
+ joint_velocity: {
1850
+ joints: [0, 0, 0, 0, 0, 0]
1851
+ },
1852
+ flange_pose: {
1853
+ position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],
1854
+ orientation: [
1855
+ 1.7564919306270736,
1856
+ -1.7542521568325058,
1857
+ 0.7326972590614671
1858
+ ],
1859
+ coordinate_system: ""
1860
+ },
1861
+ tcp_pose: {
1862
+ position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],
1863
+ orientation: [
1864
+ 1.7564919306270736,
1865
+ -1.7542521568325058,
1866
+ 0.7326972590614671
1867
+ ],
1868
+ coordinate_system: "",
1869
+ tcp: "Flange"
1870
+ },
1871
+ velocity: {
1872
+ linear: [0, 0, 0],
1873
+ angular: [0, 0, 0],
1874
+ coordinate_system: ""
1875
+ },
1876
+ force: {
1877
+ force: [0, 0, 0],
1878
+ moment: [0, 0, 0],
1879
+ coordinate_system: ""
1880
+ },
1881
+ joint_limit_reached: {
1882
+ limit_reached: [false, false, false, false, false, false]
1883
+ },
1884
+ joint_current: {
1885
+ joints: [0, 0, 0, 0, 0, 0]
1886
+ }
1887
+ }
1888
+ };
1889
+
1890
+ // src/lib/v2/NovaClient.ts
1891
+ var NovaClient = class {
1892
+ constructor(config) {
1893
+ this.authPromise = null;
1894
+ this.accessToken = null;
1895
+ var _a;
1896
+ console.warn("Using experimental NOVA v2 client");
1897
+ const cellId = (_a = config.cellId) != null ? _a : "cell";
1898
+ this.config = __spreadValues({
1899
+ cellId
1900
+ }, config);
1901
+ this.accessToken = config.accessToken || availableStorage.getString("wbjs.access_token") || null;
1902
+ if (this.config.instanceUrl === "https://mock.example.com") {
1903
+ this.mock = new MockNovaInstance();
1904
+ }
1905
+ const axiosInstance = import_axios4.default.create({
1906
+ baseURL: (0, import_url_join.default)(this.config.instanceUrl, "/api/v2")
1907
+ });
1908
+ axiosInstance.interceptors.request.use((request) => __async(this, null, function* () {
1909
+ if (!request.headers.Authorization) {
1910
+ if (this.accessToken) {
1911
+ request.headers.Authorization = `Bearer ${this.accessToken}`;
1912
+ } else if (this.config.username && this.config.password) {
1913
+ request.headers.Authorization = `Basic ${btoa(config.username + ":" + config.password)}`;
1914
+ }
1915
+ }
1916
+ return request;
1917
+ }));
1918
+ if (typeof window !== "undefined") {
1919
+ axiosInstance.interceptors.response.use(
1920
+ (r) => r,
1921
+ (error) => __async(this, null, function* () {
1922
+ var _a2, _b;
1923
+ if ((0, import_axios4.isAxiosError)(error)) {
1924
+ if (((_a2 = error.response) == null ? void 0 : _a2.status) === 401) {
1925
+ try {
1926
+ yield this.renewAuthentication();
1927
+ if (error.config) {
1928
+ if (this.accessToken) {
1929
+ error.config.headers.Authorization = `Bearer ${this.accessToken}`;
1930
+ } else {
1931
+ delete error.config.headers.Authorization;
1932
+ }
1933
+ return axiosInstance.request(error.config);
1934
+ }
1935
+ } catch (err) {
1936
+ return Promise.reject(err);
1937
+ }
1938
+ } else if (((_b = error.response) == null ? void 0 : _b.status) === 503) {
1939
+ const res = yield fetch(window.location.href);
1940
+ if (res.status === 503) {
1941
+ window.location.reload();
1942
+ }
1943
+ }
1944
+ }
1945
+ return Promise.reject(error);
1946
+ })
1947
+ );
1948
+ }
1949
+ this.api = new NovaCellAPIClient(cellId, __spreadProps(__spreadValues({}, config), {
1950
+ basePath: (0, import_url_join.default)(this.config.instanceUrl, "/api/v1"),
1951
+ isJsonMime: (mime) => {
1952
+ return mime === "application/json";
1953
+ },
1954
+ baseOptions: __spreadValues(__spreadValues({}, this.mock ? {
1955
+ adapter: (config2) => {
1956
+ return this.mock.handleAPIRequest(config2);
1957
+ }
1958
+ } : {}), config.baseOptions),
1959
+ axiosInstance
1960
+ }));
1961
+ }
1962
+ renewAuthentication() {
1963
+ return __async(this, null, function* () {
1964
+ if (this.authPromise) {
1965
+ return;
1966
+ }
1967
+ this.authPromise = loginWithAuth0(this.config.instanceUrl);
1968
+ try {
1969
+ this.accessToken = yield this.authPromise;
1970
+ if (this.accessToken) {
1971
+ availableStorage.setString("wbjs.access_token", this.accessToken);
1972
+ } else {
1973
+ availableStorage.delete("wbjs.access_token");
1974
+ }
1975
+ } finally {
1976
+ this.authPromise = null;
1977
+ }
1978
+ });
1979
+ }
1980
+ makeWebsocketURL(path) {
1981
+ const url = new URL(
1982
+ (0, import_url_join.default)(
1983
+ this.config.instanceUrl,
1984
+ `/api/v1/cells/${this.config.cellId}`,
1985
+ path
1986
+ )
1987
+ );
1988
+ url.protocol = url.protocol.replace("http", "ws");
1989
+ url.protocol = url.protocol.replace("https", "wss");
1990
+ if (this.accessToken) {
1991
+ url.searchParams.append("token", this.accessToken);
1992
+ } else if (this.config.username && this.config.password) {
1993
+ url.username = this.config.username;
1994
+ url.password = this.config.password;
1995
+ }
1996
+ return url.toString();
1997
+ }
1998
+ /**
1999
+ * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.
2000
+ * If you explicitly want to reconnect an existing websocket, call `reconnect`
2001
+ * on the returned object.
2002
+ */
2003
+ openReconnectingWebsocket(path) {
2004
+ return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {
2005
+ mock: this.mock
2006
+ });
2007
+ }
2008
+ /**
2009
+ * Connect to the motion state websocket(s) for a given motion group
2010
+ */
2011
+ connectMotionStream(motionGroupId) {
2012
+ return __async(this, null, function* () {
2013
+ return yield MotionStreamConnection.open(this, motionGroupId);
2014
+ });
2015
+ }
2016
+ connectMotionGroups(motionGroupIds) {
2017
+ return __async(this, null, function* () {
2018
+ const { controllers } = yield this.api.controller.listControllers();
2019
+ return Promise.all(
2020
+ motionGroupIds.map(
2021
+ (motionGroupId) => ConnectedMotionGroup.connect(this, motionGroupId, controllers)
2022
+ )
2023
+ );
2024
+ });
2025
+ }
2026
+ connectMotionGroup(motionGroupId) {
2027
+ return __async(this, null, function* () {
2028
+ const motionGroups = yield this.connectMotionGroups([motionGroupId]);
2029
+ return motionGroups[0];
2030
+ });
2031
+ }
2032
+ };
2033
+
2034
+ // src/lib/v2/ProgramStateConnection.ts
2035
+ var import_axios5 = require("axios");
2036
+ var import_mobx3 = require("mobx");
2037
+ var ProgramState = /* @__PURE__ */ ((ProgramState2) => {
2038
+ ProgramState2["NotStarted"] = "not started";
2039
+ ProgramState2["Running"] = "running";
2040
+ ProgramState2["Stopped"] = "stopped";
2041
+ ProgramState2["Failed"] = "failed";
2042
+ ProgramState2["Completed"] = "completed";
2043
+ return ProgramState2;
2044
+ })(ProgramState || {});
2045
+ var ProgramStateConnection = class {
2046
+ constructor(nova) {
2047
+ this.nova = nova;
2048
+ this.currentProgram = {};
2049
+ this.logs = [];
2050
+ this.executionState = "idle";
2051
+ this.currentlyExecutingProgramRunnerId = null;
2052
+ (0, import_mobx3.makeAutoObservable)(this, {}, { autoBind: true });
2053
+ this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`);
2054
+ this.programStateSocket.addEventListener("message", (ev) => {
2055
+ const msg = tryParseJson(ev.data);
2056
+ if (!msg) {
2057
+ console.error("Failed to parse program state message", ev.data);
2058
+ return;
2059
+ }
2060
+ if (msg.type === "update") {
2061
+ this.handleProgramStateMessage(msg);
2062
+ }
2063
+ });
2064
+ }
2065
+ /** Handle a program state update from the backend */
2066
+ handleProgramStateMessage(msg) {
2067
+ return __async(this, null, function* () {
2068
+ var _a;
2069
+ const { runner } = msg;
2070
+ if (runner.id !== this.currentlyExecutingProgramRunnerId) return;
2071
+ if (runner.state === "failed" /* Failed */) {
2072
+ try {
2073
+ const runnerState = yield this.nova.api.program.getProgramRunner(
2074
+ runner.id
2075
+ );
2076
+ const stdout = runnerState.stdout;
2077
+ if (stdout) {
2078
+ this.log(stdout);
2079
+ }
2080
+ this.logError(
2081
+ `Program runner ${runner.id} failed with error: ${runnerState.error}
2082
+ ${runnerState.traceback}`
2083
+ );
2084
+ } catch (err) {
2085
+ this.logError(
2086
+ `Failed to retrieve results for program ${runner.id}: ${err}`
2087
+ );
2088
+ }
2089
+ this.currentProgram.state = "failed" /* Failed */;
2090
+ this.gotoIdleState();
2091
+ } else if (runner.state === "stopped" /* Stopped */) {
2092
+ try {
2093
+ const runnerState = yield this.nova.api.program.getProgramRunner(
2094
+ runner.id
2095
+ );
2096
+ const stdout = runnerState.stdout;
2097
+ if (stdout) {
2098
+ this.log(stdout);
2099
+ }
2100
+ this.currentProgram.state = "stopped" /* Stopped */;
2101
+ this.log(`Program runner ${runner.id} stopped`);
2102
+ } catch (err) {
2103
+ this.logError(
2104
+ `Failed to retrieve results for program ${runner.id}: ${err}`
2105
+ );
2106
+ }
2107
+ this.gotoIdleState();
2108
+ } else if (runner.state === "completed" /* Completed */) {
2109
+ try {
2110
+ const runnerState = yield this.nova.api.program.getProgramRunner(
2111
+ runner.id
2112
+ );
2113
+ const stdout = runnerState.stdout;
2114
+ if (stdout) {
2115
+ this.log(stdout);
2116
+ }
2117
+ this.log(
2118
+ `Program runner ${runner.id} finished successfully in ${(_a = runner.execution_time) == null ? void 0 : _a.toFixed(2)} seconds`
2119
+ );
2120
+ this.currentProgram.state = "completed" /* Completed */;
2121
+ } catch (err) {
2122
+ this.logError(
2123
+ `Failed to retrieve results for program ${runner.id}: ${err}`
2124
+ );
2125
+ }
2126
+ this.gotoIdleState();
2127
+ } else if (runner.state === "running" /* Running */) {
2128
+ this.currentProgram.state = "running" /* Running */;
2129
+ this.log(`Program runner ${runner.id} now running`);
2130
+ } else if (runner.state !== "not started" /* NotStarted */) {
2131
+ console.error(runner);
2132
+ this.logError(
2133
+ `Program runner ${runner.id} entered unexpected state: ${runner.state}`
2134
+ );
2135
+ this.currentProgram.state = "not started" /* NotStarted */;
2136
+ this.gotoIdleState();
2137
+ }
2138
+ });
2139
+ }
2140
+ /** Call when a program is no longer executing */
2141
+ gotoIdleState() {
2142
+ (0, import_mobx3.runInAction)(() => {
2143
+ this.executionState = "idle";
2144
+ });
2145
+ this.currentlyExecutingProgramRunnerId = null;
2146
+ }
2147
+ executeProgram(wandelscript, initial_state, activeRobot) {
2148
+ return __async(this, null, function* () {
2149
+ this.currentProgram = {
2150
+ wandelscript,
2151
+ state: "not started" /* NotStarted */
2152
+ };
2153
+ const { currentProgram: openProgram } = this;
2154
+ if (!openProgram) return;
2155
+ (0, import_mobx3.runInAction)(() => {
2156
+ this.executionState = "starting";
2157
+ });
2158
+ const trimmedCode = openProgram.wandelscript.replaceAll(/^\s*$/gm, "");
2159
+ try {
2160
+ const programRunnerRef = yield this.nova.api.program.createProgramRunner(
2161
+ {
2162
+ code: trimmedCode,
2163
+ initial_state,
2164
+ default_robot: activeRobot == null ? void 0 : activeRobot.wandelscriptIdentifier
2165
+ },
2166
+ {
2167
+ headers: {
2168
+ "Content-Type": "application/json"
2169
+ }
2170
+ }
2171
+ );
2172
+ this.log(`Created program runner ${programRunnerRef.id}"`);
2173
+ (0, import_mobx3.runInAction)(() => {
2174
+ this.executionState = "executing";
2175
+ });
2176
+ this.currentlyExecutingProgramRunnerId = programRunnerRef.id;
2177
+ } catch (error) {
2178
+ if (error instanceof import_axios5.AxiosError && error.response && error.request) {
2179
+ this.logError(
2180
+ `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`
2181
+ );
2182
+ } else {
2183
+ this.logError(JSON.stringify(error));
2184
+ }
2185
+ (0, import_mobx3.runInAction)(() => {
2186
+ this.executionState = "idle";
2187
+ });
2188
+ }
2189
+ });
2190
+ }
2191
+ stopProgram() {
2192
+ return __async(this, null, function* () {
2193
+ if (!this.currentlyExecutingProgramRunnerId) return;
2194
+ (0, import_mobx3.runInAction)(() => {
2195
+ this.executionState = "stopping";
2196
+ });
2197
+ try {
2198
+ yield this.nova.api.program.stopProgramRunner(
2199
+ this.currentlyExecutingProgramRunnerId
2200
+ );
2201
+ } catch (err) {
2202
+ (0, import_mobx3.runInAction)(() => {
2203
+ this.executionState = "executing";
2204
+ });
2205
+ throw err;
2206
+ }
2207
+ });
2208
+ }
2209
+ reset() {
2210
+ this.currentProgram = {};
2211
+ }
2212
+ log(message) {
2213
+ console.log(message);
2214
+ this.logs.push({
2215
+ timestamp: Date.now(),
2216
+ message
2217
+ });
2218
+ }
2219
+ logError(message) {
2220
+ console.log(message);
2221
+ this.logs.push({
2222
+ timestamp: Date.now(),
2223
+ message,
2224
+ level: "error"
2225
+ });
2226
+ }
2227
+ };
2228
+ // Annotate the CommonJS export names for ESM import in node:
2229
+ 0 && (module.exports = {
2230
+ ConnectedMotionGroup,
2231
+ JoggerConnection,
2232
+ MotionStreamConnection,
2233
+ NovaCellAPIClient,
2234
+ NovaClient,
2235
+ ProgramState,
2236
+ ProgramStateConnection,
2237
+ ...require("@wandelbots/nova-api/v2")
2238
+ });
2239
+ //# sourceMappingURL=index.cjs.map