UNPKG

@wandelbots/nova-js

Version:

Official JS client for the Wandelbots API

1,469 lines (1,459 loc) 65.3 kB
import { AutoReconnectingWebsocket, __async, __spreadProps, __spreadValues, availableStorage, loginWithAuth0, tryParseJson } from "../../chunk-V3NJLR6P.js"; // src/lib/v2/index.ts export * from "@wandelbots/nova-api/v2"; // src/lib/v2/ConnectedMotionGroup.ts import { AxiosError } from "axios"; import { makeAutoObservable, runInAction } from "mobx"; // src/lib/v2/motionStateUpdate.ts function jointValuesEqual(oldJointValues, newJointValues, changeDeltaThreshold) { if (newJointValues.length !== oldJointValues.length) { return true; } for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) { if (Math.abs(newJointValues[jointIndex] - oldJointValues[jointIndex]) > changeDeltaThreshold) { return false; } } return true; } function tcpPoseEqual(oldTcp, newTcp, changeDeltaThreshold) { if (oldTcp === void 0 && newTcp || oldTcp && newTcp === void 0) { return false; } if (oldTcp === void 0 || newTcp === void 0) { return true; } let changedDelta = 0; changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0]); changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1]); changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2]); changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0]); changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1]); changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2]); if (changedDelta > changeDeltaThreshold) { return false; } return oldTcp.coordinate_system === newTcp.coordinate_system && oldTcp.tcp === newTcp.tcp; } // src/lib/v2/ConnectedMotionGroup.ts var MOTION_DELTA_THRESHOLD = 1e-4; var ConnectedMotionGroup = class _ConnectedMotionGroup { constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup) { this.nova = nova; this.controller = controller; this.motionGroup = motionGroup; this.initialMotionState = initialMotionState; this.motionStateSocket = motionStateSocket; this.isVirtual = isVirtual; this.tcps = tcps; this.motionGroupSpecification = motionGroupSpecification; this.safetySetup = safetySetup; this.connectedJoggingCartesianSocket = null; this.connectedJoggingJointsSocket = null; // tmp this.joggingVelocity = 10; this.rapidlyChangingMotionState = initialMotionState; motionStateSocket.addEventListener("message", (event) => { var _a; const motionStateResponse = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result; if (!motionStateResponse) { throw new Error( `Failed to get motion state for ${this.motionGroupId}: ${event.data}` ); } if (!jointValuesEqual( this.rapidlyChangingMotionState.joint_position.joints, motionStateResponse.joint_position.joints, MOTION_DELTA_THRESHOLD )) { runInAction(() => { this.rapidlyChangingMotionState = motionStateResponse; }); } if (!tcpPoseEqual( this.rapidlyChangingMotionState.tcp_pose, motionStateResponse.tcp_pose, MOTION_DELTA_THRESHOLD )) { runInAction(() => { this.rapidlyChangingMotionState.tcp_pose = motionStateResponse.tcp_pose; }); } }); makeAutoObservable(this); } static connect(nova, motionGroupId, controllers) { return __async(this, null, function* () { var _a; const [_motionGroupIndex, controllerId] = motionGroupId.split("@"); const controller = controllers.find((c) => c.controller === controllerId); const motionGroup = controller == null ? void 0 : controller.motion_groups.find( (mg) => mg.motion_group === motionGroupId ); if (!controller || !motionGroup) { throw new Error( `Controller ${controllerId} or motion group ${motionGroupId} not found` ); } const motionStateSocket = nova.openReconnectingWebsocket( `/motion-groups/${motionGroupId}/state-stream` ); const firstMessage = yield motionStateSocket.firstMessage(); const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result; if (!initialMotionState) { throw new Error( `Unable to parse initial motion state message ${firstMessage.data}` ); } console.log( `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state: `, initialMotionState ); let isVirtual = false; try { const opMode = yield nova.api.virtualRobotMode.getOperationMode(controllerId); if (opMode) isVirtual = true; } catch (err) { if (err instanceof AxiosError) { console.log( `Received ${err.status} from getOperationMode, concluding that ${controllerId} is physical` ); } else { throw err; } } const { tcps } = yield nova.api.motionGroupInfos.listTcps(motionGroupId); const motionGroupSpecification = yield nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId); const safetySetup = yield nova.api.motionGroupInfos.getSafetySetup(motionGroupId); return new _ConnectedMotionGroup( nova, controller, motionGroup, initialMotionState, motionStateSocket, isVirtual, tcps, motionGroupSpecification, safetySetup ); }); } get motionGroupId() { return this.motionGroup.motion_group; } get controllerId() { return this.controller.controller; } get modelFromController() { return this.motionGroup.model_from_controller; } get wandelscriptIdentifier() { const num = this.motionGroupId.split("@")[0]; return `${this.controllerId.replaceAll("-", "_")}_${num}`; } /** Jogging velocity in radians for rotation and joint movement */ get joggingVelocityRads() { return this.joggingVelocity * Math.PI / 180; } get joints() { return this.initialMotionState.joint_position.joints.map((_, i) => { return { index: i }; }); } get dhParameters() { return this.motionGroupSpecification.dh_parameters; } get safetyZones() { return this.safetySetup.safety_zones; } dispose() { this.motionStateSocket.close(); if (this.connectedJoggingCartesianSocket) this.connectedJoggingCartesianSocket.close(); if (this.connectedJoggingJointsSocket) this.connectedJoggingJointsSocket.close(); } setJoggingVelocity(velocity) { this.joggingVelocity = velocity; } }; // src/lib/v2/vectorUtils.ts import * as THREE from "three"; function axisToIndex(axis) { switch (axis) { case "x": return 0; case "y": return 1; case "z": return 2; } } function vector3ToArray(vector) { return [vector.x, vector.y, vector.z]; } // src/lib/v2/JoggerConnection.ts var JoggerConnection = class _JoggerConnection { constructor(nova, cell, motionGroupId, motionGroupState, opts) { this.nova = nova; this.cell = cell; this.motionGroupId = motionGroupId; this.motionGroupState = motionGroupState; this.opts = opts; // Currently a separate websocket is needed for each mode, pester API people // to merge these for simplicity this.joggingWebsocket = null; this.lastVelocityRequest = null; this.lastResponse = null; this.joggingWebsocket = nova.openReconnectingWebsocket( `/cells/${cell}/execution/jogging` ); this.joggingWebsocket.addEventListener("message", (ev) => { const data = tryParseJson(ev.data); if (data && "error" in data) { if (this.opts.onError) { this.opts.onError(ev.data); } else { throw new Error(ev.data); } } }); this.joggingWebsocket.addEventListener("message", (ev) => { const data = tryParseJson(ev.data); if (data && "error" in data) { if (this.opts.onError) { this.opts.onError(ev.data); } else { throw new Error(ev.data); } } }); } static open(nova, cell, motionGroupId, opts) { return __async(this, null, function* () { const motionGroupState = yield nova.api.motionGroupInfos.getCurrentMotionGroupState(motionGroupId); return new _JoggerConnection( nova, cell, motionGroupId, motionGroupState, opts ); }); } get jointCount() { var _a; return (_a = this.motionGroupState.joint_current) == null ? void 0 : _a.joints.length; } get activeWebsocket() { return this.joggingWebsocket; } stop() { return __async(this, null, function* () { var _a, _b; if (!this.joggingWebsocket) { return; } if (((_a = this.lastVelocityRequest) == null ? void 0 : _a.message_type) === "JointVelocityRequest") { this.joggingWebsocket.sendJson({ message_type: "JointVelocityRequest", velocity: { joints: Array.from(new Array(this.jointCount).keys()).map(() => 0) } }); } if (((_b = this.lastVelocityRequest) == null ? void 0 : _b.message_type) === "TcpVelocityRequest") { this.joggingWebsocket.sendJson({ message_type: "TcpVelocityRequest", rotation: [0, 0, 0], translation: [0, 0, 0] }); } }); } dispose() { if (this.joggingWebsocket) { this.joggingWebsocket.dispose(); } } /** * Start rotation of a single robot joint at the specified velocity */ startJointRotation(_0) { return __async(this, arguments, function* ({ joint, velocityRadsPerSec }) { if (!this.joggingWebsocket) { throw new Error( "Joint jogging websocket not connected. Wait for reconnect or open new jogging connection" ); } const jointVelocities = new Array(this.jointCount).fill(0); jointVelocities[joint] = velocityRadsPerSec; this.joggingWebsocket.sendJson({ message_type: "JointVelocityRequest", velocity: { joints: jointVelocities } }); }); } /** * Start the TCP moving along a specified axis at a given velocity */ startTCPTranslation(_0) { return __async(this, arguments, function* ({ axis, velocityMmPerSec, useToolCoordinateSystem }) { if (!this.joggingWebsocket) { throw new Error( "Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection" ); } const joggingVector = [0, 0, 0]; joggingVector[axisToIndex(axis)] = velocityMmPerSec; this.joggingWebsocket.sendJson({ message_type: "TcpVelocityRequest", translation: joggingVector, rotation: [0, 0, 0], use_tool_coordinate_system: useToolCoordinateSystem }); }); } /** * Start the TCP rotating around a specified axis at a given velocity */ startTCPRotation(_0) { return __async(this, arguments, function* ({ axis, velocityRadsPerSec, useToolCoordinateSystem }) { if (!this.joggingWebsocket) { throw new Error( "Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection" ); } const joggingVector = [0, 0, 0]; joggingVector[axisToIndex(axis)] = velocityRadsPerSec; this.joggingWebsocket.sendJson({ message_type: "TcpVelocityRequest", rotation: joggingVector, translation: [0, 0, 0], use_tool_coordinate_system: useToolCoordinateSystem }); }); } }; // src/lib/v2/MotionStreamConnection.ts import { makeAutoObservable as makeAutoObservable2, runInAction as runInAction2 } from "mobx"; import * as THREE2 from "three"; var MOTION_DELTA_THRESHOLD2 = 1e-4; function unwrapRotationVector(newRotationVectorApi, currentRotationVectorApi) { const currentRotationVector = new THREE2.Vector3( currentRotationVectorApi[0], currentRotationVectorApi[1], currentRotationVectorApi[2] ); const newRotationVector = new THREE2.Vector3( newRotationVectorApi[0], newRotationVectorApi[1], newRotationVectorApi[2] ); const currentAngle = currentRotationVector.length(); const currentAxis = currentRotationVector.normalize(); let newAngle = newRotationVector.length(); let newAxis = newRotationVector.normalize(); if (newAxis.dot(currentAxis) < 0) { newAngle = -newAngle; newAxis = newAxis.multiplyScalar(-1); } let angleDifference = newAngle - currentAngle; angleDifference -= 2 * Math.PI * Math.floor((angleDifference + Math.PI) / (2 * Math.PI)); newAngle = currentAngle + angleDifference; return vector3ToArray(newAxis.multiplyScalar(newAngle)); } var MotionStreamConnection = class _MotionStreamConnection { constructor(nova, controller, motionGroup, initialMotionState, motionStateSocket) { this.nova = nova; this.controller = controller; this.motionGroup = motionGroup; this.initialMotionState = initialMotionState; this.motionStateSocket = motionStateSocket; this.rapidlyChangingMotionState = initialMotionState; motionStateSocket.addEventListener("message", (event) => { var _a; const motionState = (_a = tryParseJson(event.data)) == null ? void 0 : _a.result; if (!motionState) { throw new Error( `Failed to get motion state for ${this.motionGroupId}: ${event.data}` ); } if (!jointValuesEqual( this.rapidlyChangingMotionState.joint_position.joints, motionState.joint_position.joints, MOTION_DELTA_THRESHOLD2 )) { runInAction2(() => { this.rapidlyChangingMotionState = motionState; }); } if (!tcpPoseEqual( this.rapidlyChangingMotionState.tcp_pose, motionState.tcp_pose, MOTION_DELTA_THRESHOLD2 )) { runInAction2(() => { if (this.rapidlyChangingMotionState.tcp_pose == void 0) { this.rapidlyChangingMotionState.tcp_pose = motionState.tcp_pose; } else { this.rapidlyChangingMotionState.tcp_pose = { position: motionState.tcp_pose.position, orientation: unwrapRotationVector( motionState.tcp_pose.orientation, this.rapidlyChangingMotionState.tcp_pose.orientation ), tcp: motionState.tcp_pose.tcp, coordinate_system: motionState.tcp_pose.coordinate_system }; } }); } }); makeAutoObservable2(this); } static open(nova, motionGroupId) { return __async(this, null, function* () { var _a; const { controllers } = yield nova.api.controller.listControllers(); const [_motionGroupIndex, controllerId] = motionGroupId.split("@"); const controller = controllers.find((c) => c.controller === controllerId); const motionGroup = controller == null ? void 0 : controller.motion_groups.find( (mg) => mg.motion_group === motionGroupId ); if (!controller || !motionGroup) { throw new Error( `Controller ${controllerId} or motion group ${motionGroupId} not found` ); } const motionStateSocket = nova.openReconnectingWebsocket( `/motion-groups/${motionGroupId}/state-stream` ); const firstMessage = yield motionStateSocket.firstMessage(); console.log("got first message", firstMessage); const initialMotionState = (_a = tryParseJson(firstMessage.data)) == null ? void 0 : _a.result; if (!initialMotionState) { throw new Error( `Unable to parse initial motion state message ${firstMessage.data}` ); } console.log( `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state: `, initialMotionState ); return new _MotionStreamConnection( nova, controller, motionGroup, initialMotionState, motionStateSocket ); }); } get motionGroupId() { return this.motionGroup.motion_group; } get controllerId() { return this.controller.controller; } get modelFromController() { return this.motionGroup.model_from_controller; } get wandelscriptIdentifier() { const num = this.motionGroupId.split("@")[0]; return `${this.controllerId.replaceAll("-", "_")}_${num}`; } get joints() { return this.initialMotionState.joint_position.joints.map((_, i) => { return { index: i }; }); } dispose() { this.motionStateSocket.close(); } }; // src/lib/v2/NovaCellAPIClient.ts import { ApplicationApi, CellApi, ControllerApi, ControllerInputsOutputsApi, CoordinateSystemsApi, JoggingApi, MotionGroupApi, MotionGroupInfoApi, MotionGroupKinematicsApi, ProgramApi, ProgramOperatorApi, StoreCollisionComponentsApi, StoreCollisionScenesApi, StoreObjectApi, SystemApi, TrajectoryExecutionApi, TrajectoryPlanningApi, VirtualRobotApi, VirtualRobotBehaviorApi, VirtualRobotModeApi, VirtualRobotSetupApi } from "@wandelbots/nova-api/v2"; import axios from "axios"; var NovaCellAPIClient = class { constructor(cellId, opts) { this.cellId = cellId; this.opts = opts; this.system = this.withUnwrappedResponsesOnly(SystemApi); this.cell = this.withUnwrappedResponsesOnly(CellApi); this.motionGroup = this.withCellId(MotionGroupApi); this.motionGroupInfos = this.withCellId(MotionGroupInfoApi); this.controller = this.withCellId(ControllerApi); this.program = this.withCellId(ProgramApi); this.programOperator = this.withCellId(ProgramOperatorApi); this.controllerIOs = this.withCellId(ControllerInputsOutputsApi); this.motionGroupKinematic = this.withCellId(MotionGroupKinematicsApi); this.trajectoryPlanning = this.withCellId(TrajectoryPlanningApi); this.trajectoryExecution = this.withCellId(TrajectoryExecutionApi); this.coordinateSystems = this.withCellId(CoordinateSystemsApi); this.application = this.withCellId(ApplicationApi); this.applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi); this.jogging = this.withCellId(JoggingApi); this.virtualRobot = this.withCellId(VirtualRobotApi); this.virtualRobotSetup = this.withCellId(VirtualRobotSetupApi); this.virtualRobotMode = this.withCellId(VirtualRobotModeApi); this.virtualRobotBehavior = this.withCellId(VirtualRobotBehaviorApi); this.storeObject = this.withCellId(StoreObjectApi); this.storeCollisionComponents = this.withCellId( StoreCollisionComponentsApi ); this.storeCollisionScenes = this.withCellId(StoreCollisionScenesApi); } /** * Some TypeScript sorcery which alters the API class methods so you don't * have to pass the cell id to every single one, and de-encapsulates the * response data */ withCellId(ApiConstructor) { var _a, _b; const apiClient = new ApiConstructor( __spreadProps(__spreadValues({}, this.opts), { isJsonMime: (mime) => { return mime === "application/json"; } }), (_a = this.opts.basePath) != null ? _a : "", (_b = this.opts.axiosInstance) != null ? _b : axios.create() ); for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) { if (key !== "constructor" && typeof apiClient[key] === "function") { const originalFunction = apiClient[key]; apiClient[key] = (...args) => { return originalFunction.apply(apiClient, [this.cellId, ...args]).then((res) => res.data); }; } } return apiClient; } /** * As withCellId, but only does the response unwrapping */ withUnwrappedResponsesOnly(ApiConstructor) { var _a, _b; const apiClient = new ApiConstructor( __spreadProps(__spreadValues({}, this.opts), { isJsonMime: (mime) => { return mime === "application/json"; } }), (_a = this.opts.basePath) != null ? _a : "", (_b = this.opts.axiosInstance) != null ? _b : axios.create() ); for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient))) { if (key !== "constructor" && typeof apiClient[key] === "function") { const originalFunction = apiClient[key]; apiClient[key] = (...args) => { return originalFunction.apply(apiClient, args).then((res) => res.data); }; } } return apiClient; } }; // src/lib/v2/NovaClient.ts import axios2, { isAxiosError } from "axios"; import urlJoin from "url-join"; // src/lib/v2/mock/MockNovaInstance.ts import { AxiosError as AxiosError2 } from "axios"; import * as pathToRegexp from "path-to-regexp"; var MockNovaInstance = class { constructor() { this.connections = []; } handleAPIRequest(config) { return __async(this, null, function* () { var _a, _b, _c; const apiHandlers = [ { method: "GET", path: "/cells/:cellId/controllers", handle() { return { controllers: [ { controller: "mock-ur5e", model_name: "UniversalRobots::Controller", host: "mock-ur5e", allow_software_install_on_controller: true, motion_groups: [ { motion_group: "0@mock-ur5e", name_from_controller: "UR5e", active: false, model_from_controller: "UniversalRobots_UR5e" } ], has_error: false, error_details: "" } ] }; } }, { method: "GET", path: "/cells/:cellId/controllers/:controllerId", handle() { return { configuration: { kind: "VirtualController", manufacturer: "universalrobots", position: "[0,-1.571,-1.571,-1.571,1.571,-1.571,0]", type: "universalrobots-ur5e" }, name: "mock-ur5" }; } }, { method: "GET", path: "/cells/:cellId/motion-groups/:motionGroupId/specification", handle() { return { dh_parameters: [ { alpha: 1.5707963267948966, theta: 0, a: 0, d: 162.25, reverse_rotation_direction: false }, { alpha: 0, theta: 0, a: -425, d: 0, reverse_rotation_direction: false }, { alpha: 0, theta: 0, a: -392.2, d: 0, reverse_rotation_direction: false }, { alpha: 1.5707963267948966, theta: 0, a: 0, d: 133.3, reverse_rotation_direction: false }, { alpha: -1.5707963267948966, theta: 0, a: 0, d: 99.7, reverse_rotation_direction: false }, { alpha: 0, theta: 0, a: 0, d: 99.6, reverse_rotation_direction: false } ], mechanical_joint_limits: [ { joint: "JOINTNAME_AXIS_1", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false }, { joint: "JOINTNAME_AXIS_2", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false }, { joint: "JOINTNAME_AXIS_3", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false }, { joint: "JOINTNAME_AXIS_4", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false }, { joint: "JOINTNAME_AXIS_5", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false }, { joint: "JOINTNAME_AXIS_6", lower_limit: -6.335545063018799, upper_limit: 6.335545063018799, unlimited: false } ] }; } }, { method: "GET", path: "/cells/:cellId/motion-groups/:motionGroupId/safety-setup", handle() { return { safety_settings: [ { safety_state: "SAFETY_NORMAL", settings: { joint_position_limits: [ { joint: "JOINTNAME_AXIS_1", lower_limit: -2.96705961227417, upper_limit: 2.96705961227417, unlimited: false }, { joint: "JOINTNAME_AXIS_2", lower_limit: -1.7453292608261108, upper_limit: 2.7925267219543457, unlimited: false }, { joint: "JOINTNAME_AXIS_3", lower_limit: -3.3161256313323975, upper_limit: 0.40142571926116943, unlimited: false }, { joint: "JOINTNAME_AXIS_4", lower_limit: -3.4906585216522217, upper_limit: 3.4906585216522217, unlimited: false }, { joint: "JOINTNAME_AXIS_5", lower_limit: -2.4434609413146973, upper_limit: 2.4434609413146973, unlimited: false }, { joint: "JOINTNAME_AXIS_6", lower_limit: -4.71238899230957, upper_limit: 4.71238899230957, unlimited: false } ], joint_velocity_limits: [ { joint: "JOINTNAME_AXIS_1", limit: 3.1415927410125732 }, { joint: "JOINTNAME_AXIS_2", limit: 3.1415927410125732 }, { joint: "JOINTNAME_AXIS_3", limit: 3.4906585216522217 }, { joint: "JOINTNAME_AXIS_4", limit: 6.108652591705322 }, { joint: "JOINTNAME_AXIS_5", limit: 6.108652591705322 }, { joint: "JOINTNAME_AXIS_6", limit: 6.981317043304443 } ], joint_acceleration_limits: [], joint_torque_limits: [], tcp_velocity_limit: 1800 } } ], safety_zones: [ { id: 1, priority: 0, geometry: { compound: { child_geometries: [ { convex_hull: { vertices: [ { vertex: [-800, -1330, -1820] }, { vertex: [1650, -1330, -1820] }, { vertex: [1650, 1330, -1820] }, { vertex: [-800, 1330, -1820] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" }, { convex_hull: { vertices: [ { vertex: [-800, -1330, -1820] }, { vertex: [1650, -1330, -1820] }, { vertex: [1650, -1330, 1500] }, { vertex: [-800, -1330, 1500] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" }, { convex_hull: { vertices: [ { vertex: [-800, -1330, -1820] }, { vertex: [-800, 1330, -1820] }, { vertex: [-800, 1330, 1500] }, { vertex: [-800, -1330, 1500] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" }, { convex_hull: { vertices: [ { vertex: [1650, 1330, 1500] }, { vertex: [-800, 1330, 1500] }, { vertex: [-800, -1330, 1500] }, { vertex: [1650, -1330, 1500] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" }, { convex_hull: { vertices: [ { vertex: [1650, 1330, 1500] }, { vertex: [-800, 1330, 1500] }, { vertex: [-800, 1330, -1820] }, { vertex: [1650, 1330, -1820] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" }, { convex_hull: { vertices: [ { vertex: [1650, 1330, 1500] }, { vertex: [1650, -1330, 1500] }, { vertex: [1650, -1330, -1820] }, { vertex: [1650, 1330, -1820] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "box" } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "Cell workzone" }, motion_group_uid: 1 }, { id: 2, priority: 0, geometry: { convex_hull: { vertices: [ { vertex: [1650, 1330, -1850] }, { vertex: [865, 1330, -1850] }, { vertex: [865, -720, -1850] }, { vertex: [1650, -720, -1850] }, { vertex: [1650, 1330, -920] }, { vertex: [865, 1330, -920] }, { vertex: [865, -720, -920] }, { vertex: [1650, -720, -920] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "Transport" }, motion_group_uid: 1 }, { id: 3, priority: 0, geometry: { convex_hull: { vertices: [ { vertex: [1650, 1330, -600] }, { vertex: [865, 1330, -600] }, { vertex: [865, 430, -600] }, { vertex: [1650, 430, -600] }, { vertex: [1650, 1330, -1250] }, { vertex: [865, 1330, -1250] }, { vertex: [865, 430, -1250] }, { vertex: [1650, 430, -1250] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "Tunel" }, motion_group_uid: 1 }, { id: 4, priority: 0, geometry: { convex_hull: { vertices: [ { vertex: [1650, -760, -440] }, { vertex: [900, -760, -440] }, { vertex: [900, -1330, -440] }, { vertex: [1650, -1330, -440] }, { vertex: [1650, -760, -1800] }, { vertex: [900, -760, -1800] }, { vertex: [900, -1330, -1800] }, { vertex: [1650, -1330, -1800] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "Fanuc controller" }, motion_group_uid: 1 }, { id: 6, priority: 0, geometry: { convex_hull: { vertices: [ { vertex: [-200, -200, -1900] }, { vertex: [200, -200, -1900] }, { vertex: [200, 200, -1900] }, { vertex: [-200, 200, -1900] }, { vertex: [-200, -200, -350] }, { vertex: [200, -200, -350] }, { vertex: [200, 200, -350] }, { vertex: [-200, 200, -350] } ] }, init_pose: { position: [0, 0, 0], orientation: [0, 0, 0, 1] }, id: "Robot base" }, motion_group_uid: 1 } ], robot_model_geometries: [ { link_index: 1, geometry: { sphere: { radius: 270 }, init_pose: { position: [-70, -70, -50], orientation: [0, 0, 0, 1] }, id: "link1_sphere" } }, { link_index: 2, geometry: { capsule: { radius: 160, cylinder_height: 800 }, init_pose: { position: [-450, 40, 170], orientation: [ 0, -0.7071067811865475, 0, 0.7071067811865476 ] }, id: "link2_capsule" } }, { link_index: 3, geometry: { sphere: { radius: 270 }, init_pose: { position: [-110, 10, -100], orientation: [0, 0, 0, 1] }, id: "link3_sphere" } }, { link_index: 4, geometry: { capsule: { radius: 110, cylinder_height: 600 }, init_pose: { position: [0, 300, 40], orientation: [ -0.7071067811865475, 0, 0, 0.7071067811865476 ] }, id: "link4_capsule" } }, { link_index: 5, geometry: { sphere: { radius: 75 }, init_pose: { position: [0, 0, -50], orientation: [0, 0, 0, 1] }, id: "link5_sphere" } } ], tool_geometries: [] }; } }, { method: "GET", path: "/cells/:cellId/coordinate-systems", handle() { return { coordinatesystems: [ { coordinate_system: "", name: "world", reference_uid: "", position: [0, 0, 0], rotation: { angles: [0, 0, 0], type: "ROTATION_VECTOR" } } ] }; } }, { method: "GET", path: "/cells/:cellId/motion-groups/:motionGroupId/tcps", handle() { return { tcps: [ { id: "Flange", readable_name: "Default-Flange", position: [0, 0, 0], rotation: { angles: [0, 0, 0, 0], type: "ROTATION_VECTOR" } }, { id: "complex-tcp-position", readable_name: "Complex TCP Position", position: [-200, 300, 150], rotation: { angles: [ -0.12139440409113832, -0.06356210998212003, -0.2023240068185639, 0 ], type: "ROTATION_VECTOR" } } ] }; } } ]; const method = ((_a = config.method) == null ? void 0 : _a.toUpperCase()) || "GET"; const path = "/cells" + ((_c = (_b = config.url) == null ? void 0 : _b.split("/cells")[1]) == null ? void 0 : _c.split("?")[0]); for (const handler of apiHandlers) { const match2 = pathToRegexp.match(handler.path)(path || ""); if (method === handler.method && match2) { const json = handler.handle(); return { status: 200, statusText: "Success", data: JSON.stringify(json), headers: {}, config, request: { responseURL: config.url } }; } } throw new AxiosError2( `No mock handler matched this request: ${method} ${path}`, "404", config ); }); } handleWebsocketConnection(socket) { this.connections.push(socket); setTimeout(() => { socket.dispatchEvent(new Event("open")); console.log("Websocket connection opened from", socket.url); if (socket.url.includes("/state-stream")) { socket.dispatchEvent( new MessageEvent("message", { data: JSON.stringify(defaultMotionState) }) ); } if (socket.url.includes("/move-joint")) { socket.dispatchEvent( new MessageEvent("message", { data: JSON.stringify({ result: { motion_group: "0@ur", state: { controller: "ur", operation_mode: "OPERATION_MODE_AUTO", safety_state: "SAFETY_STATE_NORMAL", timestamp: "2024-09-18T12:48:26.096266444Z", velocity_override: 100, motion_groups: [ { motion_group: "0@ur", controller: "ur", joint_position: { joints: [ 1.3492152690887451, -1.5659207105636597, 1.6653711795806885, -1.0991662740707397, -1.829018235206604, 1.264623761177063 ] }, joint_velocity: { joints: [0, 0, 0, 0, 0, 0] }, flange_pose: { position: [ 6.437331889439328, -628.4123774830913, 577.0569957147832 ], orientation: { x: -1.683333649797158, y: -1.9783363827298732, z: -0.4928031860165713 }, coordinate_system: "" }, tcp_pose: { position: [ 6.437331889439328, -628.4123774830913, 577.0569957147832 ], orientation: { x: -1.683333649797158, y: -1.9783363827298732, z: -0.4928031860165713 }, coordinate_system: "", tcp: "Flange" }, velocity: { linear: { x: 0, y: 0, z: 0 }, angular: { x: -0, y: 0, z: 0 }, coordinate_system: "" }, force: { force: { x: 0, y: 0, z: 0 }, moment: { x: 0, y: 0, z: 0 }, coordinate_system: "" }, joint_limit_reached: { limit_reached: [ false, false, false, false, false, false ] }, joint_current: { joints: [0, 0, 0, 0, 0, 0] }, sequence_number: "671259" } ], sequence_number: "671259" }, movement_state: "MOVEMENT_STATE_MOVING" } }) }) ); } if (socket.url.includes("/move-tcp")) { socket.dispatchEvent( new MessageEvent("message", { data: JSON.stringify({ result: { motion_group: "0@ur", state: { controller: "ur", operation_mode: "OPERATION_MODE_AUTO", safety_state: "SAFETY_STATE_NORMAL", timestamp: "2024-09-18T12:43:12.188335774Z", velocity_override: 100, motion_groups: [ { motion_group: "0@ur", controller: "ur", joint_position: { joints: [ 1.3352527618408203, -1.5659207105636597, 1.6653711795806885, -1.110615611076355, -1.829018235206604, 1.264623761177063 ] }, joint_velocity: { joints: [0, 0, 0, 0, 0, 0] }, flange_pose: { position: [ -2.763015284002938, -630.2151479701106, 577.524509114342 ], orientation: { x: -1.704794877102097, y: -1.9722372952861567, z: -0.4852079204210754 }, coor