@wandelbots/nova-js 3.1.0 → 3.2.0-pr.ci-simplify-build.137.87eeb8d

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 (79) hide show
  1. package/dist/AutoReconnectingWebsocket-BI1ckzP8.d.ts +71 -0
  2. package/dist/AutoReconnectingWebsocket-BI1ckzP8.d.ts.map +1 -0
  3. package/dist/AutoReconnectingWebsocket-Cr7f9016.d.cts +71 -0
  4. package/dist/AutoReconnectingWebsocket-Cr7f9016.d.cts.map +1 -0
  5. package/dist/LoginWithAuth0-0g0wWRUC.js +217 -0
  6. package/dist/LoginWithAuth0-0g0wWRUC.js.map +1 -0
  7. package/dist/LoginWithAuth0-C82OCyDy.cjs +264 -0
  8. package/dist/LoginWithAuth0-C82OCyDy.cjs.map +1 -0
  9. package/dist/converters-DP2EIVv6.cjs +108 -0
  10. package/dist/converters-DP2EIVv6.cjs.map +1 -0
  11. package/dist/converters-DY6Lf7mb.js +66 -0
  12. package/dist/converters-DY6Lf7mb.js.map +1 -0
  13. package/dist/index.cjs +41 -386
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +70 -0
  16. package/dist/index.d.cts.map +1 -0
  17. package/dist/index.d.ts +69 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +28 -52
  20. package/dist/index.js.map +1 -1
  21. package/dist/lib/v1/index.cjs +2146 -2917
  22. package/dist/lib/v1/index.cjs.map +1 -1
  23. package/dist/lib/v1/index.d.cts +397 -0
  24. package/dist/lib/v1/index.d.cts.map +1 -0
  25. package/dist/lib/v1/index.d.ts +395 -7
  26. package/dist/lib/v1/index.d.ts.map +1 -1
  27. package/dist/lib/v1/index.js +2127 -2623
  28. package/dist/lib/v1/index.js.map +1 -1
  29. package/dist/lib/v2/index.cjs +1356 -1472
  30. package/dist/lib/v2/index.cjs.map +1 -1
  31. package/dist/lib/v2/index.d.cts +115 -0
  32. package/dist/lib/v2/index.d.cts.map +1 -0
  33. package/dist/lib/v2/index.d.ts +113 -2
  34. package/dist/lib/v2/index.d.ts.map +1 -1
  35. package/dist/lib/v2/index.js +1346 -1189
  36. package/dist/lib/v2/index.js.map +1 -1
  37. package/package.json +14 -16
  38. package/src/LoginWithAuth0.ts +9 -9
  39. package/src/lib/v1/NovaCellAPIClient.ts +4 -2
  40. package/src/lib/v2/NovaCellAPIClient.ts +4 -2
  41. package/src/lib/v2/mock/MockNovaInstance.ts +9 -13
  42. package/dist/LoginWithAuth0.d.ts +0 -7
  43. package/dist/LoginWithAuth0.d.ts.map +0 -1
  44. package/dist/chunk-B2C22PTK.js +0 -53
  45. package/dist/chunk-B2C22PTK.js.map +0 -1
  46. package/dist/chunk-I3PUV6ZD.js +0 -286
  47. package/dist/chunk-I3PUV6ZD.js.map +0 -1
  48. package/dist/lib/AutoReconnectingWebsocket.d.ts +0 -43
  49. package/dist/lib/AutoReconnectingWebsocket.d.ts.map +0 -1
  50. package/dist/lib/availableStorage.d.ts +0 -15
  51. package/dist/lib/availableStorage.d.ts.map +0 -1
  52. package/dist/lib/converters.d.ts +0 -26
  53. package/dist/lib/converters.d.ts.map +0 -1
  54. package/dist/lib/errorHandling.d.ts +0 -15
  55. package/dist/lib/errorHandling.d.ts.map +0 -1
  56. package/dist/lib/v1/ConnectedMotionGroup.d.ts +0 -77
  57. package/dist/lib/v1/ConnectedMotionGroup.d.ts.map +0 -1
  58. package/dist/lib/v1/JoggerConnection.d.ts +0 -94
  59. package/dist/lib/v1/JoggerConnection.d.ts.map +0 -1
  60. package/dist/lib/v1/MotionStreamConnection.d.ts +0 -26
  61. package/dist/lib/v1/MotionStreamConnection.d.ts.map +0 -1
  62. package/dist/lib/v1/NovaCellAPIClient.d.ts +0 -68
  63. package/dist/lib/v1/NovaCellAPIClient.d.ts.map +0 -1
  64. package/dist/lib/v1/NovaClient.d.ts +0 -67
  65. package/dist/lib/v1/NovaClient.d.ts.map +0 -1
  66. package/dist/lib/v1/ProgramStateConnection.d.ts +0 -57
  67. package/dist/lib/v1/ProgramStateConnection.d.ts.map +0 -1
  68. package/dist/lib/v1/getLatestTrajectories.d.ts +0 -4
  69. package/dist/lib/v1/getLatestTrajectories.d.ts.map +0 -1
  70. package/dist/lib/v1/mock/MockNovaInstance.d.ts +0 -13
  71. package/dist/lib/v1/mock/MockNovaInstance.d.ts.map +0 -1
  72. package/dist/lib/v1/motionStateUpdate.d.ts +0 -4
  73. package/dist/lib/v1/motionStateUpdate.d.ts.map +0 -1
  74. package/dist/lib/v2/NovaCellAPIClient.d.ts +0 -62
  75. package/dist/lib/v2/NovaCellAPIClient.d.ts.map +0 -1
  76. package/dist/lib/v2/NovaClient.d.ts +0 -60
  77. package/dist/lib/v2/NovaClient.d.ts.map +0 -1
  78. package/dist/lib/v2/mock/MockNovaInstance.d.ts +0 -13
  79. package/dist/lib/v2/mock/MockNovaInstance.d.ts.map +0 -1
@@ -1,2946 +1,2175 @@
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/v1/index.ts
69
- var v1_exports = {};
70
- __export(v1_exports, {
71
- ConnectedMotionGroup: () => ConnectedMotionGroup,
72
- JoggerConnection: () => JoggerConnection,
73
- MotionStreamConnection: () => MotionStreamConnection,
74
- NovaCellAPIClient: () => NovaCellAPIClient,
75
- NovaClient: () => NovaClient,
76
- ProgramState: () => ProgramState,
77
- ProgramStateConnection: () => ProgramStateConnection,
78
- getLatestTrajectories: () => getLatestTrajectories
79
- });
80
- module.exports = __toCommonJS(v1_exports);
81
- __reExport(v1_exports, require("@wandelbots/nova-api/v1"), module.exports);
1
+ const require_LoginWithAuth0 = require('../../LoginWithAuth0-C82OCyDy.cjs');
2
+ const require_converters = require('../../converters-DP2EIVv6.cjs');
3
+ let axios = require("axios");
4
+ axios = require_LoginWithAuth0.__toESM(axios);
5
+ let __wandelbots_nova_api_v1 = require("@wandelbots/nova-api/v1");
6
+ __wandelbots_nova_api_v1 = require_LoginWithAuth0.__toESM(__wandelbots_nova_api_v1);
7
+ let mobx = require("mobx");
8
+ mobx = require_LoginWithAuth0.__toESM(mobx);
9
+ let three = require("three");
10
+ three = require_LoginWithAuth0.__toESM(three);
11
+ let three_src_math_Vector3_js = require("three/src/math/Vector3.js");
12
+ three_src_math_Vector3_js = require_LoginWithAuth0.__toESM(three_src_math_Vector3_js);
13
+ let url_join = require("url-join");
14
+ url_join = require_LoginWithAuth0.__toESM(url_join);
15
+ let path_to_regexp = require("path-to-regexp");
16
+ path_to_regexp = require_LoginWithAuth0.__toESM(path_to_regexp);
82
17
 
83
- // src/lib/v1/ConnectedMotionGroup.ts
84
- var import_mobx = require("mobx");
85
- var THREE = __toESM(require("three"), 1);
86
-
87
- // src/lib/converters.ts
88
- function tryParseJson(json) {
89
- try {
90
- return JSON.parse(json);
91
- } catch (e) {
92
- return void 0;
93
- }
94
- }
95
- function isSameCoordinateSystem(firstCoordSystem, secondCoordSystem) {
96
- if (!firstCoordSystem) firstCoordSystem = "world";
97
- if (!secondCoordSystem) secondCoordSystem = "world";
98
- return firstCoordSystem === secondCoordSystem;
99
- }
100
-
101
- // src/lib/v1/motionStateUpdate.ts
18
+ //#region src/lib/v1/motionStateUpdate.ts
102
19
  function jointValuesEqual(oldJointValues, newJointValues, changeDeltaThreshold) {
103
- if (newJointValues.length !== oldJointValues.length) {
104
- return true;
105
- }
106
- for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {
107
- if (
108
- // biome-ignore lint/style/noNonNullAssertion: legacy code
109
- Math.abs(newJointValues[jointIndex] - oldJointValues[jointIndex]) > changeDeltaThreshold
110
- ) {
111
- return false;
112
- }
113
- }
114
- return true;
20
+ if (newJointValues.length !== oldJointValues.length) return true;
21
+ for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) if (Math.abs(newJointValues[jointIndex] - oldJointValues[jointIndex]) > changeDeltaThreshold) return false;
22
+ return true;
115
23
  }
116
24
  function tcpPoseEqual(oldTcp, newTcp, changeDeltaThreshold) {
117
- if (oldTcp === void 0 && newTcp || oldTcp && newTcp === void 0) {
118
- return false;
119
- }
120
- if (oldTcp === void 0 || newTcp === void 0) {
121
- return true;
122
- }
123
- let changedDelta = 0;
124
- changedDelta += Math.abs(oldTcp.orientation.x - newTcp.orientation.x);
125
- changedDelta += Math.abs(oldTcp.orientation.y - newTcp.orientation.y);
126
- changedDelta += Math.abs(oldTcp.orientation.z - newTcp.orientation.z);
127
- changedDelta += Math.abs(oldTcp.position.x - newTcp.position.x);
128
- changedDelta += Math.abs(oldTcp.position.y - newTcp.position.y);
129
- changedDelta += Math.abs(oldTcp.position.z - newTcp.position.z);
130
- if (changedDelta > changeDeltaThreshold) {
131
- return false;
132
- }
133
- return oldTcp.coordinate_system === newTcp.coordinate_system && oldTcp.tcp === newTcp.tcp;
25
+ if (oldTcp === void 0 && newTcp || oldTcp && newTcp === void 0) return false;
26
+ if (oldTcp === void 0 || newTcp === void 0) return true;
27
+ let changedDelta = 0;
28
+ changedDelta += Math.abs(oldTcp.orientation.x - newTcp.orientation.x);
29
+ changedDelta += Math.abs(oldTcp.orientation.y - newTcp.orientation.y);
30
+ changedDelta += Math.abs(oldTcp.orientation.z - newTcp.orientation.z);
31
+ changedDelta += Math.abs(oldTcp.position.x - newTcp.position.x);
32
+ changedDelta += Math.abs(oldTcp.position.y - newTcp.position.y);
33
+ changedDelta += Math.abs(oldTcp.position.z - newTcp.position.z);
34
+ if (changedDelta > changeDeltaThreshold) return false;
35
+ return oldTcp.coordinate_system === newTcp.coordinate_system && oldTcp.tcp === newTcp.tcp;
134
36
  }
135
37
 
136
- // src/lib/v1/ConnectedMotionGroup.ts
137
- var MOTION_DELTA_THRESHOLD = 1e-4;
138
- var ConnectedMotionGroup = class _ConnectedMotionGroup {
139
- constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup, mounting, initialControllerState, controllerStateSocket) {
140
- this.nova = nova;
141
- this.controller = controller;
142
- this.motionGroup = motionGroup;
143
- this.initialMotionState = initialMotionState;
144
- this.motionStateSocket = motionStateSocket;
145
- this.isVirtual = isVirtual;
146
- this.tcps = tcps;
147
- this.motionGroupSpecification = motionGroupSpecification;
148
- this.safetySetup = safetySetup;
149
- this.mounting = mounting;
150
- this.initialControllerState = initialControllerState;
151
- this.controllerStateSocket = controllerStateSocket;
152
- this.connectedJoggingCartesianSocket = null;
153
- this.connectedJoggingJointsSocket = null;
154
- // tmp
155
- this.joggingVelocity = 10;
156
- /**
157
- * Reflects activation state of the motion group / robot servos. The
158
- * movement controls in the UI should only be enabled in the "active" state
159
- */
160
- this.activationState = "inactive";
161
- this.rapidlyChangingMotionState = initialMotionState;
162
- this.controllerState = initialControllerState;
163
- controllerStateSocket.addEventListener("message", (event) => {
164
- var _a;
165
- const data = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result;
166
- if (!data) {
167
- return;
168
- }
169
- (0, import_mobx.runInAction)(() => {
170
- this.controllerState = data;
171
- });
172
- });
173
- motionStateSocket.addEventListener("message", (event) => {
174
- var _a;
175
- const motionStateResponse = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result;
176
- if (!motionStateResponse) {
177
- throw new Error(
178
- `Failed to get motion state for ${this.motionGroupId}: ${event.data}`
179
- );
180
- }
181
- if (!jointValuesEqual(
182
- this.rapidlyChangingMotionState.state.joint_position.joints,
183
- motionStateResponse.state.joint_position.joints,
184
- MOTION_DELTA_THRESHOLD
185
- )) {
186
- (0, import_mobx.runInAction)(() => {
187
- this.rapidlyChangingMotionState.state = motionStateResponse.state;
188
- });
189
- }
190
- if (!tcpPoseEqual(
191
- this.rapidlyChangingMotionState.tcp_pose,
192
- motionStateResponse.tcp_pose,
193
- MOTION_DELTA_THRESHOLD
194
- )) {
195
- (0, import_mobx.runInAction)(() => {
196
- this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
197
- });
198
- }
199
- });
200
- (0, import_mobx.makeAutoObservable)(this);
201
- }
202
- static connect(nova, motionGroupId, controllers) {
203
- return __async(this, null, function* () {
204
- var _a, _b;
205
- const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
206
- const controller = controllers.find((c) => c.controller === controllerId);
207
- const motionGroup = controller == null ? void 0 : controller.physical_motion_groups.find(
208
- (mg) => mg.motion_group === motionGroupId
209
- );
210
- if (!controller || !motionGroup) {
211
- throw new Error(
212
- `Controller ${controllerId} or motion group ${motionGroupId} not found`
213
- );
214
- }
215
- const motionStateSocket = nova.openReconnectingWebsocket(
216
- `/motion-groups/${motionGroupId}/state-stream`
217
- );
218
- const firstMessage = yield motionStateSocket.firstMessage();
219
- const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result;
220
- if (!initialMotionState) {
221
- throw new Error(
222
- `Unable to parse initial motion state message ${firstMessage.data}`
223
- );
224
- }
225
- console.log(
226
- `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:
227
- `,
228
- initialMotionState
229
- );
230
- const config = yield nova.api.controller.getRobotController(
231
- controller.controller
232
- );
233
- const isVirtual = config.configuration.kind === "VirtualController";
234
- const mounting = yield (() => __async(null, null, function* () {
235
- try {
236
- const mounting2 = yield nova.api.motionGroupInfos.getMounting(
237
- motionGroup.motion_group
238
- );
239
- return mounting2;
240
- } catch (err) {
241
- console.error(
242
- `Error fetching mounting for ${motionGroup.motion_group}`,
243
- err
244
- );
245
- return null;
246
- }
247
- }))();
248
- const controllerStateSocket = nova.openReconnectingWebsocket(
249
- `/controllers/${controller.controller}/state-stream?response_rate=1000`
250
- );
251
- const firstControllerMessage = yield controllerStateSocket.firstMessage();
252
- const initialControllerState = (_b = tryParseJson(firstControllerMessage.data)) == null ? void 0 : _b.result;
253
- if (!initialControllerState) {
254
- throw new Error(
255
- `Unable to parse initial controller state message ${firstControllerMessage.data}`
256
- );
257
- }
258
- console.log(
259
- `Connected controller state websocket to controller ${controller.controller}. Initial state:
260
- `,
261
- initialControllerState
262
- );
263
- const { tcps } = yield nova.api.motionGroupInfos.listTcps(motionGroupId);
264
- const motionGroupSpecification = yield nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId);
265
- const safetySetup = yield nova.api.motionGroupInfos.getSafetySetup(motionGroupId);
266
- return new _ConnectedMotionGroup(
267
- nova,
268
- controller,
269
- motionGroup,
270
- initialMotionState,
271
- motionStateSocket,
272
- isVirtual,
273
- // biome-ignore lint/style/noNonNullAssertion: legacy code
274
- tcps,
275
- motionGroupSpecification,
276
- safetySetup,
277
- mounting,
278
- initialControllerState,
279
- controllerStateSocket
280
- );
281
- });
282
- }
283
- get motionGroupId() {
284
- return this.motionGroup.motion_group;
285
- }
286
- get controllerId() {
287
- return this.controller.controller;
288
- }
289
- get modelFromController() {
290
- return this.motionGroup.model_from_controller;
291
- }
292
- get wandelscriptIdentifier() {
293
- const num = this.motionGroupId.split("@")[0];
294
- return `${this.controllerId.replaceAll("-", "_")}_${num}`;
295
- }
296
- /** Jogging velocity in radians for rotation and joint movement */
297
- get joggingVelocityRads() {
298
- return this.joggingVelocity * Math.PI / 180;
299
- }
300
- get joints() {
301
- return this.initialMotionState.state.joint_position.joints.map((_, i) => {
302
- return {
303
- index: i
304
- };
305
- });
306
- }
307
- get dhParameters() {
308
- return this.motionGroupSpecification.dh_parameters;
309
- }
310
- get safetyZones() {
311
- return this.safetySetup.safety_zones;
312
- }
313
- /** Gets the robot mounting position offset in 3D viz coordinates */
314
- get mountingPosition() {
315
- if (!this.mounting) {
316
- return [0, 0, 0];
317
- }
318
- return [
319
- this.mounting.pose.position.x / 1e3,
320
- this.mounting.pose.position.y / 1e3,
321
- this.mounting.pose.position.z / 1e3
322
- ];
323
- }
324
- /** Gets the robot mounting position rotation in 3D viz coordinates */
325
- get mountingQuaternion() {
326
- var _a, _b, _c, _d, _e, _f;
327
- const rotationVector = new THREE.Vector3(
328
- ((_b = (_a = this.mounting) == null ? void 0 : _a.pose.orientation) == null ? void 0 : _b.x) || 0,
329
- ((_d = (_c = this.mounting) == null ? void 0 : _c.pose.orientation) == null ? void 0 : _d.y) || 0,
330
- ((_f = (_e = this.mounting) == null ? void 0 : _e.pose.orientation) == null ? void 0 : _f.z) || 0
331
- );
332
- const magnitude = rotationVector.length();
333
- const axis = rotationVector.normalize();
334
- return new THREE.Quaternion().setFromAxisAngle(axis, magnitude);
335
- }
336
- /**
337
- * Whether the controller is currently in a safety state
338
- * corresponding to an emergency stop
339
- */
340
- get isEstopActive() {
341
- const estopStates = [
342
- "SAFETY_STATE_ROBOT_EMERGENCY_STOP",
343
- "SAFETY_STATE_DEVICE_EMERGENCY_STOP"
344
- ];
345
- return estopStates.includes(this.controllerState.safety_state);
346
- }
347
- /**
348
- * Whether the controller is in a safety state
349
- * that may be non-functional for robot pad purposes
350
- */
351
- get isMoveableSafetyState() {
352
- const goodSafetyStates = [
353
- "SAFETY_STATE_NORMAL",
354
- "SAFETY_STATE_REDUCED"
355
- ];
356
- return goodSafetyStates.includes(this.controllerState.safety_state);
357
- }
358
- /**
359
- * Whether the controller is in an operation mode that allows movement
360
- */
361
- get isMoveableOperationMode() {
362
- const goodOperationModes = [
363
- "OPERATION_MODE_AUTO",
364
- "OPERATION_MODE_MANUAL",
365
- "OPERATION_MODE_MANUAL_T1",
366
- "OPERATION_MODE_MANUAL_T2"
367
- ];
368
- return goodOperationModes.includes(this.controllerState.operation_mode);
369
- }
370
- /**
371
- * Whether the robot is currently active and can be moved, based on the
372
- * safety state, operation mode and servo toggle activation state.
373
- */
374
- get canBeMoved() {
375
- return this.isMoveableSafetyState && this.isMoveableOperationMode && this.activationState === "active";
376
- }
377
- deactivate() {
378
- return __async(this, null, function* () {
379
- if (this.activationState !== "active") {
380
- console.error("Tried to deactivate while already deactivating");
381
- return;
382
- }
383
- (0, import_mobx.runInAction)(() => {
384
- this.activationState = "deactivating";
385
- });
386
- try {
387
- yield this.nova.api.controller.setDefaultMode(
388
- this.controllerId,
389
- "MODE_MONITOR"
390
- );
391
- (0, import_mobx.runInAction)(() => {
392
- this.activationState = "inactive";
393
- });
394
- } catch (err) {
395
- (0, import_mobx.runInAction)(() => {
396
- this.activationState = "active";
397
- });
398
- throw err;
399
- }
400
- });
401
- }
402
- activate() {
403
- return __async(this, null, function* () {
404
- if (this.activationState !== "inactive") {
405
- console.error("Tried to activate while already activating");
406
- return;
407
- }
408
- (0, import_mobx.runInAction)(() => {
409
- this.activationState = "activating";
410
- });
411
- try {
412
- yield this.nova.api.controller.setDefaultMode(
413
- this.controllerId,
414
- "MODE_CONTROL"
415
- );
416
- (0, import_mobx.runInAction)(() => {
417
- this.activationState = "active";
418
- });
419
- } catch (err) {
420
- (0, import_mobx.runInAction)(() => {
421
- this.activationState = "inactive";
422
- });
423
- throw err;
424
- }
425
- });
426
- }
427
- toggleActivation() {
428
- if (this.activationState === "inactive") {
429
- this.activate();
430
- } else if (this.activationState === "active") {
431
- this.deactivate();
432
- }
433
- }
434
- dispose() {
435
- this.motionStateSocket.close();
436
- if (this.connectedJoggingCartesianSocket)
437
- this.connectedJoggingCartesianSocket.close();
438
- if (this.connectedJoggingJointsSocket)
439
- this.connectedJoggingJointsSocket.close();
440
- }
441
- setJoggingVelocity(velocity) {
442
- this.joggingVelocity = velocity;
443
- }
38
+ //#endregion
39
+ //#region src/lib/v1/ConnectedMotionGroup.ts
40
+ const MOTION_DELTA_THRESHOLD$1 = 1e-4;
41
+ /**
42
+ * Store representing the current state of a connected motion group.
43
+ */
44
+ var ConnectedMotionGroup = class ConnectedMotionGroup {
45
+ static async connect(nova, motionGroupId, controllers) {
46
+ const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
47
+ const controller = controllers.find((c) => c.controller === controllerId);
48
+ const motionGroup = controller?.physical_motion_groups.find((mg) => mg.motion_group === motionGroupId);
49
+ if (!controller || !motionGroup) throw new Error(`Controller ${controllerId} or motion group ${motionGroupId} not found`);
50
+ const motionStateSocket = nova.openReconnectingWebsocket(`/motion-groups/${motionGroupId}/state-stream`);
51
+ const firstMessage = await motionStateSocket.firstMessage();
52
+ const initialMotionState = require_converters.tryParseJson(firstMessage.data)?.result;
53
+ if (!initialMotionState) throw new Error(`Unable to parse initial motion state message ${firstMessage.data}`);
54
+ console.log(`Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\n `, initialMotionState);
55
+ const isVirtual = (await nova.api.controller.getRobotController(controller.controller)).configuration.kind === "VirtualController";
56
+ const mounting = await (async () => {
57
+ try {
58
+ return await nova.api.motionGroupInfos.getMounting(motionGroup.motion_group);
59
+ } catch (err) {
60
+ console.error(`Error fetching mounting for ${motionGroup.motion_group}`, err);
61
+ return null;
62
+ }
63
+ })();
64
+ const controllerStateSocket = nova.openReconnectingWebsocket(`/controllers/${controller.controller}/state-stream?response_rate=1000`);
65
+ const firstControllerMessage = await controllerStateSocket.firstMessage();
66
+ const initialControllerState = require_converters.tryParseJson(firstControllerMessage.data)?.result;
67
+ if (!initialControllerState) throw new Error(`Unable to parse initial controller state message ${firstControllerMessage.data}`);
68
+ console.log(`Connected controller state websocket to controller ${controller.controller}. Initial state:\n `, initialControllerState);
69
+ const { tcps } = await nova.api.motionGroupInfos.listTcps(motionGroupId);
70
+ const motionGroupSpecification = await nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId);
71
+ const safetySetup = await nova.api.motionGroupInfos.getSafetySetup(motionGroupId);
72
+ return new ConnectedMotionGroup(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup, mounting, initialControllerState, controllerStateSocket);
73
+ }
74
+ constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup, mounting, initialControllerState, controllerStateSocket) {
75
+ this.nova = nova;
76
+ this.controller = controller;
77
+ this.motionGroup = motionGroup;
78
+ this.initialMotionState = initialMotionState;
79
+ this.motionStateSocket = motionStateSocket;
80
+ this.isVirtual = isVirtual;
81
+ this.tcps = tcps;
82
+ this.motionGroupSpecification = motionGroupSpecification;
83
+ this.safetySetup = safetySetup;
84
+ this.mounting = mounting;
85
+ this.initialControllerState = initialControllerState;
86
+ this.controllerStateSocket = controllerStateSocket;
87
+ this.connectedJoggingCartesianSocket = null;
88
+ this.connectedJoggingJointsSocket = null;
89
+ this.joggingVelocity = 10;
90
+ this.activationState = "inactive";
91
+ this.rapidlyChangingMotionState = initialMotionState;
92
+ this.controllerState = initialControllerState;
93
+ controllerStateSocket.addEventListener("message", (event) => {
94
+ const data = require_converters.tryParseJson(event.data)?.result;
95
+ if (!data) return;
96
+ (0, mobx.runInAction)(() => {
97
+ this.controllerState = data;
98
+ });
99
+ });
100
+ motionStateSocket.addEventListener("message", (event) => {
101
+ const motionStateResponse = require_converters.tryParseJson(event.data)?.result;
102
+ if (!motionStateResponse) throw new Error(`Failed to get motion state for ${this.motionGroupId}: ${event.data}`);
103
+ if (!jointValuesEqual(this.rapidlyChangingMotionState.state.joint_position.joints, motionStateResponse.state.joint_position.joints, MOTION_DELTA_THRESHOLD$1)) (0, mobx.runInAction)(() => {
104
+ this.rapidlyChangingMotionState.state = motionStateResponse.state;
105
+ });
106
+ if (!tcpPoseEqual(this.rapidlyChangingMotionState.tcp_pose, motionStateResponse.tcp_pose, MOTION_DELTA_THRESHOLD$1)) (0, mobx.runInAction)(() => {
107
+ this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
108
+ });
109
+ });
110
+ (0, mobx.makeAutoObservable)(this);
111
+ }
112
+ get motionGroupId() {
113
+ return this.motionGroup.motion_group;
114
+ }
115
+ get controllerId() {
116
+ return this.controller.controller;
117
+ }
118
+ get modelFromController() {
119
+ return this.motionGroup.model_from_controller;
120
+ }
121
+ get wandelscriptIdentifier() {
122
+ const num = this.motionGroupId.split("@")[0];
123
+ return `${this.controllerId.replaceAll("-", "_")}_${num}`;
124
+ }
125
+ /** Jogging velocity in radians for rotation and joint movement */
126
+ get joggingVelocityRads() {
127
+ return this.joggingVelocity * Math.PI / 180;
128
+ }
129
+ get joints() {
130
+ return this.initialMotionState.state.joint_position.joints.map((_, i) => {
131
+ return { index: i };
132
+ });
133
+ }
134
+ get dhParameters() {
135
+ return this.motionGroupSpecification.dh_parameters;
136
+ }
137
+ get safetyZones() {
138
+ return this.safetySetup.safety_zones;
139
+ }
140
+ /** Gets the robot mounting position offset in 3D viz coordinates */
141
+ get mountingPosition() {
142
+ if (!this.mounting) return [
143
+ 0,
144
+ 0,
145
+ 0
146
+ ];
147
+ return [
148
+ this.mounting.pose.position.x / 1e3,
149
+ this.mounting.pose.position.y / 1e3,
150
+ this.mounting.pose.position.z / 1e3
151
+ ];
152
+ }
153
+ /** Gets the robot mounting position rotation in 3D viz coordinates */
154
+ get mountingQuaternion() {
155
+ const rotationVector = new three.Vector3(this.mounting?.pose.orientation?.x || 0, this.mounting?.pose.orientation?.y || 0, this.mounting?.pose.orientation?.z || 0);
156
+ const magnitude = rotationVector.length();
157
+ const axis = rotationVector.normalize();
158
+ return new three.Quaternion().setFromAxisAngle(axis, magnitude);
159
+ }
160
+ /**
161
+ * Whether the controller is currently in a safety state
162
+ * corresponding to an emergency stop
163
+ */
164
+ get isEstopActive() {
165
+ return ["SAFETY_STATE_ROBOT_EMERGENCY_STOP", "SAFETY_STATE_DEVICE_EMERGENCY_STOP"].includes(this.controllerState.safety_state);
166
+ }
167
+ /**
168
+ * Whether the controller is in a safety state
169
+ * that may be non-functional for robot pad purposes
170
+ */
171
+ get isMoveableSafetyState() {
172
+ return ["SAFETY_STATE_NORMAL", "SAFETY_STATE_REDUCED"].includes(this.controllerState.safety_state);
173
+ }
174
+ /**
175
+ * Whether the controller is in an operation mode that allows movement
176
+ */
177
+ get isMoveableOperationMode() {
178
+ return [
179
+ "OPERATION_MODE_AUTO",
180
+ "OPERATION_MODE_MANUAL",
181
+ "OPERATION_MODE_MANUAL_T1",
182
+ "OPERATION_MODE_MANUAL_T2"
183
+ ].includes(this.controllerState.operation_mode);
184
+ }
185
+ /**
186
+ * Whether the robot is currently active and can be moved, based on the
187
+ * safety state, operation mode and servo toggle activation state.
188
+ */
189
+ get canBeMoved() {
190
+ return this.isMoveableSafetyState && this.isMoveableOperationMode && this.activationState === "active";
191
+ }
192
+ async deactivate() {
193
+ if (this.activationState !== "active") {
194
+ console.error("Tried to deactivate while already deactivating");
195
+ return;
196
+ }
197
+ (0, mobx.runInAction)(() => {
198
+ this.activationState = "deactivating";
199
+ });
200
+ try {
201
+ await this.nova.api.controller.setDefaultMode(this.controllerId, "MODE_MONITOR");
202
+ (0, mobx.runInAction)(() => {
203
+ this.activationState = "inactive";
204
+ });
205
+ } catch (err) {
206
+ (0, mobx.runInAction)(() => {
207
+ this.activationState = "active";
208
+ });
209
+ throw err;
210
+ }
211
+ }
212
+ async activate() {
213
+ if (this.activationState !== "inactive") {
214
+ console.error("Tried to activate while already activating");
215
+ return;
216
+ }
217
+ (0, mobx.runInAction)(() => {
218
+ this.activationState = "activating";
219
+ });
220
+ try {
221
+ await this.nova.api.controller.setDefaultMode(this.controllerId, "MODE_CONTROL");
222
+ (0, mobx.runInAction)(() => {
223
+ this.activationState = "active";
224
+ });
225
+ } catch (err) {
226
+ (0, mobx.runInAction)(() => {
227
+ this.activationState = "inactive";
228
+ });
229
+ throw err;
230
+ }
231
+ }
232
+ toggleActivation() {
233
+ if (this.activationState === "inactive") this.activate();
234
+ else if (this.activationState === "active") this.deactivate();
235
+ }
236
+ dispose() {
237
+ this.motionStateSocket.close();
238
+ if (this.connectedJoggingCartesianSocket) this.connectedJoggingCartesianSocket.close();
239
+ if (this.connectedJoggingJointsSocket) this.connectedJoggingJointsSocket.close();
240
+ }
241
+ setJoggingVelocity(velocity) {
242
+ this.joggingVelocity = velocity;
243
+ }
444
244
  };
445
245
 
446
- // src/lib/v1/getLatestTrajectories.ts
447
- var lastMotionIds = /* @__PURE__ */ new Set();
448
- function getLatestTrajectories(apiClient, sampleTime = 50, responsesCoordinateSystem) {
449
- return __async(this, null, function* () {
450
- const newTrajectories = [];
451
- try {
452
- const motions = yield apiClient.motion.listMotions();
453
- const currentMotionIds = new Set(motions.motions);
454
- const newMotionIds = Array.from(currentMotionIds).filter(
455
- (id) => !lastMotionIds.has(id)
456
- );
457
- for (const motionId of newMotionIds) {
458
- const trajectory = yield apiClient.motion.getMotionTrajectory(
459
- motionId,
460
- sampleTime,
461
- responsesCoordinateSystem
462
- );
463
- newTrajectories.push(trajectory);
464
- }
465
- lastMotionIds = currentMotionIds;
466
- } catch (error) {
467
- console.error("Failed to get latest trajectories:", error);
468
- }
469
- return newTrajectories;
470
- });
246
+ //#endregion
247
+ //#region src/lib/v1/getLatestTrajectories.ts
248
+ let lastMotionIds = /* @__PURE__ */ new Set();
249
+ async function getLatestTrajectories(apiClient, sampleTime = 50, responsesCoordinateSystem) {
250
+ const newTrajectories = [];
251
+ try {
252
+ const motions = await apiClient.motion.listMotions();
253
+ const currentMotionIds = new Set(motions.motions);
254
+ const newMotionIds = Array.from(currentMotionIds).filter((id) => !lastMotionIds.has(id));
255
+ for (const motionId of newMotionIds) {
256
+ const trajectory = await apiClient.motion.getMotionTrajectory(motionId, sampleTime, responsesCoordinateSystem);
257
+ newTrajectories.push(trajectory);
258
+ }
259
+ lastMotionIds = currentMotionIds;
260
+ } catch (error) {
261
+ console.error("Failed to get latest trajectories:", error);
262
+ }
263
+ return newTrajectories;
471
264
  }
472
265
 
473
- // src/lib/v1/JoggerConnection.ts
474
- var import_Vector3 = require("three/src/math/Vector3.js");
475
- var JoggerConnection = class _JoggerConnection {
476
- constructor(motionStream, opts = {}) {
477
- this.motionStream = motionStream;
478
- this.opts = opts;
479
- // Currently a separate websocket is needed for each mode, pester API people
480
- // to merge these for simplicity
481
- this.cartesianWebsocket = null;
482
- this.jointWebsocket = null;
483
- this.cartesianJoggingOpts = {};
484
- }
485
- static open(_0, _1) {
486
- return __async(this, arguments, function* (nova, motionGroupId, opts = {}) {
487
- const motionStream = yield nova.connectMotionStream(motionGroupId);
488
- return new _JoggerConnection(motionStream, opts);
489
- });
490
- }
491
- get motionGroupId() {
492
- return this.motionStream.motionGroupId;
493
- }
494
- get nova() {
495
- return this.motionStream.nova;
496
- }
497
- get numJoints() {
498
- return this.motionStream.joints.length;
499
- }
500
- get activeJoggingMode() {
501
- if (this.cartesianWebsocket) return "cartesian";
502
- if (this.jointWebsocket) return "joint";
503
- return "increment";
504
- }
505
- get activeWebsocket() {
506
- return this.cartesianWebsocket || this.jointWebsocket;
507
- }
508
- stop() {
509
- return __async(this, null, function* () {
510
- if (this.cartesianWebsocket) {
511
- this.cartesianWebsocket.sendJson({
512
- motion_group: this.motionGroupId,
513
- position_direction: { x: 0, y: 0, z: 0 },
514
- rotation_direction: { x: 0, y: 0, z: 0 },
515
- position_velocity: 0,
516
- rotation_velocity: 0,
517
- tcp: this.cartesianJoggingOpts.tcpId,
518
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
519
- });
520
- }
521
- if (this.jointWebsocket) {
522
- this.jointWebsocket.sendJson({
523
- motion_group: this.motionGroupId,
524
- joint_velocities: new Array(this.numJoints).fill(0)
525
- });
526
- }
527
- });
528
- }
529
- dispose() {
530
- if (this.cartesianWebsocket) {
531
- this.cartesianWebsocket.dispose();
532
- }
533
- if (this.jointWebsocket) {
534
- this.jointWebsocket.dispose();
535
- }
536
- }
537
- setJoggingMode(mode, cartesianJoggingOpts) {
538
- console.log("Setting jogging mode to", mode);
539
- if (cartesianJoggingOpts) {
540
- if (JSON.stringify(this.cartesianJoggingOpts) !== JSON.stringify(cartesianJoggingOpts)) {
541
- if (this.cartesianWebsocket) {
542
- this.cartesianWebsocket.dispose();
543
- this.cartesianWebsocket = null;
544
- }
545
- }
546
- this.cartesianJoggingOpts = cartesianJoggingOpts;
547
- }
548
- if (mode !== "cartesian" && this.cartesianWebsocket) {
549
- this.cartesianWebsocket.dispose();
550
- this.cartesianWebsocket = null;
551
- }
552
- if (mode !== "joint" && this.jointWebsocket) {
553
- this.jointWebsocket.dispose();
554
- this.jointWebsocket = null;
555
- }
556
- if (mode === "cartesian" && !this.cartesianWebsocket) {
557
- this.cartesianWebsocket = this.nova.openReconnectingWebsocket(
558
- `/motion-groups/move-tcp`
559
- );
560
- this.cartesianWebsocket.addEventListener(
561
- "message",
562
- (ev) => {
563
- const data = tryParseJson(ev.data);
564
- if (data && "error" in data) {
565
- if (this.opts.onError) {
566
- this.opts.onError(ev.data);
567
- } else {
568
- throw new Error(ev.data);
569
- }
570
- }
571
- }
572
- );
573
- }
574
- if (mode === "joint" && !this.jointWebsocket) {
575
- this.jointWebsocket = this.nova.openReconnectingWebsocket(
576
- `/motion-groups/move-joint`
577
- );
578
- this.jointWebsocket.addEventListener("message", (ev) => {
579
- const data = tryParseJson(ev.data);
580
- if (data && "error" in data) {
581
- if (this.opts.onError) {
582
- this.opts.onError(ev.data);
583
- } else {
584
- throw new Error(ev.data);
585
- }
586
- }
587
- });
588
- }
589
- }
590
- /**
591
- * Start rotation of a single robot joint at the specified velocity
592
- */
593
- startJointRotation(_0) {
594
- return __async(this, arguments, function* ({
595
- joint,
596
- direction,
597
- velocityRadsPerSec
598
- }) {
599
- if (!this.jointWebsocket) {
600
- throw new Error(
601
- "Joint jogging websocket not connected; call setJoggingMode first"
602
- );
603
- }
604
- const jointVelocities = new Array(this.numJoints).fill(0);
605
- jointVelocities[joint] = direction === "-" ? -velocityRadsPerSec : velocityRadsPerSec;
606
- this.jointWebsocket.sendJson({
607
- motion_group: this.motionGroupId,
608
- joint_velocities: jointVelocities
609
- });
610
- });
611
- }
612
- /**
613
- * Start the TCP moving along a specified axis at a given velocity
614
- */
615
- startTCPTranslation(_0) {
616
- return __async(this, arguments, function* ({
617
- axis,
618
- direction,
619
- velocityMmPerSec
620
- }) {
621
- if (!this.cartesianWebsocket) {
622
- throw new Error(
623
- "Cartesian jogging websocket not connected; call setJoggingMode first"
624
- );
625
- }
626
- const zeroVector = { x: 0, y: 0, z: 0 };
627
- const joggingVector = Object.assign({}, zeroVector);
628
- joggingVector[axis] = direction === "-" ? -1 : 1;
629
- this.cartesianWebsocket.sendJson({
630
- motion_group: this.motionGroupId,
631
- position_direction: joggingVector,
632
- rotation_direction: zeroVector,
633
- position_velocity: velocityMmPerSec,
634
- rotation_velocity: 0,
635
- tcp: this.cartesianJoggingOpts.tcpId,
636
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
637
- });
638
- });
639
- }
640
- /**
641
- * Start the TCP rotating around a specified axis at a given velocity
642
- */
643
- startTCPRotation(_0) {
644
- return __async(this, arguments, function* ({
645
- axis,
646
- direction,
647
- velocityRadsPerSec
648
- }) {
649
- if (!this.cartesianWebsocket) {
650
- throw new Error(
651
- "Cartesian jogging websocket not connected; call setJoggingMode first"
652
- );
653
- }
654
- const zeroVector = { x: 0, y: 0, z: 0 };
655
- const joggingVector = Object.assign({}, zeroVector);
656
- joggingVector[axis] = direction === "-" ? -1 : 1;
657
- this.cartesianWebsocket.sendJson({
658
- motion_group: this.motionGroupId,
659
- position_direction: zeroVector,
660
- rotation_direction: joggingVector,
661
- position_velocity: 0,
662
- rotation_velocity: velocityRadsPerSec,
663
- tcp: this.cartesianJoggingOpts.tcpId,
664
- coordinate_system: this.cartesianJoggingOpts.coordSystemId
665
- });
666
- });
667
- }
668
- /**
669
- * Move the robot by a fixed distance in a single cartesian
670
- * axis, either rotating or translating relative to the TCP.
671
- * Promise resolves only after the motion has completed.
672
- */
673
- runIncrementalCartesianMotion(_0) {
674
- return __async(this, arguments, function* ({
675
- currentTcpPose,
676
- currentJoints,
677
- coordSystemId,
678
- velocityInRelevantUnits,
679
- axis,
680
- direction,
681
- motion
682
- }) {
683
- var _a;
684
- const commands = [];
685
- if (!isSameCoordinateSystem(currentTcpPose.coordinate_system, coordSystemId)) {
686
- throw new Error(
687
- `Current TCP pose coordinate system ${currentTcpPose.coordinate_system} does not match target coordinate system ${coordSystemId}`
688
- );
689
- }
690
- if (motion.type === "translate") {
691
- const targetTcpPosition = Object.assign({}, currentTcpPose.position);
692
- targetTcpPosition[axis] += motion.distanceMm * (direction === "-" ? -1 : 1);
693
- commands.push({
694
- settings: {
695
- limits_override: {
696
- tcp_velocity_limit: velocityInRelevantUnits
697
- }
698
- },
699
- line: {
700
- position: targetTcpPosition,
701
- orientation: currentTcpPose.orientation,
702
- coordinate_system: coordSystemId
703
- }
704
- });
705
- } else if (motion.type === "rotate") {
706
- const currentRotationVector = new import_Vector3.Vector3(
707
- currentTcpPose.orientation.x,
708
- currentTcpPose.orientation.y,
709
- currentTcpPose.orientation.z
710
- );
711
- const currentRotationRad = currentRotationVector.length();
712
- const currentRotationDirection = currentRotationVector.clone().normalize();
713
- const differenceRotationRad = motion.distanceRads * (direction === "-" ? -1 : 1);
714
- const differenceRotationDirection = new import_Vector3.Vector3(0, 0, 0);
715
- differenceRotationDirection[axis] = 1;
716
- const f1 = Math.cos(0.5 * differenceRotationRad) * Math.cos(0.5 * currentRotationRad);
717
- const f2 = Math.sin(0.5 * differenceRotationRad) * Math.sin(0.5 * currentRotationRad);
718
- const f3 = Math.sin(0.5 * differenceRotationRad) * Math.cos(0.5 * currentRotationRad);
719
- const f4 = Math.cos(0.5 * differenceRotationRad) * Math.sin(0.5 * currentRotationRad);
720
- const dotProduct = differenceRotationDirection.dot(
721
- currentRotationDirection
722
- );
723
- const crossProduct = differenceRotationDirection.clone().cross(currentRotationDirection);
724
- const newRotationRad = 2 * Math.acos(f1 - f2 * dotProduct);
725
- const f5 = newRotationRad / Math.sin(0.5 * newRotationRad);
726
- const targetTcpOrientation = new import_Vector3.Vector3().addScaledVector(crossProduct, f2).addScaledVector(differenceRotationDirection, f3).addScaledVector(currentRotationDirection, f4).multiplyScalar(f5);
727
- commands.push({
728
- settings: {
729
- limits_override: {
730
- tcp_orientation_velocity_limit: velocityInRelevantUnits
731
- }
732
- },
733
- line: {
734
- position: currentTcpPose.position,
735
- orientation: targetTcpOrientation,
736
- coordinate_system: coordSystemId
737
- }
738
- });
739
- }
740
- const motionPlanRes = yield this.nova.api.motion.planMotion({
741
- motion_group: this.motionGroupId,
742
- start_joint_position: currentJoints,
743
- tcp: this.cartesianJoggingOpts.tcpId,
744
- commands
745
- });
746
- const plannedMotion = (_a = motionPlanRes.plan_successful_response) == null ? void 0 : _a.motion;
747
- if (!plannedMotion) {
748
- throw new Error(
749
- `Failed to plan jogging increment motion ${JSON.stringify(motionPlanRes)}`
750
- );
751
- }
752
- yield this.nova.api.motion.streamMoveForward(
753
- plannedMotion,
754
- 100,
755
- void 0,
756
- void 0,
757
- void 0,
758
- {
759
- // Might take a while at low velocity
760
- timeout: 1e3 * 60
761
- }
762
- );
763
- });
764
- }
765
- /**
766
- * Rotate a single robot joint by a fixed number of radians
767
- * Promise resolves only after the motion has completed.
768
- */
769
- runIncrementalJointRotation(_0) {
770
- return __async(this, arguments, function* ({
771
- joint,
772
- currentJoints,
773
- velocityRadsPerSec,
774
- direction,
775
- distanceRads
776
- }) {
777
- var _a;
778
- const targetJoints = [...currentJoints.joints];
779
- targetJoints[joint] += distanceRads * (direction === "-" ? -1 : 1);
780
- const jointVelocityLimits = new Array(
781
- currentJoints.joints.length
782
- ).fill(velocityRadsPerSec);
783
- const motionPlanRes = yield this.nova.api.motion.planMotion({
784
- motion_group: this.motionGroupId,
785
- start_joint_position: currentJoints,
786
- commands: [
787
- {
788
- settings: {
789
- limits_override: {
790
- joint_velocity_limits: {
791
- joints: jointVelocityLimits
792
- }
793
- }
794
- },
795
- joint_ptp: {
796
- joints: targetJoints
797
- }
798
- }
799
- ]
800
- });
801
- const plannedMotion = (_a = motionPlanRes.plan_successful_response) == null ? void 0 : _a.motion;
802
- if (!plannedMotion) {
803
- console.error("Failed to plan jogging increment motion", motionPlanRes);
804
- return;
805
- }
806
- yield this.nova.api.motion.streamMoveForward(
807
- plannedMotion,
808
- 100,
809
- void 0,
810
- void 0,
811
- void 0,
812
- {
813
- // Might take a while at low velocity
814
- timeout: 1e3 * 60
815
- }
816
- );
817
- });
818
- }
266
+ //#endregion
267
+ //#region src/lib/v1/JoggerConnection.ts
268
+ var JoggerConnection = class JoggerConnection {
269
+ static async open(nova, motionGroupId, opts = {}) {
270
+ const motionStream = await nova.connectMotionStream(motionGroupId);
271
+ return new JoggerConnection(motionStream, opts);
272
+ }
273
+ constructor(motionStream, opts = {}) {
274
+ this.motionStream = motionStream;
275
+ this.opts = opts;
276
+ this.cartesianWebsocket = null;
277
+ this.jointWebsocket = null;
278
+ this.cartesianJoggingOpts = {};
279
+ }
280
+ get motionGroupId() {
281
+ return this.motionStream.motionGroupId;
282
+ }
283
+ get nova() {
284
+ return this.motionStream.nova;
285
+ }
286
+ get numJoints() {
287
+ return this.motionStream.joints.length;
288
+ }
289
+ get activeJoggingMode() {
290
+ if (this.cartesianWebsocket) return "cartesian";
291
+ if (this.jointWebsocket) return "joint";
292
+ return "increment";
293
+ }
294
+ get activeWebsocket() {
295
+ return this.cartesianWebsocket || this.jointWebsocket;
296
+ }
297
+ async stop() {
298
+ if (this.cartesianWebsocket) this.cartesianWebsocket.sendJson({
299
+ motion_group: this.motionGroupId,
300
+ position_direction: {
301
+ x: 0,
302
+ y: 0,
303
+ z: 0
304
+ },
305
+ rotation_direction: {
306
+ x: 0,
307
+ y: 0,
308
+ z: 0
309
+ },
310
+ position_velocity: 0,
311
+ rotation_velocity: 0,
312
+ tcp: this.cartesianJoggingOpts.tcpId,
313
+ coordinate_system: this.cartesianJoggingOpts.coordSystemId
314
+ });
315
+ if (this.jointWebsocket) this.jointWebsocket.sendJson({
316
+ motion_group: this.motionGroupId,
317
+ joint_velocities: new Array(this.numJoints).fill(0)
318
+ });
319
+ }
320
+ dispose() {
321
+ if (this.cartesianWebsocket) this.cartesianWebsocket.dispose();
322
+ if (this.jointWebsocket) this.jointWebsocket.dispose();
323
+ }
324
+ setJoggingMode(mode, cartesianJoggingOpts) {
325
+ console.log("Setting jogging mode to", mode);
326
+ if (cartesianJoggingOpts) {
327
+ if (JSON.stringify(this.cartesianJoggingOpts) !== JSON.stringify(cartesianJoggingOpts)) {
328
+ if (this.cartesianWebsocket) {
329
+ this.cartesianWebsocket.dispose();
330
+ this.cartesianWebsocket = null;
331
+ }
332
+ }
333
+ this.cartesianJoggingOpts = cartesianJoggingOpts;
334
+ }
335
+ if (mode !== "cartesian" && this.cartesianWebsocket) {
336
+ this.cartesianWebsocket.dispose();
337
+ this.cartesianWebsocket = null;
338
+ }
339
+ if (mode !== "joint" && this.jointWebsocket) {
340
+ this.jointWebsocket.dispose();
341
+ this.jointWebsocket = null;
342
+ }
343
+ if (mode === "cartesian" && !this.cartesianWebsocket) {
344
+ this.cartesianWebsocket = this.nova.openReconnectingWebsocket(`/motion-groups/move-tcp`);
345
+ this.cartesianWebsocket.addEventListener("message", (ev) => {
346
+ const data = require_converters.tryParseJson(ev.data);
347
+ if (data && "error" in data) if (this.opts.onError) this.opts.onError(ev.data);
348
+ else throw new Error(ev.data);
349
+ });
350
+ }
351
+ if (mode === "joint" && !this.jointWebsocket) {
352
+ this.jointWebsocket = this.nova.openReconnectingWebsocket(`/motion-groups/move-joint`);
353
+ this.jointWebsocket.addEventListener("message", (ev) => {
354
+ const data = require_converters.tryParseJson(ev.data);
355
+ if (data && "error" in data) if (this.opts.onError) this.opts.onError(ev.data);
356
+ else throw new Error(ev.data);
357
+ });
358
+ }
359
+ }
360
+ /**
361
+ * Start rotation of a single robot joint at the specified velocity
362
+ */
363
+ async startJointRotation({ joint, direction, velocityRadsPerSec }) {
364
+ if (!this.jointWebsocket) throw new Error("Joint jogging websocket not connected; call setJoggingMode first");
365
+ const jointVelocities = new Array(this.numJoints).fill(0);
366
+ jointVelocities[joint] = direction === "-" ? -velocityRadsPerSec : velocityRadsPerSec;
367
+ this.jointWebsocket.sendJson({
368
+ motion_group: this.motionGroupId,
369
+ joint_velocities: jointVelocities
370
+ });
371
+ }
372
+ /**
373
+ * Start the TCP moving along a specified axis at a given velocity
374
+ */
375
+ async startTCPTranslation({ axis, direction, velocityMmPerSec }) {
376
+ if (!this.cartesianWebsocket) throw new Error("Cartesian jogging websocket not connected; call setJoggingMode first");
377
+ const zeroVector = {
378
+ x: 0,
379
+ y: 0,
380
+ z: 0
381
+ };
382
+ const joggingVector = Object.assign({}, zeroVector);
383
+ joggingVector[axis] = direction === "-" ? -1 : 1;
384
+ this.cartesianWebsocket.sendJson({
385
+ motion_group: this.motionGroupId,
386
+ position_direction: joggingVector,
387
+ rotation_direction: zeroVector,
388
+ position_velocity: velocityMmPerSec,
389
+ rotation_velocity: 0,
390
+ tcp: this.cartesianJoggingOpts.tcpId,
391
+ coordinate_system: this.cartesianJoggingOpts.coordSystemId
392
+ });
393
+ }
394
+ /**
395
+ * Start the TCP rotating around a specified axis at a given velocity
396
+ */
397
+ async startTCPRotation({ axis, direction, velocityRadsPerSec }) {
398
+ if (!this.cartesianWebsocket) throw new Error("Cartesian jogging websocket not connected; call setJoggingMode first");
399
+ const zeroVector = {
400
+ x: 0,
401
+ y: 0,
402
+ z: 0
403
+ };
404
+ const joggingVector = Object.assign({}, zeroVector);
405
+ joggingVector[axis] = direction === "-" ? -1 : 1;
406
+ this.cartesianWebsocket.sendJson({
407
+ motion_group: this.motionGroupId,
408
+ position_direction: zeroVector,
409
+ rotation_direction: joggingVector,
410
+ position_velocity: 0,
411
+ rotation_velocity: velocityRadsPerSec,
412
+ tcp: this.cartesianJoggingOpts.tcpId,
413
+ coordinate_system: this.cartesianJoggingOpts.coordSystemId
414
+ });
415
+ }
416
+ /**
417
+ * Move the robot by a fixed distance in a single cartesian
418
+ * axis, either rotating or translating relative to the TCP.
419
+ * Promise resolves only after the motion has completed.
420
+ */
421
+ async runIncrementalCartesianMotion({ currentTcpPose, currentJoints, coordSystemId, velocityInRelevantUnits, axis, direction, motion }) {
422
+ const commands = [];
423
+ if (!require_converters.isSameCoordinateSystem(currentTcpPose.coordinate_system, coordSystemId)) throw new Error(`Current TCP pose coordinate system ${currentTcpPose.coordinate_system} does not match target coordinate system ${coordSystemId}`);
424
+ if (motion.type === "translate") {
425
+ const targetTcpPosition = Object.assign({}, currentTcpPose.position);
426
+ targetTcpPosition[axis] += motion.distanceMm * (direction === "-" ? -1 : 1);
427
+ commands.push({
428
+ settings: { limits_override: { tcp_velocity_limit: velocityInRelevantUnits } },
429
+ line: {
430
+ position: targetTcpPosition,
431
+ orientation: currentTcpPose.orientation,
432
+ coordinate_system: coordSystemId
433
+ }
434
+ });
435
+ } else if (motion.type === "rotate") {
436
+ const currentRotationVector = new three_src_math_Vector3_js.Vector3(currentTcpPose.orientation.x, currentTcpPose.orientation.y, currentTcpPose.orientation.z);
437
+ const currentRotationRad = currentRotationVector.length();
438
+ const currentRotationDirection = currentRotationVector.clone().normalize();
439
+ const differenceRotationRad = motion.distanceRads * (direction === "-" ? -1 : 1);
440
+ const differenceRotationDirection = new three_src_math_Vector3_js.Vector3(0, 0, 0);
441
+ differenceRotationDirection[axis] = 1;
442
+ const f1 = Math.cos(.5 * differenceRotationRad) * Math.cos(.5 * currentRotationRad);
443
+ const f2 = Math.sin(.5 * differenceRotationRad) * Math.sin(.5 * currentRotationRad);
444
+ const f3 = Math.sin(.5 * differenceRotationRad) * Math.cos(.5 * currentRotationRad);
445
+ const f4 = Math.cos(.5 * differenceRotationRad) * Math.sin(.5 * currentRotationRad);
446
+ const dotProduct = differenceRotationDirection.dot(currentRotationDirection);
447
+ const crossProduct = differenceRotationDirection.clone().cross(currentRotationDirection);
448
+ const newRotationRad = 2 * Math.acos(f1 - f2 * dotProduct);
449
+ const f5 = newRotationRad / Math.sin(.5 * newRotationRad);
450
+ const targetTcpOrientation = new three_src_math_Vector3_js.Vector3().addScaledVector(crossProduct, f2).addScaledVector(differenceRotationDirection, f3).addScaledVector(currentRotationDirection, f4).multiplyScalar(f5);
451
+ commands.push({
452
+ settings: { limits_override: { tcp_orientation_velocity_limit: velocityInRelevantUnits } },
453
+ line: {
454
+ position: currentTcpPose.position,
455
+ orientation: targetTcpOrientation,
456
+ coordinate_system: coordSystemId
457
+ }
458
+ });
459
+ }
460
+ const motionPlanRes = await this.nova.api.motion.planMotion({
461
+ motion_group: this.motionGroupId,
462
+ start_joint_position: currentJoints,
463
+ tcp: this.cartesianJoggingOpts.tcpId,
464
+ commands
465
+ });
466
+ const plannedMotion = motionPlanRes.plan_successful_response?.motion;
467
+ if (!plannedMotion) throw new Error(`Failed to plan jogging increment motion ${JSON.stringify(motionPlanRes)}`);
468
+ await this.nova.api.motion.streamMoveForward(plannedMotion, 100, void 0, void 0, void 0, { timeout: 1e3 * 60 });
469
+ }
470
+ /**
471
+ * Rotate a single robot joint by a fixed number of radians
472
+ * Promise resolves only after the motion has completed.
473
+ */
474
+ async runIncrementalJointRotation({ joint, currentJoints, velocityRadsPerSec, direction, distanceRads }) {
475
+ const targetJoints = [...currentJoints.joints];
476
+ targetJoints[joint] += distanceRads * (direction === "-" ? -1 : 1);
477
+ const jointVelocityLimits = new Array(currentJoints.joints.length).fill(velocityRadsPerSec);
478
+ const motionPlanRes = await this.nova.api.motion.planMotion({
479
+ motion_group: this.motionGroupId,
480
+ start_joint_position: currentJoints,
481
+ commands: [{
482
+ settings: { limits_override: { joint_velocity_limits: { joints: jointVelocityLimits } } },
483
+ joint_ptp: { joints: targetJoints }
484
+ }]
485
+ });
486
+ const plannedMotion = motionPlanRes.plan_successful_response?.motion;
487
+ if (!plannedMotion) {
488
+ console.error("Failed to plan jogging increment motion", motionPlanRes);
489
+ return;
490
+ }
491
+ await this.nova.api.motion.streamMoveForward(plannedMotion, 100, void 0, void 0, void 0, { timeout: 1e3 * 60 });
492
+ }
819
493
  };
820
494
 
821
- // src/lib/v1/MotionStreamConnection.ts
822
- var import_mobx2 = require("mobx");
823
- var import_three = require("three");
824
- var MOTION_DELTA_THRESHOLD2 = 1e-4;
495
+ //#endregion
496
+ //#region src/lib/v1/MotionStreamConnection.ts
497
+ const MOTION_DELTA_THRESHOLD = 1e-4;
825
498
  function unwrapRotationVector(newRotationVectorApi, currentRotationVectorApi) {
826
- const currentRotationVector = new import_three.Vector3(
827
- currentRotationVectorApi.x,
828
- currentRotationVectorApi.y,
829
- currentRotationVectorApi.z
830
- );
831
- const newRotationVector = new import_three.Vector3(
832
- newRotationVectorApi.x,
833
- newRotationVectorApi.y,
834
- newRotationVectorApi.z
835
- );
836
- const currentAngle = currentRotationVector.length();
837
- const currentAxis = currentRotationVector.normalize();
838
- let newAngle = newRotationVector.length();
839
- let newAxis = newRotationVector.normalize();
840
- if (newAxis.dot(currentAxis) < 0) {
841
- newAngle = -newAngle;
842
- newAxis = newAxis.multiplyScalar(-1);
843
- }
844
- let angleDifference = newAngle - currentAngle;
845
- angleDifference -= 2 * Math.PI * Math.floor((angleDifference + Math.PI) / (2 * Math.PI));
846
- newAngle = currentAngle + angleDifference;
847
- return newAxis.multiplyScalar(newAngle);
499
+ const currentRotationVector = new three.Vector3(currentRotationVectorApi.x, currentRotationVectorApi.y, currentRotationVectorApi.z);
500
+ const newRotationVector = new three.Vector3(newRotationVectorApi.x, newRotationVectorApi.y, newRotationVectorApi.z);
501
+ const currentAngle = currentRotationVector.length();
502
+ const currentAxis = currentRotationVector.normalize();
503
+ let newAngle = newRotationVector.length();
504
+ let newAxis = newRotationVector.normalize();
505
+ if (newAxis.dot(currentAxis) < 0) {
506
+ newAngle = -newAngle;
507
+ newAxis = newAxis.multiplyScalar(-1);
508
+ }
509
+ let angleDifference = newAngle - currentAngle;
510
+ angleDifference -= 2 * Math.PI * Math.floor((angleDifference + Math.PI) / (2 * Math.PI));
511
+ newAngle = currentAngle + angleDifference;
512
+ return newAxis.multiplyScalar(newAngle);
848
513
  }
849
- var MotionStreamConnection = class _MotionStreamConnection {
850
- constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket) {
851
- this.nova = nova;
852
- this.controller = controller;
853
- this.motionGroup = motionGroup;
854
- this.initialMotionState = initialMotionState;
855
- this.motionStateSocket = motionStateSocket;
856
- this.rapidlyChangingMotionState = initialMotionState;
857
- motionStateSocket.addEventListener("message", (event) => {
858
- var _a;
859
- const motionStateResponse = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result;
860
- if (!motionStateResponse) {
861
- throw new Error(
862
- `Failed to get motion state for ${this.motionGroupId}: ${event.data}`
863
- );
864
- }
865
- if (!jointValuesEqual(
866
- this.rapidlyChangingMotionState.state.joint_position.joints,
867
- motionStateResponse.state.joint_position.joints,
868
- MOTION_DELTA_THRESHOLD2
869
- )) {
870
- (0, import_mobx2.runInAction)(() => {
871
- this.rapidlyChangingMotionState.state = motionStateResponse.state;
872
- });
873
- }
874
- if (!tcpPoseEqual(
875
- this.rapidlyChangingMotionState.tcp_pose,
876
- motionStateResponse.tcp_pose,
877
- MOTION_DELTA_THRESHOLD2
878
- )) {
879
- (0, import_mobx2.runInAction)(() => {
880
- if (this.rapidlyChangingMotionState.tcp_pose == null) {
881
- this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
882
- } else {
883
- this.rapidlyChangingMotionState.tcp_pose = {
884
- position: motionStateResponse.tcp_pose.position,
885
- orientation: unwrapRotationVector(
886
- motionStateResponse.tcp_pose.orientation,
887
- this.rapidlyChangingMotionState.tcp_pose.orientation
888
- ),
889
- tcp: motionStateResponse.tcp_pose.tcp,
890
- coordinate_system: motionStateResponse.tcp_pose.coordinate_system
891
- };
892
- }
893
- });
894
- }
895
- });
896
- (0, import_mobx2.makeAutoObservable)(this);
897
- }
898
- static open(nova, motionGroupId) {
899
- return __async(this, null, function* () {
900
- var _a;
901
- const { instances: controllers } = yield nova.api.controller.listControllers();
902
- const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
903
- const controller = controllers.find((c) => c.controller === controllerId);
904
- const motionGroup = controller == null ? void 0 : controller.physical_motion_groups.find(
905
- (mg) => mg.motion_group === motionGroupId
906
- );
907
- if (!controller || !motionGroup) {
908
- throw new Error(
909
- `Controller ${controllerId} or motion group ${motionGroupId} not found`
910
- );
911
- }
912
- const motionStateSocket = nova.openReconnectingWebsocket(
913
- `/motion-groups/${motionGroupId}/state-stream`
914
- );
915
- const firstMessage = yield motionStateSocket.firstMessage();
916
- console.log("got first message", firstMessage);
917
- const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result;
918
- if (!initialMotionState) {
919
- throw new Error(
920
- `Unable to parse initial motion state message ${firstMessage.data}`
921
- );
922
- }
923
- console.log(
924
- `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:
925
- `,
926
- initialMotionState
927
- );
928
- return new _MotionStreamConnection(
929
- nova,
930
- controller,
931
- motionGroup,
932
- initialMotionState,
933
- motionStateSocket
934
- );
935
- });
936
- }
937
- get motionGroupId() {
938
- return this.motionGroup.motion_group;
939
- }
940
- get controllerId() {
941
- return this.controller.controller;
942
- }
943
- get modelFromController() {
944
- return this.motionGroup.model_from_controller;
945
- }
946
- get wandelscriptIdentifier() {
947
- const num = this.motionGroupId.split("@")[0];
948
- return `${this.controllerId.replaceAll("-", "_")}_${num}`;
949
- }
950
- get joints() {
951
- return this.initialMotionState.state.joint_position.joints.map((_, i) => {
952
- return {
953
- index: i
954
- };
955
- });
956
- }
957
- dispose() {
958
- this.motionStateSocket.close();
959
- }
514
+ /**
515
+ * Store representing the current state of a connected motion group.
516
+ */
517
+ var MotionStreamConnection = class MotionStreamConnection {
518
+ static async open(nova, motionGroupId) {
519
+ const { instances: controllers } = await nova.api.controller.listControllers();
520
+ const [_motionGroupIndex, controllerId] = motionGroupId.split("@");
521
+ const controller = controllers.find((c) => c.controller === controllerId);
522
+ const motionGroup = controller?.physical_motion_groups.find((mg) => mg.motion_group === motionGroupId);
523
+ if (!controller || !motionGroup) throw new Error(`Controller ${controllerId} or motion group ${motionGroupId} not found`);
524
+ const motionStateSocket = nova.openReconnectingWebsocket(`/motion-groups/${motionGroupId}/state-stream`);
525
+ const firstMessage = await motionStateSocket.firstMessage();
526
+ console.log("got first message", firstMessage);
527
+ const initialMotionState = require_converters.tryParseJson(firstMessage.data)?.result;
528
+ if (!initialMotionState) throw new Error(`Unable to parse initial motion state message ${firstMessage.data}`);
529
+ console.log(`Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\n `, initialMotionState);
530
+ return new MotionStreamConnection(nova, controller, motionGroup, initialMotionState, motionStateSocket);
531
+ }
532
+ constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket) {
533
+ this.nova = nova;
534
+ this.controller = controller;
535
+ this.motionGroup = motionGroup;
536
+ this.initialMotionState = initialMotionState;
537
+ this.motionStateSocket = motionStateSocket;
538
+ this.rapidlyChangingMotionState = initialMotionState;
539
+ motionStateSocket.addEventListener("message", (event) => {
540
+ const motionStateResponse = require_converters.tryParseJson(event.data)?.result;
541
+ if (!motionStateResponse) throw new Error(`Failed to get motion state for ${this.motionGroupId}: ${event.data}`);
542
+ if (!jointValuesEqual(this.rapidlyChangingMotionState.state.joint_position.joints, motionStateResponse.state.joint_position.joints, MOTION_DELTA_THRESHOLD)) (0, mobx.runInAction)(() => {
543
+ this.rapidlyChangingMotionState.state = motionStateResponse.state;
544
+ });
545
+ if (!tcpPoseEqual(this.rapidlyChangingMotionState.tcp_pose, motionStateResponse.tcp_pose, MOTION_DELTA_THRESHOLD)) (0, mobx.runInAction)(() => {
546
+ if (this.rapidlyChangingMotionState.tcp_pose == null) this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose;
547
+ else this.rapidlyChangingMotionState.tcp_pose = {
548
+ position: motionStateResponse.tcp_pose.position,
549
+ orientation: unwrapRotationVector(motionStateResponse.tcp_pose.orientation, this.rapidlyChangingMotionState.tcp_pose.orientation),
550
+ tcp: motionStateResponse.tcp_pose.tcp,
551
+ coordinate_system: motionStateResponse.tcp_pose.coordinate_system
552
+ };
553
+ });
554
+ });
555
+ (0, mobx.makeAutoObservable)(this);
556
+ }
557
+ get motionGroupId() {
558
+ return this.motionGroup.motion_group;
559
+ }
560
+ get controllerId() {
561
+ return this.controller.controller;
562
+ }
563
+ get modelFromController() {
564
+ return this.motionGroup.model_from_controller;
565
+ }
566
+ get wandelscriptIdentifier() {
567
+ const num = this.motionGroupId.split("@")[0];
568
+ return `${this.controllerId.replaceAll("-", "_")}_${num}`;
569
+ }
570
+ get joints() {
571
+ return this.initialMotionState.state.joint_position.joints.map((_, i) => {
572
+ return { index: i };
573
+ });
574
+ }
575
+ dispose() {
576
+ this.motionStateSocket.close();
577
+ }
960
578
  };
961
579
 
962
- // src/lib/v1/NovaCellAPIClient.ts
963
- var import_v1 = require("@wandelbots/nova-api/v1");
964
- var import_axios = __toESM(require("axios"), 1);
580
+ //#endregion
581
+ //#region src/lib/v1/NovaCellAPIClient.ts
582
+ /**
583
+ * API client providing type-safe access to all the Nova API REST endpoints
584
+ * associated with a specific cell id.
585
+ */
965
586
  var NovaCellAPIClient = class {
966
- constructor(cellId, opts) {
967
- this.cellId = cellId;
968
- this.opts = opts;
969
- this.system = this.withUnwrappedResponsesOnly(import_v1.SystemApi);
970
- this.cell = this.withUnwrappedResponsesOnly(import_v1.CellApi);
971
- this.deviceConfig = this.withCellId(import_v1.DeviceConfigurationApi);
972
- this.motionGroup = this.withCellId(import_v1.MotionGroupApi);
973
- this.motionGroupInfos = this.withCellId(import_v1.MotionGroupInfosApi);
974
- this.controller = this.withCellId(import_v1.ControllerApi);
975
- this.program = this.withCellId(import_v1.ProgramApi);
976
- this.programValues = this.withCellId(import_v1.ProgramValuesApi);
977
- this.controllerIOs = this.withCellId(import_v1.ControllerIOsApi);
978
- this.motionGroupKinematic = this.withCellId(import_v1.MotionGroupKinematicApi);
979
- this.motion = this.withCellId(import_v1.MotionApi);
980
- this.coordinateSystems = this.withCellId(import_v1.CoordinateSystemsApi);
981
- this.application = this.withCellId(import_v1.ApplicationApi);
982
- this.applicationGlobal = this.withUnwrappedResponsesOnly(import_v1.ApplicationApi);
983
- this.motionGroupJogging = this.withCellId(import_v1.MotionGroupJoggingApi);
984
- this.virtualRobot = this.withCellId(import_v1.VirtualRobotApi);
985
- this.virtualRobotSetup = this.withCellId(import_v1.VirtualRobotSetupApi);
986
- this.virtualRobotMode = this.withCellId(import_v1.VirtualRobotModeApi);
987
- this.virtualRobotBehavior = this.withCellId(import_v1.VirtualRobotBehaviorApi);
988
- this.libraryProgramMetadata = this.withCellId(import_v1.LibraryProgramMetadataApi);
989
- this.libraryProgram = this.withCellId(import_v1.LibraryProgramApi);
990
- this.libraryRecipeMetadata = this.withCellId(import_v1.LibraryRecipeMetadataApi);
991
- this.libraryRecipe = this.withCellId(import_v1.LibraryRecipeApi);
992
- this.storeObject = this.withCellId(import_v1.StoreObjectApi);
993
- this.storeCollisionComponents = this.withCellId(
994
- import_v1.StoreCollisionComponentsApi
995
- );
996
- this.storeCollisionScenes = this.withCellId(import_v1.StoreCollisionScenesApi);
997
- }
998
- /**
999
- * Some TypeScript sorcery which alters the API class methods so you don't
1000
- * have to pass the cell id to every single one, and de-encapsulates the
1001
- * response data
1002
- */
1003
- withCellId(ApiConstructor) {
1004
- var _a, _b;
1005
- const apiClient = new ApiConstructor(
1006
- __spreadProps(__spreadValues({}, this.opts), {
1007
- isJsonMime: (mime) => {
1008
- return mime === "application/json";
1009
- }
1010
- }),
1011
- (_a = this.opts.basePath) != null ? _a : "",
1012
- (_b = this.opts.axiosInstance) != null ? _b : import_axios.default.create()
1013
- );
1014
- for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) {
1015
- if (key !== "constructor" && typeof apiClient[key] === "function") {
1016
- const originalFunction = apiClient[key];
1017
- apiClient[key] = (...args) => {
1018
- return originalFunction.apply(apiClient, [this.cellId, ...args]).then((res) => res.data);
1019
- };
1020
- }
1021
- }
1022
- return apiClient;
1023
- }
1024
- /**
1025
- * As withCellId, but only does the response unwrapping
1026
- */
1027
- withUnwrappedResponsesOnly(ApiConstructor) {
1028
- var _a, _b;
1029
- const apiClient = new ApiConstructor(
1030
- __spreadProps(__spreadValues({}, this.opts), {
1031
- isJsonMime: (mime) => {
1032
- return mime === "application/json";
1033
- }
1034
- }),
1035
- (_a = this.opts.basePath) != null ? _a : "",
1036
- (_b = this.opts.axiosInstance) != null ? _b : import_axios.default.create()
1037
- );
1038
- for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) {
1039
- if (key !== "constructor" && typeof apiClient[key] === "function") {
1040
- const originalFunction = apiClient[key];
1041
- apiClient[key] = (...args) => {
1042
- return originalFunction.apply(apiClient, args).then((res) => res.data);
1043
- };
1044
- }
1045
- }
1046
- return apiClient;
1047
- }
1048
- };
1049
-
1050
- // src/lib/v1/NovaClient.ts
1051
- var import_axios3 = __toESM(require("axios"), 1);
1052
- var import_url_join = __toESM(require("url-join"), 1);
1053
-
1054
- // src/LoginWithAuth0.ts
1055
- var DOMAIN_SUFFIX = "wandelbots.io";
1056
- var auth0ConfigMap = {
1057
- dev: {
1058
- domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,
1059
- clientId: "fLbJD0RLp5r2Dpucm5j8BjwMR6Hunfha"
1060
- },
1061
- stg: {
1062
- domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,
1063
- clientId: "joVDeD9e786WzFNSGCqoVq7HNkWt5j6s"
1064
- },
1065
- prod: {
1066
- domain: `https://auth.portal.${DOMAIN_SUFFIX}`,
1067
- clientId: "J7WJUi38xVQdJAEBNRT9Xw1b0fXDb4J2"
1068
- }
1069
- };
1070
- var getAuth0Config = (instanceUrl) => {
1071
- if (instanceUrl.includes(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev;
1072
- if (instanceUrl.includes(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg;
1073
- if (instanceUrl.includes(DOMAIN_SUFFIX)) return auth0ConfigMap.prod;
1074
- throw new Error(
1075
- "Unsupported instance URL. Cannot determine Auth0 configuration."
1076
- );
1077
- };
1078
- var loginWithAuth0 = (instanceUrl) => __async(null, null, function* () {
1079
- var _a;
1080
- if (typeof window === "undefined") {
1081
- throw new Error(
1082
- `Access token must be set to use NovaClient when not in a browser environment.`
1083
- );
1084
- }
1085
- const auth0Config = getAuth0Config(instanceUrl);
1086
- if (new URL(instanceUrl).origin === window.location.origin) {
1087
- window.location.reload();
1088
- throw new Error(
1089
- "Failed to reload page to get auth details, please refresh manually"
1090
- );
1091
- }
1092
- const { Auth0Client } = yield import("@auth0/auth0-spa-js");
1093
- const auth0Client = new Auth0Client({
1094
- domain: auth0Config.domain,
1095
- clientId: (_a = auth0Config.clientId) != null ? _a : "",
1096
- useRefreshTokens: false,
1097
- authorizationParams: {
1098
- audience: "nova-api",
1099
- redirect_uri: window.location.origin
1100
- }
1101
- });
1102
- if (window.location.search.includes("code=") && window.location.search.includes("state=")) {
1103
- const { appState } = yield auth0Client.handleRedirectCallback();
1104
- window.history.replaceState(
1105
- {},
1106
- document.title,
1107
- (appState == null ? void 0 : appState.returnTo) || window.location.pathname
1108
- );
1109
- } else {
1110
- yield auth0Client.loginWithRedirect();
1111
- }
1112
- const accessToken = yield auth0Client.getTokenSilently();
1113
- return accessToken;
1114
- });
1115
-
1116
- // src/lib/AutoReconnectingWebsocket.ts
1117
- var import_reconnecting_websocket = __toESM(require("reconnecting-websocket"), 1);
1118
- var AutoReconnectingWebsocket = class extends import_reconnecting_websocket.default {
1119
- constructor(targetUrl, opts = {}) {
1120
- console.log("Opening websocket to", targetUrl);
1121
- super(() => this.targetUrl || targetUrl, void 0, {
1122
- startClosed: true
1123
- });
1124
- this.opts = opts;
1125
- this.disposed = false;
1126
- Object.defineProperty(this, "url", {
1127
- get() {
1128
- return this.targetUrl;
1129
- }
1130
- });
1131
- this.targetUrl = targetUrl;
1132
- this.addEventListener("open", () => {
1133
- console.log(`Websocket to ${this.url} opened`);
1134
- });
1135
- this.addEventListener("message", (ev) => {
1136
- if (!this.receivedFirstMessage) {
1137
- this.receivedFirstMessage = ev;
1138
- }
1139
- });
1140
- this.addEventListener("close", () => {
1141
- console.log(`Websocket to ${this.url} closed`);
1142
- });
1143
- const origReconnect = this.reconnect;
1144
- this.reconnect = () => {
1145
- if (this.opts.mock) {
1146
- this.opts.mock.handleWebsocketConnection(this);
1147
- } else {
1148
- origReconnect.apply(this);
1149
- }
1150
- };
1151
- this.reconnect();
1152
- }
1153
- changeUrl(targetUrl) {
1154
- this.receivedFirstMessage = void 0;
1155
- this.targetUrl = targetUrl;
1156
- this.reconnect();
1157
- }
1158
- sendJson(data) {
1159
- if (this.opts.mock) {
1160
- this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data));
1161
- } else {
1162
- this.send(JSON.stringify(data));
1163
- }
1164
- }
1165
- /**
1166
- * Permanently close this websocket and indicate that
1167
- * this object should not be used again.
1168
- **/
1169
- dispose() {
1170
- this.close();
1171
- this.disposed = true;
1172
- if (this.opts.onDispose) {
1173
- this.opts.onDispose();
1174
- }
1175
- }
1176
- /**
1177
- * Returns a promise that resolves once the websocket
1178
- * is in the OPEN state. */
1179
- opened() {
1180
- return __async(this, null, function* () {
1181
- return new Promise((resolve, reject) => {
1182
- if (this.readyState === WebSocket.OPEN) {
1183
- resolve();
1184
- } else {
1185
- this.addEventListener("open", () => resolve());
1186
- this.addEventListener("error", reject);
1187
- }
1188
- });
1189
- });
1190
- }
1191
- /**
1192
- * Returns a promise that resolves once the websocket
1193
- * is in the CLOSED state. */
1194
- closed() {
1195
- return __async(this, null, function* () {
1196
- return new Promise((resolve, reject) => {
1197
- if (this.readyState === WebSocket.CLOSED) {
1198
- resolve();
1199
- } else {
1200
- this.addEventListener("close", () => resolve());
1201
- this.addEventListener("error", reject);
1202
- }
1203
- });
1204
- });
1205
- }
1206
- /**
1207
- * Returns a promise that resolves when the first message
1208
- * is received from the websocket. Resolves immediately if
1209
- * the first message has already been received.
1210
- */
1211
- firstMessage() {
1212
- return __async(this, null, function* () {
1213
- if (this.receivedFirstMessage) {
1214
- return this.receivedFirstMessage;
1215
- }
1216
- return new Promise((resolve, reject) => {
1217
- const onMessage = (ev) => {
1218
- this.receivedFirstMessage = ev;
1219
- this.removeEventListener("message", onMessage);
1220
- this.removeEventListener("error", onError);
1221
- resolve(ev);
1222
- };
1223
- const onError = (ev) => {
1224
- this.removeEventListener("message", onMessage);
1225
- this.removeEventListener("error", onError);
1226
- reject(ev);
1227
- };
1228
- this.addEventListener("message", onMessage);
1229
- this.addEventListener("error", onError);
1230
- });
1231
- });
1232
- }
1233
- /**
1234
- * Returns a promise that resolves when the next message
1235
- * is received from the websocket.
1236
- */
1237
- nextMessage() {
1238
- return __async(this, null, function* () {
1239
- return new Promise((resolve, reject) => {
1240
- const onMessage = (ev) => {
1241
- this.removeEventListener("message", onMessage);
1242
- this.removeEventListener("error", onError);
1243
- resolve(ev);
1244
- };
1245
- const onError = (ev) => {
1246
- this.removeEventListener("message", onMessage);
1247
- this.removeEventListener("error", onError);
1248
- reject(ev);
1249
- };
1250
- this.addEventListener("message", onMessage);
1251
- this.addEventListener("error", onError);
1252
- });
1253
- });
1254
- }
587
+ constructor(cellId, opts) {
588
+ this.cellId = cellId;
589
+ this.opts = opts;
590
+ this.system = this.withUnwrappedResponsesOnly(__wandelbots_nova_api_v1.SystemApi);
591
+ this.cell = this.withUnwrappedResponsesOnly(__wandelbots_nova_api_v1.CellApi);
592
+ this.deviceConfig = this.withCellId(__wandelbots_nova_api_v1.DeviceConfigurationApi);
593
+ this.motionGroup = this.withCellId(__wandelbots_nova_api_v1.MotionGroupApi);
594
+ this.motionGroupInfos = this.withCellId(__wandelbots_nova_api_v1.MotionGroupInfosApi);
595
+ this.controller = this.withCellId(__wandelbots_nova_api_v1.ControllerApi);
596
+ this.program = this.withCellId(__wandelbots_nova_api_v1.ProgramApi);
597
+ this.programValues = this.withCellId(__wandelbots_nova_api_v1.ProgramValuesApi);
598
+ this.controllerIOs = this.withCellId(__wandelbots_nova_api_v1.ControllerIOsApi);
599
+ this.motionGroupKinematic = this.withCellId(__wandelbots_nova_api_v1.MotionGroupKinematicApi);
600
+ this.motion = this.withCellId(__wandelbots_nova_api_v1.MotionApi);
601
+ this.coordinateSystems = this.withCellId(__wandelbots_nova_api_v1.CoordinateSystemsApi);
602
+ this.application = this.withCellId(__wandelbots_nova_api_v1.ApplicationApi);
603
+ this.applicationGlobal = this.withUnwrappedResponsesOnly(__wandelbots_nova_api_v1.ApplicationApi);
604
+ this.motionGroupJogging = this.withCellId(__wandelbots_nova_api_v1.MotionGroupJoggingApi);
605
+ this.virtualRobot = this.withCellId(__wandelbots_nova_api_v1.VirtualRobotApi);
606
+ this.virtualRobotSetup = this.withCellId(__wandelbots_nova_api_v1.VirtualRobotSetupApi);
607
+ this.virtualRobotMode = this.withCellId(__wandelbots_nova_api_v1.VirtualRobotModeApi);
608
+ this.virtualRobotBehavior = this.withCellId(__wandelbots_nova_api_v1.VirtualRobotBehaviorApi);
609
+ this.libraryProgramMetadata = this.withCellId(__wandelbots_nova_api_v1.LibraryProgramMetadataApi);
610
+ this.libraryProgram = this.withCellId(__wandelbots_nova_api_v1.LibraryProgramApi);
611
+ this.libraryRecipeMetadata = this.withCellId(__wandelbots_nova_api_v1.LibraryRecipeMetadataApi);
612
+ this.libraryRecipe = this.withCellId(__wandelbots_nova_api_v1.LibraryRecipeApi);
613
+ this.storeObject = this.withCellId(__wandelbots_nova_api_v1.StoreObjectApi);
614
+ this.storeCollisionComponents = this.withCellId(__wandelbots_nova_api_v1.StoreCollisionComponentsApi);
615
+ this.storeCollisionScenes = this.withCellId(__wandelbots_nova_api_v1.StoreCollisionScenesApi);
616
+ }
617
+ /**
618
+ * Some TypeScript sorcery which alters the API class methods so you don't
619
+ * have to pass the cell id to every single one, and de-encapsulates the
620
+ * response data
621
+ */
622
+ withCellId(ApiConstructor) {
623
+ const apiClient = new ApiConstructor({
624
+ ...this.opts,
625
+ isJsonMime: (mime) => {
626
+ return mime === "application/json";
627
+ }
628
+ }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.default.create());
629
+ for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) if (key !== "constructor" && typeof apiClient[key] === "function") {
630
+ const originalFunction = apiClient[key];
631
+ apiClient[key] = (...args) => {
632
+ return originalFunction.apply(apiClient, [this.cellId, ...args]).then((res) => res.data);
633
+ };
634
+ }
635
+ return apiClient;
636
+ }
637
+ /**
638
+ * As withCellId, but only does the response unwrapping
639
+ */
640
+ withUnwrappedResponsesOnly(ApiConstructor) {
641
+ const apiClient = new ApiConstructor({
642
+ ...this.opts,
643
+ isJsonMime: (mime) => {
644
+ return mime === "application/json";
645
+ }
646
+ }, this.opts.basePath ?? "", this.opts.axiosInstance ?? axios.default.create());
647
+ for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) if (key !== "constructor" && typeof apiClient[key] === "function") {
648
+ const originalFunction = apiClient[key];
649
+ apiClient[key] = (...args) => {
650
+ return originalFunction.apply(apiClient, args).then((res) => res.data);
651
+ };
652
+ }
653
+ return apiClient;
654
+ }
1255
655
  };
1256
656
 
1257
- // src/lib/availableStorage.ts
1258
- var AvailableStorage = class {
1259
- constructor() {
1260
- this.available = typeof window !== "undefined" && !!window.localStorage;
1261
- }
1262
- getJSON(key) {
1263
- if (!this.available) return null;
1264
- const result = window.localStorage.getItem(key);
1265
- if (result === null) return null;
1266
- try {
1267
- return JSON.parse(result);
1268
- } catch (err) {
1269
- return null;
1270
- }
1271
- }
1272
- setJSON(key, obj) {
1273
- if (!this.available) return null;
1274
- window.localStorage.setItem(key, JSON.stringify(obj));
1275
- }
1276
- delete(key) {
1277
- if (!this.available) return null;
1278
- window.localStorage.removeItem(key);
1279
- }
1280
- setString(key, value) {
1281
- if (!this.available) return null;
1282
- window.localStorage.setItem(key, value);
1283
- }
1284
- getString(key) {
1285
- if (!this.available) return null;
1286
- return window.localStorage.getItem(key);
1287
- }
1288
- };
1289
- var availableStorage = new AvailableStorage();
1290
-
1291
- // src/lib/v1/mock/MockNovaInstance.ts
1292
- var import_axios2 = require("axios");
1293
- var pathToRegexp = __toESM(require("path-to-regexp"), 1);
657
+ //#endregion
658
+ //#region src/lib/v1/mock/MockNovaInstance.ts
659
+ /**
660
+ * EXPERIMENTAL
661
+ * Ultra-simplified mock Nova server for testing stuff
662
+ */
1294
663
  var MockNovaInstance = class {
1295
- constructor() {
1296
- this.connections = [];
1297
- }
1298
- handleAPIRequest(config) {
1299
- return __async(this, null, function* () {
1300
- var _a, _b, _c;
1301
- const apiHandlers = [
1302
- {
1303
- method: "GET",
1304
- path: "/cells/:cellId/controllers",
1305
- handle() {
1306
- return {
1307
- instances: [
1308
- {
1309
- controller: "mock-ur5e",
1310
- model_name: "UniversalRobots::Controller",
1311
- host: "mock-ur5e",
1312
- allow_software_install_on_controller: true,
1313
- physical_motion_groups: [
1314
- {
1315
- motion_group: "0@mock-ur5e",
1316
- name_from_controller: "UR5e",
1317
- active: false,
1318
- model_from_controller: "UniversalRobots_UR5e"
1319
- }
1320
- ],
1321
- has_error: false,
1322
- error_details: ""
1323
- }
1324
- ]
1325
- };
1326
- }
1327
- },
1328
- {
1329
- method: "GET",
1330
- path: "/cells/:cellId/controllers/:controllerId",
1331
- handle() {
1332
- return {
1333
- configuration: {
1334
- kind: "VirtualController",
1335
- manufacturer: "universalrobots",
1336
- position: "[0,-1.571,-1.571,-1.571,1.571,-1.571,0]",
1337
- type: "universalrobots-ur5e"
1338
- },
1339
- name: "mock-ur5"
1340
- };
1341
- }
1342
- },
1343
- {
1344
- method: "GET",
1345
- path: "/cells/:cellId/motion-groups/:motionGroupId/specification",
1346
- handle() {
1347
- return {
1348
- dh_parameters: [
1349
- {
1350
- alpha: 1.5707963267948966,
1351
- theta: 0,
1352
- a: 0,
1353
- d: 162.25,
1354
- reverse_rotation_direction: false
1355
- },
1356
- {
1357
- alpha: 0,
1358
- theta: 0,
1359
- a: -425,
1360
- d: 0,
1361
- reverse_rotation_direction: false
1362
- },
1363
- {
1364
- alpha: 0,
1365
- theta: 0,
1366
- a: -392.2,
1367
- d: 0,
1368
- reverse_rotation_direction: false
1369
- },
1370
- {
1371
- alpha: 1.5707963267948966,
1372
- theta: 0,
1373
- a: 0,
1374
- d: 133.3,
1375
- reverse_rotation_direction: false
1376
- },
1377
- {
1378
- alpha: -1.5707963267948966,
1379
- theta: 0,
1380
- a: 0,
1381
- d: 99.7,
1382
- reverse_rotation_direction: false
1383
- },
1384
- {
1385
- alpha: 0,
1386
- theta: 0,
1387
- a: 0,
1388
- d: 99.6,
1389
- reverse_rotation_direction: false
1390
- }
1391
- ],
1392
- mechanical_joint_limits: [
1393
- {
1394
- joint: "JOINTNAME_AXIS_1",
1395
- lower_limit: -6.335545063018799,
1396
- upper_limit: 6.335545063018799,
1397
- unlimited: false
1398
- },
1399
- {
1400
- joint: "JOINTNAME_AXIS_2",
1401
- lower_limit: -6.335545063018799,
1402
- upper_limit: 6.335545063018799,
1403
- unlimited: false
1404
- },
1405
- {
1406
- joint: "JOINTNAME_AXIS_3",
1407
- lower_limit: -6.335545063018799,
1408
- upper_limit: 6.335545063018799,
1409
- unlimited: false
1410
- },
1411
- {
1412
- joint: "JOINTNAME_AXIS_4",
1413
- lower_limit: -6.335545063018799,
1414
- upper_limit: 6.335545063018799,
1415
- unlimited: false
1416
- },
1417
- {
1418
- joint: "JOINTNAME_AXIS_5",
1419
- lower_limit: -6.335545063018799,
1420
- upper_limit: 6.335545063018799,
1421
- unlimited: false
1422
- },
1423
- {
1424
- joint: "JOINTNAME_AXIS_6",
1425
- lower_limit: -6.335545063018799,
1426
- upper_limit: 6.335545063018799,
1427
- unlimited: false
1428
- }
1429
- ]
1430
- };
1431
- }
1432
- },
1433
- {
1434
- method: "GET",
1435
- path: "/cells/:cellId/motion-groups/:motionGroupId/safety-setup",
1436
- handle() {
1437
- return {
1438
- safety_settings: [
1439
- {
1440
- safety_state: "SAFETY_NORMAL",
1441
- settings: {
1442
- joint_position_limits: [
1443
- {
1444
- joint: "JOINTNAME_AXIS_1",
1445
- lower_limit: -2.96705961227417,
1446
- upper_limit: 2.96705961227417,
1447
- unlimited: false
1448
- },
1449
- {
1450
- joint: "JOINTNAME_AXIS_2",
1451
- lower_limit: -1.7453292608261108,
1452
- upper_limit: 2.7925267219543457,
1453
- unlimited: false
1454
- },
1455
- {
1456
- joint: "JOINTNAME_AXIS_3",
1457
- lower_limit: -3.3161256313323975,
1458
- upper_limit: 0.40142571926116943,
1459
- unlimited: false
1460
- },
1461
- {
1462
- joint: "JOINTNAME_AXIS_4",
1463
- lower_limit: -3.4906585216522217,
1464
- upper_limit: 3.4906585216522217,
1465
- unlimited: false
1466
- },
1467
- {
1468
- joint: "JOINTNAME_AXIS_5",
1469
- lower_limit: -2.4434609413146973,
1470
- upper_limit: 2.4434609413146973,
1471
- unlimited: false
1472
- },
1473
- {
1474
- joint: "JOINTNAME_AXIS_6",
1475
- lower_limit: -4.71238899230957,
1476
- upper_limit: 4.71238899230957,
1477
- unlimited: false
1478
- }
1479
- ],
1480
- joint_velocity_limits: [
1481
- {
1482
- joint: "JOINTNAME_AXIS_1",
1483
- limit: 3.1415927410125732
1484
- },
1485
- {
1486
- joint: "JOINTNAME_AXIS_2",
1487
- limit: 3.1415927410125732
1488
- },
1489
- {
1490
- joint: "JOINTNAME_AXIS_3",
1491
- limit: 3.4906585216522217
1492
- },
1493
- {
1494
- joint: "JOINTNAME_AXIS_4",
1495
- limit: 6.108652591705322
1496
- },
1497
- {
1498
- joint: "JOINTNAME_AXIS_5",
1499
- limit: 6.108652591705322
1500
- },
1501
- {
1502
- joint: "JOINTNAME_AXIS_6",
1503
- limit: 6.981317043304443
1504
- }
1505
- ],
1506
- joint_acceleration_limits: [],
1507
- joint_torque_limits: [],
1508
- tcp_velocity_limit: 1800
1509
- }
1510
- }
1511
- ],
1512
- safety_zones: [
1513
- {
1514
- id: 1,
1515
- priority: 0,
1516
- geometry: {
1517
- compound: {
1518
- child_geometries: [
1519
- {
1520
- convex_hull: {
1521
- vertices: [
1522
- {
1523
- x: -800,
1524
- y: -1330,
1525
- z: -1820
1526
- },
1527
- {
1528
- x: 1650,
1529
- y: -1330,
1530
- z: -1820
1531
- },
1532
- {
1533
- x: 1650,
1534
- y: 1330,
1535
- z: -1820
1536
- },
1537
- {
1538
- x: -800,
1539
- y: 1330,
1540
- z: -1820
1541
- }
1542
- ]
1543
- },
1544
- init_pose: {
1545
- position: {
1546
- x: 0,
1547
- y: 0,
1548
- z: 0
1549
- },
1550
- orientation: {
1551
- x: 0,
1552
- y: 0,
1553
- z: 0,
1554
- w: 1
1555
- }
1556
- },
1557
- id: "box"
1558
- },
1559
- {
1560
- convex_hull: {
1561
- vertices: [
1562
- {
1563
- x: -800,
1564
- y: -1330,
1565
- z: -1820
1566
- },
1567
- {
1568
- x: 1650,
1569
- y: -1330,
1570
- z: -1820
1571
- },
1572
- {
1573
- x: 1650,
1574
- y: -1330,
1575
- z: 1500
1576
- },
1577
- {
1578
- x: -800,
1579
- y: -1330,
1580
- z: 1500
1581
- }
1582
- ]
1583
- },
1584
- init_pose: {
1585
- position: {
1586
- x: 0,
1587
- y: 0,
1588
- z: 0
1589
- },
1590
- orientation: {
1591
- x: 0,
1592
- y: 0,
1593
- z: 0,
1594
- w: 1
1595
- }
1596
- },
1597
- id: "box"
1598
- },
1599
- {
1600
- convex_hull: {
1601
- vertices: [
1602
- {
1603
- x: -800,
1604
- y: -1330,
1605
- z: -1820
1606
- },
1607
- {
1608
- x: -800,
1609
- y: 1330,
1610
- z: -1820
1611
- },
1612
- {
1613
- x: -800,
1614
- y: 1330,
1615
- z: 1500
1616
- },
1617
- {
1618
- x: -800,
1619
- y: -1330,
1620
- z: 1500
1621
- }
1622
- ]
1623
- },
1624
- init_pose: {
1625
- position: {
1626
- x: 0,
1627
- y: 0,
1628
- z: 0
1629
- },
1630
- orientation: {
1631
- x: 0,
1632
- y: 0,
1633
- z: 0,
1634
- w: 1
1635
- }
1636
- },
1637
- id: "box"
1638
- },
1639
- {
1640
- convex_hull: {
1641
- vertices: [
1642
- {
1643
- x: 1650,
1644
- y: 1330,
1645
- z: 1500
1646
- },
1647
- {
1648
- x: -800,
1649
- y: 1330,
1650
- z: 1500
1651
- },
1652
- {
1653
- x: -800,
1654
- y: -1330,
1655
- z: 1500
1656
- },
1657
- {
1658
- x: 1650,
1659
- y: -1330,
1660
- z: 1500
1661
- }
1662
- ]
1663
- },
1664
- init_pose: {
1665
- position: {
1666
- x: 0,
1667
- y: 0,
1668
- z: 0
1669
- },
1670
- orientation: {
1671
- x: 0,
1672
- y: 0,
1673
- z: 0,
1674
- w: 1
1675
- }
1676
- },
1677
- id: "box"
1678
- },
1679
- {
1680
- convex_hull: {
1681
- vertices: [
1682
- {
1683
- x: 1650,
1684
- y: 1330,
1685
- z: 1500
1686
- },
1687
- {
1688
- x: -800,
1689
- y: 1330,
1690
- z: 1500
1691
- },
1692
- {
1693
- x: -800,
1694
- y: 1330,
1695
- z: -1820
1696
- },
1697
- {
1698
- x: 1650,
1699
- y: 1330,
1700
- z: -1820
1701
- }
1702
- ]
1703
- },
1704
- init_pose: {
1705
- position: {
1706
- x: 0,
1707
- y: 0,
1708
- z: 0
1709
- },
1710
- orientation: {
1711
- x: 0,
1712
- y: 0,
1713
- z: 0,
1714
- w: 1
1715
- }
1716
- },
1717
- id: "box"
1718
- },
1719
- {
1720
- convex_hull: {
1721
- vertices: [
1722
- {
1723
- x: 1650,
1724
- y: 1330,
1725
- z: 1500
1726
- },
1727
- {
1728
- x: 1650,
1729
- y: -1330,
1730
- z: 1500
1731
- },
1732
- {
1733
- x: 1650,
1734
- y: -1330,
1735
- z: -1820
1736
- },
1737
- {
1738
- x: 1650,
1739
- y: 1330,
1740
- z: -1820
1741
- }
1742
- ]
1743
- },
1744
- init_pose: {
1745
- position: {
1746
- x: 0,
1747
- y: 0,
1748
- z: 0
1749
- },
1750
- orientation: {
1751
- x: 0,
1752
- y: 0,
1753
- z: 0,
1754
- w: 1
1755
- }
1756
- },
1757
- id: "box"
1758
- }
1759
- ]
1760
- },
1761
- init_pose: {
1762
- position: {
1763
- x: 0,
1764
- y: 0,
1765
- z: 0
1766
- },
1767
- orientation: {
1768
- x: 0,
1769
- y: 0,
1770
- z: 0,
1771
- w: 1
1772
- }
1773
- },
1774
- id: "Cell workzone"
1775
- },
1776
- motion_group_uid: 1
1777
- },
1778
- {
1779
- id: 2,
1780
- priority: 0,
1781
- geometry: {
1782
- convex_hull: {
1783
- vertices: [
1784
- {
1785
- x: 1650,
1786
- y: 1330,
1787
- z: -1850
1788
- },
1789
- {
1790
- x: 865,
1791
- y: 1330,
1792
- z: -1850
1793
- },
1794
- {
1795
- x: 865,
1796
- y: -720,
1797
- z: -1850
1798
- },
1799
- {
1800
- x: 1650,
1801
- y: -720,
1802
- z: -1850
1803
- },
1804
- {
1805
- x: 1650,
1806
- y: 1330,
1807
- z: -920
1808
- },
1809
- {
1810
- x: 865,
1811
- y: 1330,
1812
- z: -920
1813
- },
1814
- {
1815
- x: 865,
1816
- y: -720,
1817
- z: -920
1818
- },
1819
- {
1820
- x: 1650,
1821
- y: -720,
1822
- z: -920
1823
- }
1824
- ]
1825
- },
1826
- init_pose: {
1827
- position: {
1828
- x: 0,
1829
- y: 0,
1830
- z: 0
1831
- },
1832
- orientation: {
1833
- x: 0,
1834
- y: 0,
1835
- z: 0,
1836
- w: 1
1837
- }
1838
- },
1839
- id: "Transport"
1840
- },
1841
- motion_group_uid: 1
1842
- },
1843
- {
1844
- id: 3,
1845
- priority: 0,
1846
- geometry: {
1847
- convex_hull: {
1848
- vertices: [
1849
- {
1850
- x: 1650,
1851
- y: 1330,
1852
- z: -600
1853
- },
1854
- {
1855
- x: 865,
1856
- y: 1330,
1857
- z: -600
1858
- },
1859
- {
1860
- x: 865,
1861
- y: 430,
1862
- z: -600
1863
- },
1864
- {
1865
- x: 1650,
1866
- y: 430,
1867
- z: -600
1868
- },
1869
- {
1870
- x: 1650,
1871
- y: 1330,
1872
- z: -1250
1873
- },
1874
- {
1875
- x: 865,
1876
- y: 1330,
1877
- z: -1250
1878
- },
1879
- {
1880
- x: 865,
1881
- y: 430,
1882
- z: -1250
1883
- },
1884
- {
1885
- x: 1650,
1886
- y: 430,
1887
- z: -1250
1888
- }
1889
- ]
1890
- },
1891
- init_pose: {
1892
- position: {
1893
- x: 0,
1894
- y: 0,
1895
- z: 0
1896
- },
1897
- orientation: {
1898
- x: 0,
1899
- y: 0,
1900
- z: 0,
1901
- w: 1
1902
- }
1903
- },
1904
- id: "Tunel"
1905
- },
1906
- motion_group_uid: 1
1907
- },
1908
- {
1909
- id: 4,
1910
- priority: 0,
1911
- geometry: {
1912
- convex_hull: {
1913
- vertices: [
1914
- {
1915
- x: 1650,
1916
- y: -760,
1917
- z: -440
1918
- },
1919
- {
1920
- x: 900,
1921
- y: -760,
1922
- z: -440
1923
- },
1924
- {
1925
- x: 900,
1926
- y: -1330,
1927
- z: -440
1928
- },
1929
- {
1930
- x: 1650,
1931
- y: -1330,
1932
- z: -440
1933
- },
1934
- {
1935
- x: 1650,
1936
- y: -760,
1937
- z: -1800
1938
- },
1939
- {
1940
- x: 900,
1941
- y: -760,
1942
- z: -1800
1943
- },
1944
- {
1945
- x: 900,
1946
- y: -1330,
1947
- z: -1800
1948
- },
1949
- {
1950
- x: 1650,
1951
- y: -1330,
1952
- z: -1800
1953
- }
1954
- ]
1955
- },
1956
- init_pose: {
1957
- position: {
1958
- x: 0,
1959
- y: 0,
1960
- z: 0
1961
- },
1962
- orientation: {
1963
- x: 0,
1964
- y: 0,
1965
- z: 0,
1966
- w: 1
1967
- }
1968
- },
1969
- id: "Fanuc controller"
1970
- },
1971
- motion_group_uid: 1
1972
- },
1973
- {
1974
- id: 6,
1975
- priority: 0,
1976
- geometry: {
1977
- convex_hull: {
1978
- vertices: [
1979
- {
1980
- x: -200,
1981
- y: -200,
1982
- z: -1900
1983
- },
1984
- {
1985
- x: 200,
1986
- y: -200,
1987
- z: -1900
1988
- },
1989
- {
1990
- x: 200,
1991
- y: 200,
1992
- z: -1900
1993
- },
1994
- {
1995
- x: -200,
1996
- y: 200,
1997
- z: -1900
1998
- },
1999
- {
2000
- x: -200,
2001
- y: -200,
2002
- z: -350
2003
- },
2004
- {
2005
- x: 200,
2006
- y: -200,
2007
- z: -350
2008
- },
2009
- {
2010
- x: 200,
2011
- y: 200,
2012
- z: -350
2013
- },
2014
- {
2015
- x: -200,
2016
- y: 200,
2017
- z: -350
2018
- }
2019
- ]
2020
- },
2021
- init_pose: {
2022
- position: {
2023
- x: 0,
2024
- y: 0,
2025
- z: 0
2026
- },
2027
- orientation: {
2028
- x: 0,
2029
- y: 0,
2030
- z: 0,
2031
- w: 1
2032
- }
2033
- },
2034
- id: "Robot base"
2035
- },
2036
- motion_group_uid: 1
2037
- }
2038
- ],
2039
- robot_model_geometries: [
2040
- {
2041
- link_index: 1,
2042
- geometry: {
2043
- sphere: {
2044
- radius: 270
2045
- },
2046
- init_pose: {
2047
- position: {
2048
- x: -70,
2049
- y: -70,
2050
- z: -50
2051
- },
2052
- orientation: {
2053
- x: 0,
2054
- y: 0,
2055
- z: 0,
2056
- w: 1
2057
- }
2058
- },
2059
- id: "link1_sphere"
2060
- }
2061
- },
2062
- {
2063
- link_index: 2,
2064
- geometry: {
2065
- capsule: {
2066
- radius: 160,
2067
- cylinder_height: 800
2068
- },
2069
- init_pose: {
2070
- position: {
2071
- x: -450,
2072
- y: 40,
2073
- z: 170
2074
- },
2075
- orientation: {
2076
- x: 0,
2077
- y: -Math.SQRT1_2,
2078
- z: 0,
2079
- w: Math.SQRT1_2
2080
- }
2081
- },
2082
- id: "link2_capsule"
2083
- }
2084
- },
2085
- {
2086
- link_index: 3,
2087
- geometry: {
2088
- sphere: {
2089
- radius: 270
2090
- },
2091
- init_pose: {
2092
- position: {
2093
- x: -110,
2094
- y: 10,
2095
- z: -100
2096
- },
2097
- orientation: {
2098
- x: 0,
2099
- y: 0,
2100
- z: 0,
2101
- w: 1
2102
- }
2103
- },
2104
- id: "link3_sphere"
2105
- }
2106
- },
2107
- {
2108
- link_index: 4,
2109
- geometry: {
2110
- capsule: {
2111
- radius: 110,
2112
- cylinder_height: 600
2113
- },
2114
- init_pose: {
2115
- position: {
2116
- x: 0,
2117
- y: 300,
2118
- z: 40
2119
- },
2120
- orientation: {
2121
- x: -Math.SQRT1_2,
2122
- y: 0,
2123
- z: 0,
2124
- w: Math.SQRT1_2
2125
- }
2126
- },
2127
- id: "link4_capsule"
2128
- }
2129
- },
2130
- {
2131
- link_index: 5,
2132
- geometry: {
2133
- sphere: {
2134
- radius: 75
2135
- },
2136
- init_pose: {
2137
- position: {
2138
- x: 0,
2139
- y: 0,
2140
- z: -50
2141
- },
2142
- orientation: {
2143
- x: 0,
2144
- y: 0,
2145
- z: 0,
2146
- w: 1
2147
- }
2148
- },
2149
- id: "link5_sphere"
2150
- }
2151
- }
2152
- ],
2153
- tool_geometries: []
2154
- };
2155
- }
2156
- },
2157
- {
2158
- method: "GET",
2159
- path: "/cells/:cellId/coordinate-systems",
2160
- handle() {
2161
- return {
2162
- coordinatesystems: [
2163
- {
2164
- coordinate_system: "",
2165
- name: "world",
2166
- reference_uid: "",
2167
- position: {
2168
- x: 0,
2169
- y: 0,
2170
- z: 0
2171
- },
2172
- rotation: {
2173
- angles: [0, 0, 0],
2174
- type: "ROTATION_VECTOR"
2175
- }
2176
- }
2177
- ]
2178
- };
2179
- }
2180
- },
2181
- {
2182
- method: "GET",
2183
- path: "/cells/:cellId/motion-groups/:motionGroupId/tcps",
2184
- handle() {
2185
- return {
2186
- tcps: [
2187
- {
2188
- id: "Flange",
2189
- readable_name: "Default-Flange",
2190
- position: {
2191
- x: 0,
2192
- y: 0,
2193
- z: 0
2194
- },
2195
- rotation: {
2196
- angles: [0, 0, 0, 0],
2197
- type: "ROTATION_VECTOR"
2198
- }
2199
- },
2200
- {
2201
- id: "complex-tcp-position",
2202
- readable_name: "Complex TCP Position",
2203
- position: {
2204
- x: -200,
2205
- y: 300,
2206
- z: 150
2207
- },
2208
- rotation: {
2209
- angles: [
2210
- -0.12139440409113832,
2211
- -0.06356210998212003,
2212
- -0.2023240068185639,
2213
- 0
2214
- ],
2215
- type: "ROTATION_VECTOR"
2216
- }
2217
- }
2218
- ]
2219
- };
2220
- }
2221
- }
2222
- ];
2223
- const method = ((_a = config.method) == null ? void 0 : _a.toUpperCase()) || "GET";
2224
- const path = `/cells${(_c = (_b = config.url) == null ? void 0 : _b.split("/cells")[1]) == null ? void 0 : _c.split("?")[0]}`;
2225
- for (const handler of apiHandlers) {
2226
- const match2 = pathToRegexp.match(handler.path)(path || "");
2227
- if (method === handler.method && match2) {
2228
- const json = handler.handle();
2229
- return {
2230
- status: 200,
2231
- statusText: "Success",
2232
- data: JSON.stringify(json),
2233
- headers: {},
2234
- config,
2235
- request: {
2236
- responseURL: config.url
2237
- }
2238
- };
2239
- }
2240
- }
2241
- throw new import_axios2.AxiosError(
2242
- `No mock handler matched this request: ${method} ${path}`,
2243
- "404",
2244
- config
2245
- );
2246
- });
2247
- }
2248
- handleWebsocketConnection(socket) {
2249
- this.connections.push(socket);
2250
- setTimeout(() => {
2251
- socket.dispatchEvent(new Event("open"));
2252
- console.log("Websocket connection opened from", socket.url);
2253
- if (socket.url.includes("/state-stream")) {
2254
- socket.dispatchEvent(
2255
- new MessageEvent("message", {
2256
- data: JSON.stringify(defaultMotionState)
2257
- })
2258
- );
2259
- }
2260
- if (socket.url.includes("/move-joint")) {
2261
- socket.dispatchEvent(
2262
- new MessageEvent("message", {
2263
- data: JSON.stringify({
2264
- result: {
2265
- motion_group: "0@ur",
2266
- state: {
2267
- controller: "ur",
2268
- operation_mode: "OPERATION_MODE_AUTO",
2269
- safety_state: "SAFETY_STATE_NORMAL",
2270
- timestamp: "2024-09-18T12:48:26.096266444Z",
2271
- velocity_override: 100,
2272
- motion_groups: [
2273
- {
2274
- motion_group: "0@ur",
2275
- controller: "ur",
2276
- joint_position: {
2277
- joints: [
2278
- 1.3492152690887451,
2279
- -1.5659207105636597,
2280
- 1.6653711795806885,
2281
- -1.0991662740707397,
2282
- -1.829018235206604,
2283
- 1.264623761177063
2284
- ]
2285
- },
2286
- joint_velocity: {
2287
- joints: [0, 0, 0, 0, 0, 0]
2288
- },
2289
- flange_pose: {
2290
- position: {
2291
- x: 6.437331889439328,
2292
- y: -628.4123774830913,
2293
- z: 577.0569957147832
2294
- },
2295
- orientation: {
2296
- x: -1.683333649797158,
2297
- y: -1.9783363827298732,
2298
- z: -0.4928031860165713
2299
- },
2300
- coordinate_system: ""
2301
- },
2302
- tcp_pose: {
2303
- position: {
2304
- x: 6.437331889439328,
2305
- y: -628.4123774830913,
2306
- z: 577.0569957147832
2307
- },
2308
- orientation: {
2309
- x: -1.683333649797158,
2310
- y: -1.9783363827298732,
2311
- z: -0.4928031860165713
2312
- },
2313
- coordinate_system: "",
2314
- tcp: "Flange"
2315
- },
2316
- velocity: {
2317
- linear: {
2318
- x: 0,
2319
- y: 0,
2320
- z: 0
2321
- },
2322
- angular: {
2323
- x: -0,
2324
- y: 0,
2325
- z: 0
2326
- },
2327
- coordinate_system: ""
2328
- },
2329
- force: {
2330
- force: {
2331
- x: 0,
2332
- y: 0,
2333
- z: 0
2334
- },
2335
- moment: {
2336
- x: 0,
2337
- y: 0,
2338
- z: 0
2339
- },
2340
- coordinate_system: ""
2341
- },
2342
- joint_limit_reached: {
2343
- limit_reached: [
2344
- false,
2345
- false,
2346
- false,
2347
- false,
2348
- false,
2349
- false
2350
- ]
2351
- },
2352
- joint_current: {
2353
- joints: [0, 0, 0, 0, 0, 0]
2354
- },
2355
- sequence_number: "671259"
2356
- }
2357
- ],
2358
- sequence_number: "671259"
2359
- },
2360
- movement_state: "MOVEMENT_STATE_MOVING"
2361
- }
2362
- })
2363
- })
2364
- );
2365
- }
2366
- if (socket.url.includes("/move-tcp")) {
2367
- socket.dispatchEvent(
2368
- new MessageEvent("message", {
2369
- data: JSON.stringify({
2370
- result: {
2371
- motion_group: "0@ur",
2372
- state: {
2373
- controller: "ur",
2374
- operation_mode: "OPERATION_MODE_AUTO",
2375
- safety_state: "SAFETY_STATE_NORMAL",
2376
- timestamp: "2024-09-18T12:43:12.188335774Z",
2377
- velocity_override: 100,
2378
- motion_groups: [
2379
- {
2380
- motion_group: "0@ur",
2381
- controller: "ur",
2382
- joint_position: {
2383
- joints: [
2384
- 1.3352527618408203,
2385
- -1.5659207105636597,
2386
- 1.6653711795806885,
2387
- -1.110615611076355,
2388
- -1.829018235206604,
2389
- 1.264623761177063
2390
- ]
2391
- },
2392
- joint_velocity: {
2393
- joints: [0, 0, 0, 0, 0, 0]
2394
- },
2395
- flange_pose: {
2396
- position: {
2397
- x: -2.763015284002938,
2398
- y: -630.2151479701106,
2399
- z: 577.524509114342
2400
- },
2401
- orientation: {
2402
- x: -1.704794877102097,
2403
- y: -1.9722372952861567,
2404
- z: -0.4852079204210754
2405
- },
2406
- coordinate_system: ""
2407
- },
2408
- tcp_pose: {
2409
- position: {
2410
- x: -2.763015284002938,
2411
- y: -630.2151479701106,
2412
- z: 577.524509114342
2413
- },
2414
- orientation: {
2415
- x: -1.704794877102097,
2416
- y: -1.9722372952861567,
2417
- z: -0.4852079204210754
2418
- },
2419
- coordinate_system: "",
2420
- tcp: "Flange"
2421
- },
2422
- velocity: {
2423
- linear: {
2424
- x: 0,
2425
- y: 0,
2426
- z: 0
2427
- },
2428
- angular: {
2429
- x: -0,
2430
- y: 0,
2431
- z: 0
2432
- },
2433
- coordinate_system: ""
2434
- },
2435
- force: {
2436
- force: {
2437
- x: 0,
2438
- y: 0,
2439
- z: 0
2440
- },
2441
- moment: {
2442
- x: 0,
2443
- y: 0,
2444
- z: 0
2445
- },
2446
- coordinate_system: ""
2447
- },
2448
- joint_limit_reached: {
2449
- limit_reached: [
2450
- false,
2451
- false,
2452
- false,
2453
- false,
2454
- false,
2455
- false
2456
- ]
2457
- },
2458
- joint_current: {
2459
- joints: [0, 0, 0, 0, 0, 0]
2460
- },
2461
- sequence_number: "627897"
2462
- }
2463
- ],
2464
- sequence_number: "627897"
2465
- },
2466
- movement_state: "MOVEMENT_STATE_MOVING"
2467
- }
2468
- })
2469
- })
2470
- );
2471
- }
2472
- }, 10);
2473
- }
2474
- handleWebsocketMessage(socket, message) {
2475
- console.log(`Received message on ${socket.url}`, message);
2476
- }
2477
- };
2478
- var defaultMotionState = {
2479
- result: {
2480
- state: {
2481
- motion_group: "0@universalrobots-ur5e",
2482
- controller: "universalrobots-ur5e",
2483
- joint_position: {
2484
- joints: [
2485
- 1.1699999570846558,
2486
- -1.5700000524520874,
2487
- 1.3600000143051147,
2488
- 1.0299999713897705,
2489
- 1.2899999618530273,
2490
- 1.2799999713897705
2491
- ]
2492
- },
2493
- joint_velocity: {
2494
- joints: [0, 0, 0, 0, 0, 0]
2495
- },
2496
- flange_pose: {
2497
- position: {
2498
- x: 1.3300010259703043,
2499
- y: -409.2680714682808,
2500
- z: 531.0203477065281
2501
- },
2502
- orientation: {
2503
- x: 1.7564919306270736,
2504
- y: -1.7542521568325058,
2505
- z: 0.7326972590614671
2506
- },
2507
- coordinate_system: ""
2508
- },
2509
- tcp_pose: {
2510
- position: {
2511
- x: 1.3300010259703043,
2512
- y: -409.2680714682808,
2513
- z: 531.0203477065281
2514
- },
2515
- orientation: {
2516
- x: 1.7564919306270736,
2517
- y: -1.7542521568325058,
2518
- z: 0.7326972590614671
2519
- },
2520
- coordinate_system: "",
2521
- tcp: "Flange"
2522
- },
2523
- velocity: {
2524
- linear: {
2525
- x: 0,
2526
- y: 0,
2527
- z: 0
2528
- },
2529
- angular: {
2530
- x: 0,
2531
- y: 0,
2532
- z: 0
2533
- },
2534
- coordinate_system: ""
2535
- },
2536
- force: {
2537
- force: {
2538
- x: 0,
2539
- y: 0,
2540
- z: 0
2541
- },
2542
- moment: {
2543
- x: 0,
2544
- y: 0,
2545
- z: 0
2546
- },
2547
- coordinate_system: ""
2548
- },
2549
- joint_limit_reached: {
2550
- limit_reached: [false, false, false, false, false, false]
2551
- },
2552
- joint_current: {
2553
- joints: [0, 0, 0, 0, 0, 0]
2554
- },
2555
- sequence_number: "1"
2556
- },
2557
- tcp_pose: {
2558
- position: {
2559
- x: 302.90748476115556,
2560
- y: -152.87065869452337,
2561
- z: 424.0454619321661
2562
- },
2563
- orientation: {
2564
- x: 2.3403056115045353,
2565
- y: -1.1706836379431356,
2566
- z: 0.9772511964246311
2567
- },
2568
- coordinate_system: "",
2569
- tcp: "Flange"
2570
- }
2571
- }
664
+ constructor() {
665
+ this.connections = [];
666
+ }
667
+ async handleAPIRequest(config) {
668
+ const apiHandlers = [
669
+ {
670
+ method: "GET",
671
+ path: "/cells/:cellId/controllers",
672
+ handle() {
673
+ return { instances: [{
674
+ controller: "mock-ur5e",
675
+ model_name: "UniversalRobots::Controller",
676
+ host: "mock-ur5e",
677
+ allow_software_install_on_controller: true,
678
+ physical_motion_groups: [{
679
+ motion_group: "0@mock-ur5e",
680
+ name_from_controller: "UR5e",
681
+ active: false,
682
+ model_from_controller: "UniversalRobots_UR5e"
683
+ }],
684
+ has_error: false,
685
+ error_details: ""
686
+ }] };
687
+ }
688
+ },
689
+ {
690
+ method: "GET",
691
+ path: "/cells/:cellId/controllers/:controllerId",
692
+ handle() {
693
+ return {
694
+ configuration: {
695
+ kind: "VirtualController",
696
+ manufacturer: "universalrobots",
697
+ position: "[0,-1.571,-1.571,-1.571,1.571,-1.571,0]",
698
+ type: "universalrobots-ur5e"
699
+ },
700
+ name: "mock-ur5"
701
+ };
702
+ }
703
+ },
704
+ {
705
+ method: "GET",
706
+ path: "/cells/:cellId/motion-groups/:motionGroupId/specification",
707
+ handle() {
708
+ return {
709
+ dh_parameters: [
710
+ {
711
+ alpha: 1.5707963267948966,
712
+ theta: 0,
713
+ a: 0,
714
+ d: 162.25,
715
+ reverse_rotation_direction: false
716
+ },
717
+ {
718
+ alpha: 0,
719
+ theta: 0,
720
+ a: -425,
721
+ d: 0,
722
+ reverse_rotation_direction: false
723
+ },
724
+ {
725
+ alpha: 0,
726
+ theta: 0,
727
+ a: -392.2,
728
+ d: 0,
729
+ reverse_rotation_direction: false
730
+ },
731
+ {
732
+ alpha: 1.5707963267948966,
733
+ theta: 0,
734
+ a: 0,
735
+ d: 133.3,
736
+ reverse_rotation_direction: false
737
+ },
738
+ {
739
+ alpha: -1.5707963267948966,
740
+ theta: 0,
741
+ a: 0,
742
+ d: 99.7,
743
+ reverse_rotation_direction: false
744
+ },
745
+ {
746
+ alpha: 0,
747
+ theta: 0,
748
+ a: 0,
749
+ d: 99.6,
750
+ reverse_rotation_direction: false
751
+ }
752
+ ],
753
+ mechanical_joint_limits: [
754
+ {
755
+ joint: "JOINTNAME_AXIS_1",
756
+ lower_limit: -6.335545063018799,
757
+ upper_limit: 6.335545063018799,
758
+ unlimited: false
759
+ },
760
+ {
761
+ joint: "JOINTNAME_AXIS_2",
762
+ lower_limit: -6.335545063018799,
763
+ upper_limit: 6.335545063018799,
764
+ unlimited: false
765
+ },
766
+ {
767
+ joint: "JOINTNAME_AXIS_3",
768
+ lower_limit: -6.335545063018799,
769
+ upper_limit: 6.335545063018799,
770
+ unlimited: false
771
+ },
772
+ {
773
+ joint: "JOINTNAME_AXIS_4",
774
+ lower_limit: -6.335545063018799,
775
+ upper_limit: 6.335545063018799,
776
+ unlimited: false
777
+ },
778
+ {
779
+ joint: "JOINTNAME_AXIS_5",
780
+ lower_limit: -6.335545063018799,
781
+ upper_limit: 6.335545063018799,
782
+ unlimited: false
783
+ },
784
+ {
785
+ joint: "JOINTNAME_AXIS_6",
786
+ lower_limit: -6.335545063018799,
787
+ upper_limit: 6.335545063018799,
788
+ unlimited: false
789
+ }
790
+ ]
791
+ };
792
+ }
793
+ },
794
+ {
795
+ method: "GET",
796
+ path: "/cells/:cellId/motion-groups/:motionGroupId/safety-setup",
797
+ handle() {
798
+ return {
799
+ safety_settings: [{
800
+ safety_state: "SAFETY_NORMAL",
801
+ settings: {
802
+ joint_position_limits: [
803
+ {
804
+ joint: "JOINTNAME_AXIS_1",
805
+ lower_limit: -2.96705961227417,
806
+ upper_limit: 2.96705961227417,
807
+ unlimited: false
808
+ },
809
+ {
810
+ joint: "JOINTNAME_AXIS_2",
811
+ lower_limit: -1.7453292608261108,
812
+ upper_limit: 2.7925267219543457,
813
+ unlimited: false
814
+ },
815
+ {
816
+ joint: "JOINTNAME_AXIS_3",
817
+ lower_limit: -3.3161256313323975,
818
+ upper_limit: .40142571926116943,
819
+ unlimited: false
820
+ },
821
+ {
822
+ joint: "JOINTNAME_AXIS_4",
823
+ lower_limit: -3.4906585216522217,
824
+ upper_limit: 3.4906585216522217,
825
+ unlimited: false
826
+ },
827
+ {
828
+ joint: "JOINTNAME_AXIS_5",
829
+ lower_limit: -2.4434609413146973,
830
+ upper_limit: 2.4434609413146973,
831
+ unlimited: false
832
+ },
833
+ {
834
+ joint: "JOINTNAME_AXIS_6",
835
+ lower_limit: -4.71238899230957,
836
+ upper_limit: 4.71238899230957,
837
+ unlimited: false
838
+ }
839
+ ],
840
+ joint_velocity_limits: [
841
+ {
842
+ joint: "JOINTNAME_AXIS_1",
843
+ limit: 3.1415927410125732
844
+ },
845
+ {
846
+ joint: "JOINTNAME_AXIS_2",
847
+ limit: 3.1415927410125732
848
+ },
849
+ {
850
+ joint: "JOINTNAME_AXIS_3",
851
+ limit: 3.4906585216522217
852
+ },
853
+ {
854
+ joint: "JOINTNAME_AXIS_4",
855
+ limit: 6.108652591705322
856
+ },
857
+ {
858
+ joint: "JOINTNAME_AXIS_5",
859
+ limit: 6.108652591705322
860
+ },
861
+ {
862
+ joint: "JOINTNAME_AXIS_6",
863
+ limit: 6.981317043304443
864
+ }
865
+ ],
866
+ joint_acceleration_limits: [],
867
+ joint_torque_limits: [],
868
+ tcp_velocity_limit: 1800
869
+ }
870
+ }],
871
+ safety_zones: [
872
+ {
873
+ id: 1,
874
+ priority: 0,
875
+ geometry: {
876
+ compound: { child_geometries: [
877
+ {
878
+ convex_hull: { vertices: [
879
+ {
880
+ x: -800,
881
+ y: -1330,
882
+ z: -1820
883
+ },
884
+ {
885
+ x: 1650,
886
+ y: -1330,
887
+ z: -1820
888
+ },
889
+ {
890
+ x: 1650,
891
+ y: 1330,
892
+ z: -1820
893
+ },
894
+ {
895
+ x: -800,
896
+ y: 1330,
897
+ z: -1820
898
+ }
899
+ ] },
900
+ init_pose: {
901
+ position: {
902
+ x: 0,
903
+ y: 0,
904
+ z: 0
905
+ },
906
+ orientation: {
907
+ x: 0,
908
+ y: 0,
909
+ z: 0,
910
+ w: 1
911
+ }
912
+ },
913
+ id: "box"
914
+ },
915
+ {
916
+ convex_hull: { vertices: [
917
+ {
918
+ x: -800,
919
+ y: -1330,
920
+ z: -1820
921
+ },
922
+ {
923
+ x: 1650,
924
+ y: -1330,
925
+ z: -1820
926
+ },
927
+ {
928
+ x: 1650,
929
+ y: -1330,
930
+ z: 1500
931
+ },
932
+ {
933
+ x: -800,
934
+ y: -1330,
935
+ z: 1500
936
+ }
937
+ ] },
938
+ init_pose: {
939
+ position: {
940
+ x: 0,
941
+ y: 0,
942
+ z: 0
943
+ },
944
+ orientation: {
945
+ x: 0,
946
+ y: 0,
947
+ z: 0,
948
+ w: 1
949
+ }
950
+ },
951
+ id: "box"
952
+ },
953
+ {
954
+ convex_hull: { vertices: [
955
+ {
956
+ x: -800,
957
+ y: -1330,
958
+ z: -1820
959
+ },
960
+ {
961
+ x: -800,
962
+ y: 1330,
963
+ z: -1820
964
+ },
965
+ {
966
+ x: -800,
967
+ y: 1330,
968
+ z: 1500
969
+ },
970
+ {
971
+ x: -800,
972
+ y: -1330,
973
+ z: 1500
974
+ }
975
+ ] },
976
+ init_pose: {
977
+ position: {
978
+ x: 0,
979
+ y: 0,
980
+ z: 0
981
+ },
982
+ orientation: {
983
+ x: 0,
984
+ y: 0,
985
+ z: 0,
986
+ w: 1
987
+ }
988
+ },
989
+ id: "box"
990
+ },
991
+ {
992
+ convex_hull: { vertices: [
993
+ {
994
+ x: 1650,
995
+ y: 1330,
996
+ z: 1500
997
+ },
998
+ {
999
+ x: -800,
1000
+ y: 1330,
1001
+ z: 1500
1002
+ },
1003
+ {
1004
+ x: -800,
1005
+ y: -1330,
1006
+ z: 1500
1007
+ },
1008
+ {
1009
+ x: 1650,
1010
+ y: -1330,
1011
+ z: 1500
1012
+ }
1013
+ ] },
1014
+ init_pose: {
1015
+ position: {
1016
+ x: 0,
1017
+ y: 0,
1018
+ z: 0
1019
+ },
1020
+ orientation: {
1021
+ x: 0,
1022
+ y: 0,
1023
+ z: 0,
1024
+ w: 1
1025
+ }
1026
+ },
1027
+ id: "box"
1028
+ },
1029
+ {
1030
+ convex_hull: { vertices: [
1031
+ {
1032
+ x: 1650,
1033
+ y: 1330,
1034
+ z: 1500
1035
+ },
1036
+ {
1037
+ x: -800,
1038
+ y: 1330,
1039
+ z: 1500
1040
+ },
1041
+ {
1042
+ x: -800,
1043
+ y: 1330,
1044
+ z: -1820
1045
+ },
1046
+ {
1047
+ x: 1650,
1048
+ y: 1330,
1049
+ z: -1820
1050
+ }
1051
+ ] },
1052
+ init_pose: {
1053
+ position: {
1054
+ x: 0,
1055
+ y: 0,
1056
+ z: 0
1057
+ },
1058
+ orientation: {
1059
+ x: 0,
1060
+ y: 0,
1061
+ z: 0,
1062
+ w: 1
1063
+ }
1064
+ },
1065
+ id: "box"
1066
+ },
1067
+ {
1068
+ convex_hull: { vertices: [
1069
+ {
1070
+ x: 1650,
1071
+ y: 1330,
1072
+ z: 1500
1073
+ },
1074
+ {
1075
+ x: 1650,
1076
+ y: -1330,
1077
+ z: 1500
1078
+ },
1079
+ {
1080
+ x: 1650,
1081
+ y: -1330,
1082
+ z: -1820
1083
+ },
1084
+ {
1085
+ x: 1650,
1086
+ y: 1330,
1087
+ z: -1820
1088
+ }
1089
+ ] },
1090
+ init_pose: {
1091
+ position: {
1092
+ x: 0,
1093
+ y: 0,
1094
+ z: 0
1095
+ },
1096
+ orientation: {
1097
+ x: 0,
1098
+ y: 0,
1099
+ z: 0,
1100
+ w: 1
1101
+ }
1102
+ },
1103
+ id: "box"
1104
+ }
1105
+ ] },
1106
+ init_pose: {
1107
+ position: {
1108
+ x: 0,
1109
+ y: 0,
1110
+ z: 0
1111
+ },
1112
+ orientation: {
1113
+ x: 0,
1114
+ y: 0,
1115
+ z: 0,
1116
+ w: 1
1117
+ }
1118
+ },
1119
+ id: "Cell workzone"
1120
+ },
1121
+ motion_group_uid: 1
1122
+ },
1123
+ {
1124
+ id: 2,
1125
+ priority: 0,
1126
+ geometry: {
1127
+ convex_hull: { vertices: [
1128
+ {
1129
+ x: 1650,
1130
+ y: 1330,
1131
+ z: -1850
1132
+ },
1133
+ {
1134
+ x: 865,
1135
+ y: 1330,
1136
+ z: -1850
1137
+ },
1138
+ {
1139
+ x: 865,
1140
+ y: -720,
1141
+ z: -1850
1142
+ },
1143
+ {
1144
+ x: 1650,
1145
+ y: -720,
1146
+ z: -1850
1147
+ },
1148
+ {
1149
+ x: 1650,
1150
+ y: 1330,
1151
+ z: -920
1152
+ },
1153
+ {
1154
+ x: 865,
1155
+ y: 1330,
1156
+ z: -920
1157
+ },
1158
+ {
1159
+ x: 865,
1160
+ y: -720,
1161
+ z: -920
1162
+ },
1163
+ {
1164
+ x: 1650,
1165
+ y: -720,
1166
+ z: -920
1167
+ }
1168
+ ] },
1169
+ init_pose: {
1170
+ position: {
1171
+ x: 0,
1172
+ y: 0,
1173
+ z: 0
1174
+ },
1175
+ orientation: {
1176
+ x: 0,
1177
+ y: 0,
1178
+ z: 0,
1179
+ w: 1
1180
+ }
1181
+ },
1182
+ id: "Transport"
1183
+ },
1184
+ motion_group_uid: 1
1185
+ },
1186
+ {
1187
+ id: 3,
1188
+ priority: 0,
1189
+ geometry: {
1190
+ convex_hull: { vertices: [
1191
+ {
1192
+ x: 1650,
1193
+ y: 1330,
1194
+ z: -600
1195
+ },
1196
+ {
1197
+ x: 865,
1198
+ y: 1330,
1199
+ z: -600
1200
+ },
1201
+ {
1202
+ x: 865,
1203
+ y: 430,
1204
+ z: -600
1205
+ },
1206
+ {
1207
+ x: 1650,
1208
+ y: 430,
1209
+ z: -600
1210
+ },
1211
+ {
1212
+ x: 1650,
1213
+ y: 1330,
1214
+ z: -1250
1215
+ },
1216
+ {
1217
+ x: 865,
1218
+ y: 1330,
1219
+ z: -1250
1220
+ },
1221
+ {
1222
+ x: 865,
1223
+ y: 430,
1224
+ z: -1250
1225
+ },
1226
+ {
1227
+ x: 1650,
1228
+ y: 430,
1229
+ z: -1250
1230
+ }
1231
+ ] },
1232
+ init_pose: {
1233
+ position: {
1234
+ x: 0,
1235
+ y: 0,
1236
+ z: 0
1237
+ },
1238
+ orientation: {
1239
+ x: 0,
1240
+ y: 0,
1241
+ z: 0,
1242
+ w: 1
1243
+ }
1244
+ },
1245
+ id: "Tunel"
1246
+ },
1247
+ motion_group_uid: 1
1248
+ },
1249
+ {
1250
+ id: 4,
1251
+ priority: 0,
1252
+ geometry: {
1253
+ convex_hull: { vertices: [
1254
+ {
1255
+ x: 1650,
1256
+ y: -760,
1257
+ z: -440
1258
+ },
1259
+ {
1260
+ x: 900,
1261
+ y: -760,
1262
+ z: -440
1263
+ },
1264
+ {
1265
+ x: 900,
1266
+ y: -1330,
1267
+ z: -440
1268
+ },
1269
+ {
1270
+ x: 1650,
1271
+ y: -1330,
1272
+ z: -440
1273
+ },
1274
+ {
1275
+ x: 1650,
1276
+ y: -760,
1277
+ z: -1800
1278
+ },
1279
+ {
1280
+ x: 900,
1281
+ y: -760,
1282
+ z: -1800
1283
+ },
1284
+ {
1285
+ x: 900,
1286
+ y: -1330,
1287
+ z: -1800
1288
+ },
1289
+ {
1290
+ x: 1650,
1291
+ y: -1330,
1292
+ z: -1800
1293
+ }
1294
+ ] },
1295
+ init_pose: {
1296
+ position: {
1297
+ x: 0,
1298
+ y: 0,
1299
+ z: 0
1300
+ },
1301
+ orientation: {
1302
+ x: 0,
1303
+ y: 0,
1304
+ z: 0,
1305
+ w: 1
1306
+ }
1307
+ },
1308
+ id: "Fanuc controller"
1309
+ },
1310
+ motion_group_uid: 1
1311
+ },
1312
+ {
1313
+ id: 6,
1314
+ priority: 0,
1315
+ geometry: {
1316
+ convex_hull: { vertices: [
1317
+ {
1318
+ x: -200,
1319
+ y: -200,
1320
+ z: -1900
1321
+ },
1322
+ {
1323
+ x: 200,
1324
+ y: -200,
1325
+ z: -1900
1326
+ },
1327
+ {
1328
+ x: 200,
1329
+ y: 200,
1330
+ z: -1900
1331
+ },
1332
+ {
1333
+ x: -200,
1334
+ y: 200,
1335
+ z: -1900
1336
+ },
1337
+ {
1338
+ x: -200,
1339
+ y: -200,
1340
+ z: -350
1341
+ },
1342
+ {
1343
+ x: 200,
1344
+ y: -200,
1345
+ z: -350
1346
+ },
1347
+ {
1348
+ x: 200,
1349
+ y: 200,
1350
+ z: -350
1351
+ },
1352
+ {
1353
+ x: -200,
1354
+ y: 200,
1355
+ z: -350
1356
+ }
1357
+ ] },
1358
+ init_pose: {
1359
+ position: {
1360
+ x: 0,
1361
+ y: 0,
1362
+ z: 0
1363
+ },
1364
+ orientation: {
1365
+ x: 0,
1366
+ y: 0,
1367
+ z: 0,
1368
+ w: 1
1369
+ }
1370
+ },
1371
+ id: "Robot base"
1372
+ },
1373
+ motion_group_uid: 1
1374
+ }
1375
+ ],
1376
+ robot_model_geometries: [
1377
+ {
1378
+ link_index: 1,
1379
+ geometry: {
1380
+ sphere: { radius: 270 },
1381
+ init_pose: {
1382
+ position: {
1383
+ x: -70,
1384
+ y: -70,
1385
+ z: -50
1386
+ },
1387
+ orientation: {
1388
+ x: 0,
1389
+ y: 0,
1390
+ z: 0,
1391
+ w: 1
1392
+ }
1393
+ },
1394
+ id: "link1_sphere"
1395
+ }
1396
+ },
1397
+ {
1398
+ link_index: 2,
1399
+ geometry: {
1400
+ capsule: {
1401
+ radius: 160,
1402
+ cylinder_height: 800
1403
+ },
1404
+ init_pose: {
1405
+ position: {
1406
+ x: -450,
1407
+ y: 40,
1408
+ z: 170
1409
+ },
1410
+ orientation: {
1411
+ x: 0,
1412
+ y: -Math.SQRT1_2,
1413
+ z: 0,
1414
+ w: Math.SQRT1_2
1415
+ }
1416
+ },
1417
+ id: "link2_capsule"
1418
+ }
1419
+ },
1420
+ {
1421
+ link_index: 3,
1422
+ geometry: {
1423
+ sphere: { radius: 270 },
1424
+ init_pose: {
1425
+ position: {
1426
+ x: -110,
1427
+ y: 10,
1428
+ z: -100
1429
+ },
1430
+ orientation: {
1431
+ x: 0,
1432
+ y: 0,
1433
+ z: 0,
1434
+ w: 1
1435
+ }
1436
+ },
1437
+ id: "link3_sphere"
1438
+ }
1439
+ },
1440
+ {
1441
+ link_index: 4,
1442
+ geometry: {
1443
+ capsule: {
1444
+ radius: 110,
1445
+ cylinder_height: 600
1446
+ },
1447
+ init_pose: {
1448
+ position: {
1449
+ x: 0,
1450
+ y: 300,
1451
+ z: 40
1452
+ },
1453
+ orientation: {
1454
+ x: -Math.SQRT1_2,
1455
+ y: 0,
1456
+ z: 0,
1457
+ w: Math.SQRT1_2
1458
+ }
1459
+ },
1460
+ id: "link4_capsule"
1461
+ }
1462
+ },
1463
+ {
1464
+ link_index: 5,
1465
+ geometry: {
1466
+ sphere: { radius: 75 },
1467
+ init_pose: {
1468
+ position: {
1469
+ x: 0,
1470
+ y: 0,
1471
+ z: -50
1472
+ },
1473
+ orientation: {
1474
+ x: 0,
1475
+ y: 0,
1476
+ z: 0,
1477
+ w: 1
1478
+ }
1479
+ },
1480
+ id: "link5_sphere"
1481
+ }
1482
+ }
1483
+ ],
1484
+ tool_geometries: []
1485
+ };
1486
+ }
1487
+ },
1488
+ {
1489
+ method: "GET",
1490
+ path: "/cells/:cellId/coordinate-systems",
1491
+ handle() {
1492
+ return { coordinatesystems: [{
1493
+ coordinate_system: "",
1494
+ name: "world",
1495
+ reference_uid: "",
1496
+ position: {
1497
+ x: 0,
1498
+ y: 0,
1499
+ z: 0
1500
+ },
1501
+ rotation: {
1502
+ angles: [
1503
+ 0,
1504
+ 0,
1505
+ 0
1506
+ ],
1507
+ type: "ROTATION_VECTOR"
1508
+ }
1509
+ }] };
1510
+ }
1511
+ },
1512
+ {
1513
+ method: "GET",
1514
+ path: "/cells/:cellId/motion-groups/:motionGroupId/tcps",
1515
+ handle() {
1516
+ return { tcps: [{
1517
+ id: "Flange",
1518
+ readable_name: "Default-Flange",
1519
+ position: {
1520
+ x: 0,
1521
+ y: 0,
1522
+ z: 0
1523
+ },
1524
+ rotation: {
1525
+ angles: [
1526
+ 0,
1527
+ 0,
1528
+ 0,
1529
+ 0
1530
+ ],
1531
+ type: "ROTATION_VECTOR"
1532
+ }
1533
+ }, {
1534
+ id: "complex-tcp-position",
1535
+ readable_name: "Complex TCP Position",
1536
+ position: {
1537
+ x: -200,
1538
+ y: 300,
1539
+ z: 150
1540
+ },
1541
+ rotation: {
1542
+ angles: [
1543
+ -.12139440409113832,
1544
+ -.06356210998212003,
1545
+ -.2023240068185639,
1546
+ 0
1547
+ ],
1548
+ type: "ROTATION_VECTOR"
1549
+ }
1550
+ }] };
1551
+ }
1552
+ }
1553
+ ];
1554
+ const method = config.method?.toUpperCase() || "GET";
1555
+ const path = `/cells${config.url?.split("/cells")[1]?.split("?")[0]}`;
1556
+ for (const handler of apiHandlers) {
1557
+ const match = path_to_regexp.match(handler.path)(path || "");
1558
+ if (method === handler.method && match) {
1559
+ const json = handler.handle();
1560
+ return {
1561
+ status: 200,
1562
+ statusText: "Success",
1563
+ data: JSON.stringify(json),
1564
+ headers: {},
1565
+ config,
1566
+ request: { responseURL: config.url }
1567
+ };
1568
+ }
1569
+ }
1570
+ throw new axios.AxiosError(`No mock handler matched this request: ${method} ${path}`, "404", config);
1571
+ }
1572
+ handleWebsocketConnection(socket) {
1573
+ this.connections.push(socket);
1574
+ setTimeout(() => {
1575
+ socket.dispatchEvent(new Event("open"));
1576
+ console.log("Websocket connection opened from", socket.url);
1577
+ if (socket.url.includes("/state-stream")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify(defaultMotionState) }));
1578
+ if (socket.url.includes("/move-joint")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify({ result: {
1579
+ motion_group: "0@ur",
1580
+ state: {
1581
+ controller: "ur",
1582
+ operation_mode: "OPERATION_MODE_AUTO",
1583
+ safety_state: "SAFETY_STATE_NORMAL",
1584
+ timestamp: "2024-09-18T12:48:26.096266444Z",
1585
+ velocity_override: 100,
1586
+ motion_groups: [{
1587
+ motion_group: "0@ur",
1588
+ controller: "ur",
1589
+ joint_position: { joints: [
1590
+ 1.3492152690887451,
1591
+ -1.5659207105636597,
1592
+ 1.6653711795806885,
1593
+ -1.0991662740707397,
1594
+ -1.829018235206604,
1595
+ 1.264623761177063
1596
+ ] },
1597
+ joint_velocity: { joints: [
1598
+ 0,
1599
+ 0,
1600
+ 0,
1601
+ 0,
1602
+ 0,
1603
+ 0
1604
+ ] },
1605
+ flange_pose: {
1606
+ position: {
1607
+ x: 6.437331889439328,
1608
+ y: -628.4123774830913,
1609
+ z: 577.0569957147832
1610
+ },
1611
+ orientation: {
1612
+ x: -1.683333649797158,
1613
+ y: -1.9783363827298732,
1614
+ z: -.4928031860165713
1615
+ },
1616
+ coordinate_system: ""
1617
+ },
1618
+ tcp_pose: {
1619
+ position: {
1620
+ x: 6.437331889439328,
1621
+ y: -628.4123774830913,
1622
+ z: 577.0569957147832
1623
+ },
1624
+ orientation: {
1625
+ x: -1.683333649797158,
1626
+ y: -1.9783363827298732,
1627
+ z: -.4928031860165713
1628
+ },
1629
+ coordinate_system: "",
1630
+ tcp: "Flange"
1631
+ },
1632
+ velocity: {
1633
+ linear: {
1634
+ x: 0,
1635
+ y: 0,
1636
+ z: 0
1637
+ },
1638
+ angular: {
1639
+ x: -0,
1640
+ y: 0,
1641
+ z: 0
1642
+ },
1643
+ coordinate_system: ""
1644
+ },
1645
+ force: {
1646
+ force: {
1647
+ x: 0,
1648
+ y: 0,
1649
+ z: 0
1650
+ },
1651
+ moment: {
1652
+ x: 0,
1653
+ y: 0,
1654
+ z: 0
1655
+ },
1656
+ coordinate_system: ""
1657
+ },
1658
+ joint_limit_reached: { limit_reached: [
1659
+ false,
1660
+ false,
1661
+ false,
1662
+ false,
1663
+ false,
1664
+ false
1665
+ ] },
1666
+ joint_current: { joints: [
1667
+ 0,
1668
+ 0,
1669
+ 0,
1670
+ 0,
1671
+ 0,
1672
+ 0
1673
+ ] },
1674
+ sequence_number: "671259"
1675
+ }],
1676
+ sequence_number: "671259"
1677
+ },
1678
+ movement_state: "MOVEMENT_STATE_MOVING"
1679
+ } }) }));
1680
+ if (socket.url.includes("/move-tcp")) socket.dispatchEvent(new MessageEvent("message", { data: JSON.stringify({ result: {
1681
+ motion_group: "0@ur",
1682
+ state: {
1683
+ controller: "ur",
1684
+ operation_mode: "OPERATION_MODE_AUTO",
1685
+ safety_state: "SAFETY_STATE_NORMAL",
1686
+ timestamp: "2024-09-18T12:43:12.188335774Z",
1687
+ velocity_override: 100,
1688
+ motion_groups: [{
1689
+ motion_group: "0@ur",
1690
+ controller: "ur",
1691
+ joint_position: { joints: [
1692
+ 1.3352527618408203,
1693
+ -1.5659207105636597,
1694
+ 1.6653711795806885,
1695
+ -1.110615611076355,
1696
+ -1.829018235206604,
1697
+ 1.264623761177063
1698
+ ] },
1699
+ joint_velocity: { joints: [
1700
+ 0,
1701
+ 0,
1702
+ 0,
1703
+ 0,
1704
+ 0,
1705
+ 0
1706
+ ] },
1707
+ flange_pose: {
1708
+ position: {
1709
+ x: -2.763015284002938,
1710
+ y: -630.2151479701106,
1711
+ z: 577.524509114342
1712
+ },
1713
+ orientation: {
1714
+ x: -1.704794877102097,
1715
+ y: -1.9722372952861567,
1716
+ z: -.4852079204210754
1717
+ },
1718
+ coordinate_system: ""
1719
+ },
1720
+ tcp_pose: {
1721
+ position: {
1722
+ x: -2.763015284002938,
1723
+ y: -630.2151479701106,
1724
+ z: 577.524509114342
1725
+ },
1726
+ orientation: {
1727
+ x: -1.704794877102097,
1728
+ y: -1.9722372952861567,
1729
+ z: -.4852079204210754
1730
+ },
1731
+ coordinate_system: "",
1732
+ tcp: "Flange"
1733
+ },
1734
+ velocity: {
1735
+ linear: {
1736
+ x: 0,
1737
+ y: 0,
1738
+ z: 0
1739
+ },
1740
+ angular: {
1741
+ x: -0,
1742
+ y: 0,
1743
+ z: 0
1744
+ },
1745
+ coordinate_system: ""
1746
+ },
1747
+ force: {
1748
+ force: {
1749
+ x: 0,
1750
+ y: 0,
1751
+ z: 0
1752
+ },
1753
+ moment: {
1754
+ x: 0,
1755
+ y: 0,
1756
+ z: 0
1757
+ },
1758
+ coordinate_system: ""
1759
+ },
1760
+ joint_limit_reached: { limit_reached: [
1761
+ false,
1762
+ false,
1763
+ false,
1764
+ false,
1765
+ false,
1766
+ false
1767
+ ] },
1768
+ joint_current: { joints: [
1769
+ 0,
1770
+ 0,
1771
+ 0,
1772
+ 0,
1773
+ 0,
1774
+ 0
1775
+ ] },
1776
+ sequence_number: "627897"
1777
+ }],
1778
+ sequence_number: "627897"
1779
+ },
1780
+ movement_state: "MOVEMENT_STATE_MOVING"
1781
+ } }) }));
1782
+ }, 10);
1783
+ }
1784
+ handleWebsocketMessage(socket, message) {
1785
+ console.log(`Received message on ${socket.url}`, message);
1786
+ }
2572
1787
  };
1788
+ const defaultMotionState = { result: {
1789
+ state: {
1790
+ motion_group: "0@universalrobots-ur5e",
1791
+ controller: "universalrobots-ur5e",
1792
+ joint_position: { joints: [
1793
+ 1.1699999570846558,
1794
+ -1.5700000524520874,
1795
+ 1.3600000143051147,
1796
+ 1.0299999713897705,
1797
+ 1.2899999618530273,
1798
+ 1.2799999713897705
1799
+ ] },
1800
+ joint_velocity: { joints: [
1801
+ 0,
1802
+ 0,
1803
+ 0,
1804
+ 0,
1805
+ 0,
1806
+ 0
1807
+ ] },
1808
+ flange_pose: {
1809
+ position: {
1810
+ x: 1.3300010259703043,
1811
+ y: -409.2680714682808,
1812
+ z: 531.0203477065281
1813
+ },
1814
+ orientation: {
1815
+ x: 1.7564919306270736,
1816
+ y: -1.7542521568325058,
1817
+ z: .7326972590614671
1818
+ },
1819
+ coordinate_system: ""
1820
+ },
1821
+ tcp_pose: {
1822
+ position: {
1823
+ x: 1.3300010259703043,
1824
+ y: -409.2680714682808,
1825
+ z: 531.0203477065281
1826
+ },
1827
+ orientation: {
1828
+ x: 1.7564919306270736,
1829
+ y: -1.7542521568325058,
1830
+ z: .7326972590614671
1831
+ },
1832
+ coordinate_system: "",
1833
+ tcp: "Flange"
1834
+ },
1835
+ velocity: {
1836
+ linear: {
1837
+ x: 0,
1838
+ y: 0,
1839
+ z: 0
1840
+ },
1841
+ angular: {
1842
+ x: 0,
1843
+ y: 0,
1844
+ z: 0
1845
+ },
1846
+ coordinate_system: ""
1847
+ },
1848
+ force: {
1849
+ force: {
1850
+ x: 0,
1851
+ y: 0,
1852
+ z: 0
1853
+ },
1854
+ moment: {
1855
+ x: 0,
1856
+ y: 0,
1857
+ z: 0
1858
+ },
1859
+ coordinate_system: ""
1860
+ },
1861
+ joint_limit_reached: { limit_reached: [
1862
+ false,
1863
+ false,
1864
+ false,
1865
+ false,
1866
+ false,
1867
+ false
1868
+ ] },
1869
+ joint_current: { joints: [
1870
+ 0,
1871
+ 0,
1872
+ 0,
1873
+ 0,
1874
+ 0,
1875
+ 0
1876
+ ] },
1877
+ sequence_number: "1"
1878
+ },
1879
+ tcp_pose: {
1880
+ position: {
1881
+ x: 302.90748476115556,
1882
+ y: -152.87065869452337,
1883
+ z: 424.0454619321661
1884
+ },
1885
+ orientation: {
1886
+ x: 2.3403056115045353,
1887
+ y: -1.1706836379431356,
1888
+ z: .9772511964246311
1889
+ },
1890
+ coordinate_system: "",
1891
+ tcp: "Flange"
1892
+ }
1893
+ } };
2573
1894
 
2574
- // src/lib/v1/NovaClient.ts
1895
+ //#endregion
1896
+ //#region src/lib/v1/NovaClient.ts
1897
+ /**
1898
+ * Client for connecting to a Nova instance and controlling robots.
1899
+ */
2575
1900
  var NovaClient = class {
2576
- constructor(config) {
2577
- this.authPromise = null;
2578
- this.accessToken = null;
2579
- var _a;
2580
- const cellId = (_a = config.cellId) != null ? _a : "cell";
2581
- this.config = __spreadValues({
2582
- cellId
2583
- }, config);
2584
- this.accessToken = config.accessToken || availableStorage.getString("wbjs.access_token") || null;
2585
- if (this.config.instanceUrl === "https://mock.example.com") {
2586
- this.mock = new MockNovaInstance();
2587
- }
2588
- const axiosInstance = import_axios3.default.create({
2589
- baseURL: (0, import_url_join.default)(this.config.instanceUrl, "/api/v1"),
2590
- // TODO - backend needs to set proper CORS headers for this
2591
- headers: typeof window !== "undefined" && window.location.origin.includes("localhost") ? {} : {
2592
- // Identify the client to the backend for logging purposes
2593
- "X-Wandelbots-Client": "Wandelbots-Nova-JS-SDK"
2594
- }
2595
- });
2596
- axiosInstance.interceptors.request.use((request) => __async(this, null, function* () {
2597
- if (!request.headers.Authorization) {
2598
- if (this.accessToken) {
2599
- request.headers.Authorization = `Bearer ${this.accessToken}`;
2600
- } else if (this.config.username && this.config.password) {
2601
- request.headers.Authorization = `Basic ${btoa(`${config.username}:${config.password}`)}`;
2602
- }
2603
- }
2604
- return request;
2605
- }));
2606
- if (typeof window !== "undefined") {
2607
- axiosInstance.interceptors.response.use(
2608
- (r) => r,
2609
- (error) => __async(this, null, function* () {
2610
- var _a2, _b;
2611
- if ((0, import_axios3.isAxiosError)(error)) {
2612
- if (((_a2 = error.response) == null ? void 0 : _a2.status) === 401) {
2613
- try {
2614
- yield this.renewAuthentication();
2615
- if (error.config) {
2616
- if (this.accessToken) {
2617
- error.config.headers.Authorization = `Bearer ${this.accessToken}`;
2618
- } else {
2619
- delete error.config.headers.Authorization;
2620
- }
2621
- return axiosInstance.request(error.config);
2622
- }
2623
- } catch (err) {
2624
- return Promise.reject(err);
2625
- }
2626
- } else if (((_b = error.response) == null ? void 0 : _b.status) === 503) {
2627
- const res = yield fetch(window.location.href);
2628
- if (res.status === 503) {
2629
- window.location.reload();
2630
- }
2631
- }
2632
- }
2633
- return Promise.reject(error);
2634
- })
2635
- );
2636
- }
2637
- this.api = new NovaCellAPIClient(cellId, __spreadProps(__spreadValues({}, config), {
2638
- basePath: (0, import_url_join.default)(this.config.instanceUrl, "/api/v1"),
2639
- isJsonMime: (mime) => {
2640
- return mime === "application/json";
2641
- },
2642
- baseOptions: __spreadValues(__spreadValues({}, this.mock ? {
2643
- adapter: (config2) => {
2644
- return this.mock.handleAPIRequest(config2);
2645
- }
2646
- } : {}), config.baseOptions),
2647
- axiosInstance
2648
- }));
2649
- }
2650
- renewAuthentication() {
2651
- return __async(this, null, function* () {
2652
- if (this.authPromise) {
2653
- return;
2654
- }
2655
- this.authPromise = loginWithAuth0(this.config.instanceUrl);
2656
- try {
2657
- this.accessToken = yield this.authPromise;
2658
- if (this.accessToken) {
2659
- availableStorage.setString("wbjs.access_token", this.accessToken);
2660
- } else {
2661
- availableStorage.delete("wbjs.access_token");
2662
- }
2663
- } finally {
2664
- this.authPromise = null;
2665
- }
2666
- });
2667
- }
2668
- makeWebsocketURL(path) {
2669
- const url = new URL(
2670
- (0, import_url_join.default)(
2671
- this.config.instanceUrl,
2672
- `/api/v1/cells/${this.config.cellId}`,
2673
- path
2674
- )
2675
- );
2676
- url.protocol = url.protocol.replace("http", "ws");
2677
- url.protocol = url.protocol.replace("https", "wss");
2678
- if (this.accessToken) {
2679
- url.searchParams.append("token", this.accessToken);
2680
- } else if (this.config.username && this.config.password) {
2681
- url.username = this.config.username;
2682
- url.password = this.config.password;
2683
- }
2684
- return url.toString();
2685
- }
2686
- /**
2687
- * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.
2688
- * If you explicitly want to reconnect an existing websocket, call `reconnect`
2689
- * on the returned object.
2690
- */
2691
- openReconnectingWebsocket(path) {
2692
- return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {
2693
- mock: this.mock
2694
- });
2695
- }
2696
- /**
2697
- * Connect to the motion state websocket(s) for a given motion group
2698
- */
2699
- connectMotionStream(motionGroupId) {
2700
- return __async(this, null, function* () {
2701
- return yield MotionStreamConnection.open(this, motionGroupId);
2702
- });
2703
- }
2704
- /**
2705
- * Connect to the jogging websocket(s) for a given motion group
2706
- */
2707
- connectJogger(motionGroupId) {
2708
- return __async(this, null, function* () {
2709
- return yield JoggerConnection.open(this, motionGroupId);
2710
- });
2711
- }
2712
- connectMotionGroups(motionGroupIds) {
2713
- return __async(this, null, function* () {
2714
- const { instances } = yield this.api.controller.listControllers();
2715
- return Promise.all(
2716
- motionGroupIds.map(
2717
- (motionGroupId) => ConnectedMotionGroup.connect(this, motionGroupId, instances)
2718
- )
2719
- );
2720
- });
2721
- }
2722
- connectMotionGroup(motionGroupId) {
2723
- return __async(this, null, function* () {
2724
- const motionGroups = yield this.connectMotionGroups([motionGroupId]);
2725
- return motionGroups[0];
2726
- });
2727
- }
1901
+ constructor(config) {
1902
+ this.authPromise = null;
1903
+ this.accessToken = null;
1904
+ const cellId = config.cellId ?? "cell";
1905
+ this.config = {
1906
+ cellId,
1907
+ ...config
1908
+ };
1909
+ this.accessToken = config.accessToken || require_LoginWithAuth0.availableStorage.getString("wbjs.access_token") || null;
1910
+ if (this.config.instanceUrl === "https://mock.example.com") this.mock = new MockNovaInstance();
1911
+ const axiosInstance = axios.default.create({
1912
+ baseURL: (0, url_join.default)(this.config.instanceUrl, "/api/v1"),
1913
+ headers: typeof window !== "undefined" && window.location.origin.includes("localhost") ? {} : { "X-Wandelbots-Client": "Wandelbots-Nova-JS-SDK" }
1914
+ });
1915
+ axiosInstance.interceptors.request.use(async (request) => {
1916
+ if (!request.headers.Authorization) {
1917
+ if (this.accessToken) request.headers.Authorization = `Bearer ${this.accessToken}`;
1918
+ else if (this.config.username && this.config.password) request.headers.Authorization = `Basic ${btoa(`${config.username}:${config.password}`)}`;
1919
+ }
1920
+ return request;
1921
+ });
1922
+ if (typeof window !== "undefined") axiosInstance.interceptors.response.use((r) => r, async (error) => {
1923
+ if ((0, axios.isAxiosError)(error)) {
1924
+ if (error.response?.status === 401) try {
1925
+ await this.renewAuthentication();
1926
+ if (error.config) {
1927
+ if (this.accessToken) error.config.headers.Authorization = `Bearer ${this.accessToken}`;
1928
+ else delete error.config.headers.Authorization;
1929
+ return axiosInstance.request(error.config);
1930
+ }
1931
+ } catch (err) {
1932
+ return Promise.reject(err);
1933
+ }
1934
+ else if (error.response?.status === 503) {
1935
+ if ((await fetch(window.location.href)).status === 503) window.location.reload();
1936
+ }
1937
+ }
1938
+ return Promise.reject(error);
1939
+ });
1940
+ this.api = new NovaCellAPIClient(cellId, {
1941
+ ...config,
1942
+ basePath: (0, url_join.default)(this.config.instanceUrl, "/api/v1"),
1943
+ isJsonMime: (mime) => {
1944
+ return mime === "application/json";
1945
+ },
1946
+ baseOptions: {
1947
+ ...this.mock ? { adapter: (config$1) => {
1948
+ return this.mock.handleAPIRequest(config$1);
1949
+ } } : {},
1950
+ ...config.baseOptions
1951
+ },
1952
+ axiosInstance
1953
+ });
1954
+ }
1955
+ async renewAuthentication() {
1956
+ if (this.authPromise) return;
1957
+ this.authPromise = require_LoginWithAuth0.loginWithAuth0(this.config.instanceUrl);
1958
+ try {
1959
+ this.accessToken = await this.authPromise;
1960
+ if (this.accessToken) require_LoginWithAuth0.availableStorage.setString("wbjs.access_token", this.accessToken);
1961
+ else require_LoginWithAuth0.availableStorage.delete("wbjs.access_token");
1962
+ } finally {
1963
+ this.authPromise = null;
1964
+ }
1965
+ }
1966
+ makeWebsocketURL(path) {
1967
+ const url = new URL((0, url_join.default)(this.config.instanceUrl, `/api/v1/cells/${this.config.cellId}`, path));
1968
+ url.protocol = url.protocol.replace("http", "ws");
1969
+ url.protocol = url.protocol.replace("https", "wss");
1970
+ if (this.accessToken) url.searchParams.append("token", this.accessToken);
1971
+ else if (this.config.username && this.config.password) {
1972
+ url.username = this.config.username;
1973
+ url.password = this.config.password;
1974
+ }
1975
+ return url.toString();
1976
+ }
1977
+ /**
1978
+ * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.
1979
+ * If you explicitly want to reconnect an existing websocket, call `reconnect`
1980
+ * on the returned object.
1981
+ */
1982
+ openReconnectingWebsocket(path) {
1983
+ return new require_LoginWithAuth0.AutoReconnectingWebsocket(this.makeWebsocketURL(path), { mock: this.mock });
1984
+ }
1985
+ /**
1986
+ * Connect to the motion state websocket(s) for a given motion group
1987
+ */
1988
+ async connectMotionStream(motionGroupId) {
1989
+ return await MotionStreamConnection.open(this, motionGroupId);
1990
+ }
1991
+ /**
1992
+ * Connect to the jogging websocket(s) for a given motion group
1993
+ */
1994
+ async connectJogger(motionGroupId) {
1995
+ return await JoggerConnection.open(this, motionGroupId);
1996
+ }
1997
+ async connectMotionGroups(motionGroupIds) {
1998
+ const { instances } = await this.api.controller.listControllers();
1999
+ return Promise.all(motionGroupIds.map((motionGroupId) => ConnectedMotionGroup.connect(this, motionGroupId, instances)));
2000
+ }
2001
+ async connectMotionGroup(motionGroupId) {
2002
+ return (await this.connectMotionGroups([motionGroupId]))[0];
2003
+ }
2728
2004
  };
2729
2005
 
2730
- // src/lib/v1/ProgramStateConnection.ts
2731
- var import_axios4 = require("axios");
2732
- var import_mobx3 = require("mobx");
2733
- var ProgramState = /* @__PURE__ */ ((ProgramState2) => {
2734
- ProgramState2["NotStarted"] = "not started";
2735
- ProgramState2["Running"] = "running";
2736
- ProgramState2["Stopped"] = "stopped";
2737
- ProgramState2["Failed"] = "failed";
2738
- ProgramState2["Completed"] = "completed";
2739
- return ProgramState2;
2740
- })(ProgramState || {});
2006
+ //#endregion
2007
+ //#region src/lib/v1/ProgramStateConnection.ts
2008
+ let ProgramState = /* @__PURE__ */ function(ProgramState$1) {
2009
+ ProgramState$1["NotStarted"] = "not started";
2010
+ ProgramState$1["Running"] = "running";
2011
+ ProgramState$1["Stopped"] = "stopped";
2012
+ ProgramState$1["Failed"] = "failed";
2013
+ ProgramState$1["Completed"] = "completed";
2014
+ return ProgramState$1;
2015
+ }({});
2016
+ /**
2017
+ * Interface for running Wandelscript programs on the Nova instance and
2018
+ * tracking their progress and output
2019
+ */
2741
2020
  var ProgramStateConnection = class {
2742
- constructor(nova) {
2743
- this.nova = nova;
2744
- this.currentProgram = {};
2745
- this.logs = [];
2746
- this.executionState = "idle";
2747
- this.currentlyExecutingProgramRunnerId = null;
2748
- (0, import_mobx3.makeAutoObservable)(this, {}, { autoBind: true });
2749
- this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`);
2750
- this.programStateSocket.addEventListener("message", (ev) => {
2751
- const msg = tryParseJson(ev.data);
2752
- if (!msg) {
2753
- console.error("Failed to parse program state message", ev.data);
2754
- return;
2755
- }
2756
- if (msg.type === "update") {
2757
- this.handleProgramStateMessage(msg);
2758
- }
2759
- });
2760
- }
2761
- /** Handle a program state update from the backend */
2762
- handleProgramStateMessage(msg) {
2763
- return __async(this, null, function* () {
2764
- var _a;
2765
- const { runner } = msg;
2766
- if (runner.id !== this.currentlyExecutingProgramRunnerId) return;
2767
- if (runner.state === "failed" /* Failed */) {
2768
- try {
2769
- const runnerState = yield this.nova.api.program.getProgramRunner(
2770
- runner.id
2771
- );
2772
- const stdout = runnerState.stdout;
2773
- if (stdout) {
2774
- this.log(stdout);
2775
- }
2776
- this.logError(
2777
- `Program runner ${runner.id} failed with error: ${runnerState.error}
2778
- ${runnerState.traceback}`
2779
- );
2780
- } catch (err) {
2781
- this.logError(
2782
- `Failed to retrieve results for program ${runner.id}: ${err}`
2783
- );
2784
- }
2785
- this.currentProgram.state = "failed" /* Failed */;
2786
- this.gotoIdleState();
2787
- } else if (runner.state === "stopped" /* Stopped */) {
2788
- try {
2789
- const runnerState = yield this.nova.api.program.getProgramRunner(
2790
- runner.id
2791
- );
2792
- const stdout = runnerState.stdout;
2793
- if (stdout) {
2794
- this.log(stdout);
2795
- }
2796
- this.currentProgram.state = "stopped" /* Stopped */;
2797
- this.log(`Program runner ${runner.id} stopped`);
2798
- } catch (err) {
2799
- this.logError(
2800
- `Failed to retrieve results for program ${runner.id}: ${err}`
2801
- );
2802
- }
2803
- this.gotoIdleState();
2804
- } else if (runner.state === "completed" /* Completed */) {
2805
- try {
2806
- const runnerState = yield this.nova.api.program.getProgramRunner(
2807
- runner.id
2808
- );
2809
- const stdout = runnerState.stdout;
2810
- if (stdout) {
2811
- this.log(stdout);
2812
- }
2813
- this.log(
2814
- `Program runner ${runner.id} finished successfully in ${(_a = runner.execution_time) == null ? void 0 : _a.toFixed(2)} seconds`
2815
- );
2816
- this.currentProgram.state = "completed" /* Completed */;
2817
- } catch (err) {
2818
- this.logError(
2819
- `Failed to retrieve results for program ${runner.id}: ${err}`
2820
- );
2821
- }
2822
- this.gotoIdleState();
2823
- } else if (runner.state === "running" /* Running */) {
2824
- this.currentProgram.state = "running" /* Running */;
2825
- this.log(`Program runner ${runner.id} now running`);
2826
- } else if (runner.state !== "not started" /* NotStarted */) {
2827
- console.error(runner);
2828
- this.logError(
2829
- `Program runner ${runner.id} entered unexpected state: ${runner.state}`
2830
- );
2831
- this.currentProgram.state = "not started" /* NotStarted */;
2832
- this.gotoIdleState();
2833
- }
2834
- });
2835
- }
2836
- /** Call when a program is no longer executing */
2837
- gotoIdleState() {
2838
- (0, import_mobx3.runInAction)(() => {
2839
- this.executionState = "idle";
2840
- });
2841
- this.currentlyExecutingProgramRunnerId = null;
2842
- }
2843
- executeProgram(wandelscript, initial_state, activeRobot) {
2844
- return __async(this, null, function* () {
2845
- this.currentProgram = {
2846
- wandelscript,
2847
- state: "not started" /* NotStarted */
2848
- };
2849
- const { currentProgram: openProgram } = this;
2850
- if (!openProgram) return;
2851
- (0, import_mobx3.runInAction)(() => {
2852
- this.executionState = "starting";
2853
- });
2854
- if (activeRobot) {
2855
- try {
2856
- yield this.nova.api.motionGroupJogging.stopJogging(
2857
- activeRobot.motionGroupId
2858
- );
2859
- } catch (err) {
2860
- console.error(err);
2861
- }
2862
- }
2863
- const trimmedCode = openProgram.wandelscript.replaceAll(/^\s*$/gm, "");
2864
- try {
2865
- const programRunnerRef = yield this.nova.api.program.createProgramRunner(
2866
- {
2867
- code: trimmedCode,
2868
- initial_state,
2869
- // @ts-expect-error legacy code - check if param still used
2870
- default_robot: activeRobot == null ? void 0 : activeRobot.wandelscriptIdentifier
2871
- },
2872
- {
2873
- headers: {
2874
- "Content-Type": "application/json"
2875
- }
2876
- }
2877
- );
2878
- this.log(`Created program runner ${programRunnerRef.id}"`);
2879
- (0, import_mobx3.runInAction)(() => {
2880
- this.executionState = "executing";
2881
- });
2882
- this.currentlyExecutingProgramRunnerId = programRunnerRef.id;
2883
- } catch (error) {
2884
- if (error instanceof import_axios4.AxiosError && error.response && error.request) {
2885
- this.logError(
2886
- `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`
2887
- );
2888
- } else {
2889
- this.logError(JSON.stringify(error));
2890
- }
2891
- (0, import_mobx3.runInAction)(() => {
2892
- this.executionState = "idle";
2893
- });
2894
- }
2895
- });
2896
- }
2897
- stopProgram() {
2898
- return __async(this, null, function* () {
2899
- if (!this.currentlyExecutingProgramRunnerId) return;
2900
- (0, import_mobx3.runInAction)(() => {
2901
- this.executionState = "stopping";
2902
- });
2903
- try {
2904
- yield this.nova.api.program.stopProgramRunner(
2905
- this.currentlyExecutingProgramRunnerId
2906
- );
2907
- } catch (err) {
2908
- (0, import_mobx3.runInAction)(() => {
2909
- this.executionState = "executing";
2910
- });
2911
- throw err;
2912
- }
2913
- });
2914
- }
2915
- reset() {
2916
- this.currentProgram = {};
2917
- }
2918
- log(message) {
2919
- console.log(message);
2920
- this.logs.push({
2921
- timestamp: Date.now(),
2922
- message
2923
- });
2924
- }
2925
- logError(message) {
2926
- console.log(message);
2927
- this.logs.push({
2928
- timestamp: Date.now(),
2929
- message,
2930
- level: "error"
2931
- });
2932
- }
2021
+ constructor(nova) {
2022
+ this.nova = nova;
2023
+ this.currentProgram = {};
2024
+ this.logs = [];
2025
+ this.executionState = "idle";
2026
+ this.currentlyExecutingProgramRunnerId = null;
2027
+ (0, mobx.makeAutoObservable)(this, {}, { autoBind: true });
2028
+ this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`);
2029
+ this.programStateSocket.addEventListener("message", (ev) => {
2030
+ const msg = require_converters.tryParseJson(ev.data);
2031
+ if (!msg) {
2032
+ console.error("Failed to parse program state message", ev.data);
2033
+ return;
2034
+ }
2035
+ if (msg.type === "update") this.handleProgramStateMessage(msg);
2036
+ });
2037
+ }
2038
+ /** Handle a program state update from the backend */
2039
+ async handleProgramStateMessage(msg) {
2040
+ const { runner } = msg;
2041
+ if (runner.id !== this.currentlyExecutingProgramRunnerId) return;
2042
+ if (runner.state === ProgramState.Failed) {
2043
+ try {
2044
+ const runnerState = await this.nova.api.program.getProgramRunner(runner.id);
2045
+ const stdout = runnerState.stdout;
2046
+ if (stdout) this.log(stdout);
2047
+ this.logError(`Program runner ${runner.id} failed with error: ${runnerState.error}\n${runnerState.traceback}`);
2048
+ } catch (err) {
2049
+ this.logError(`Failed to retrieve results for program ${runner.id}: ${err}`);
2050
+ }
2051
+ this.currentProgram.state = ProgramState.Failed;
2052
+ this.gotoIdleState();
2053
+ } else if (runner.state === ProgramState.Stopped) {
2054
+ try {
2055
+ const stdout = (await this.nova.api.program.getProgramRunner(runner.id)).stdout;
2056
+ if (stdout) this.log(stdout);
2057
+ this.currentProgram.state = ProgramState.Stopped;
2058
+ this.log(`Program runner ${runner.id} stopped`);
2059
+ } catch (err) {
2060
+ this.logError(`Failed to retrieve results for program ${runner.id}: ${err}`);
2061
+ }
2062
+ this.gotoIdleState();
2063
+ } else if (runner.state === ProgramState.Completed) {
2064
+ try {
2065
+ const stdout = (await this.nova.api.program.getProgramRunner(runner.id)).stdout;
2066
+ if (stdout) this.log(stdout);
2067
+ this.log(`Program runner ${runner.id} finished successfully in ${runner.execution_time?.toFixed(2)} seconds`);
2068
+ this.currentProgram.state = ProgramState.Completed;
2069
+ } catch (err) {
2070
+ this.logError(`Failed to retrieve results for program ${runner.id}: ${err}`);
2071
+ }
2072
+ this.gotoIdleState();
2073
+ } else if (runner.state === ProgramState.Running) {
2074
+ this.currentProgram.state = ProgramState.Running;
2075
+ this.log(`Program runner ${runner.id} now running`);
2076
+ } else if (runner.state !== ProgramState.NotStarted) {
2077
+ console.error(runner);
2078
+ this.logError(`Program runner ${runner.id} entered unexpected state: ${runner.state}`);
2079
+ this.currentProgram.state = ProgramState.NotStarted;
2080
+ this.gotoIdleState();
2081
+ }
2082
+ }
2083
+ /** Call when a program is no longer executing */
2084
+ gotoIdleState() {
2085
+ (0, mobx.runInAction)(() => {
2086
+ this.executionState = "idle";
2087
+ });
2088
+ this.currentlyExecutingProgramRunnerId = null;
2089
+ }
2090
+ async executeProgram(wandelscript, initial_state, activeRobot) {
2091
+ this.currentProgram = {
2092
+ wandelscript,
2093
+ state: ProgramState.NotStarted
2094
+ };
2095
+ const { currentProgram: openProgram } = this;
2096
+ if (!openProgram) return;
2097
+ (0, mobx.runInAction)(() => {
2098
+ this.executionState = "starting";
2099
+ });
2100
+ if (activeRobot) try {
2101
+ await this.nova.api.motionGroupJogging.stopJogging(activeRobot.motionGroupId);
2102
+ } catch (err) {
2103
+ console.error(err);
2104
+ }
2105
+ const trimmedCode = openProgram.wandelscript.replaceAll(/^\s*$/gm, "");
2106
+ try {
2107
+ const programRunnerRef = await this.nova.api.program.createProgramRunner({
2108
+ code: trimmedCode,
2109
+ initial_state,
2110
+ default_robot: activeRobot?.wandelscriptIdentifier
2111
+ }, { headers: { "Content-Type": "application/json" } });
2112
+ this.log(`Created program runner ${programRunnerRef.id}"`);
2113
+ (0, mobx.runInAction)(() => {
2114
+ this.executionState = "executing";
2115
+ });
2116
+ this.currentlyExecutingProgramRunnerId = programRunnerRef.id;
2117
+ } catch (error) {
2118
+ if (error instanceof axios.AxiosError && error.response && error.request) this.logError(`${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`);
2119
+ else this.logError(JSON.stringify(error));
2120
+ (0, mobx.runInAction)(() => {
2121
+ this.executionState = "idle";
2122
+ });
2123
+ }
2124
+ }
2125
+ async stopProgram() {
2126
+ if (!this.currentlyExecutingProgramRunnerId) return;
2127
+ (0, mobx.runInAction)(() => {
2128
+ this.executionState = "stopping";
2129
+ });
2130
+ try {
2131
+ await this.nova.api.program.stopProgramRunner(this.currentlyExecutingProgramRunnerId);
2132
+ } catch (err) {
2133
+ (0, mobx.runInAction)(() => {
2134
+ this.executionState = "executing";
2135
+ });
2136
+ throw err;
2137
+ }
2138
+ }
2139
+ reset() {
2140
+ this.currentProgram = {};
2141
+ }
2142
+ log(message) {
2143
+ console.log(message);
2144
+ this.logs.push({
2145
+ timestamp: Date.now(),
2146
+ message
2147
+ });
2148
+ }
2149
+ logError(message) {
2150
+ console.log(message);
2151
+ this.logs.push({
2152
+ timestamp: Date.now(),
2153
+ message,
2154
+ level: "error"
2155
+ });
2156
+ }
2933
2157
  };
2934
- // Annotate the CommonJS export names for ESM import in node:
2935
- 0 && (module.exports = {
2936
- ConnectedMotionGroup,
2937
- JoggerConnection,
2938
- MotionStreamConnection,
2939
- NovaCellAPIClient,
2940
- NovaClient,
2941
- ProgramState,
2942
- ProgramStateConnection,
2943
- getLatestTrajectories,
2944
- ...require("@wandelbots/nova-api/v1")
2158
+
2159
+ //#endregion
2160
+ exports.ConnectedMotionGroup = ConnectedMotionGroup;
2161
+ exports.JoggerConnection = JoggerConnection;
2162
+ exports.MotionStreamConnection = MotionStreamConnection;
2163
+ exports.NovaCellAPIClient = NovaCellAPIClient;
2164
+ exports.NovaClient = NovaClient;
2165
+ exports.ProgramState = ProgramState;
2166
+ exports.ProgramStateConnection = ProgramStateConnection;
2167
+ exports.getLatestTrajectories = getLatestTrajectories;
2168
+ Object.keys(__wandelbots_nova_api_v1).forEach(function (k) {
2169
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
2170
+ enumerable: true,
2171
+ get: function () { return __wandelbots_nova_api_v1[k]; }
2172
+ });
2945
2173
  });
2174
+
2946
2175
  //# sourceMappingURL=index.cjs.map