@wandelbots/wandelbots-js-react-components 2.54.5-pr.feat-upgrade-jogging-to-v2.404.a6b053a → 2.54.5-pr.feat-upgrade-jogging-to-v2.404.6f841e7

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=JoggerConnection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JoggerConnection.test.d.ts","sourceRoot":"","sources":["../../src/lib/JoggerConnection.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wandelbots/wandelbots-js-react-components",
3
- "version": "2.54.5-pr.feat-upgrade-jogging-to-v2.404.a6b053a",
3
+ "version": "2.54.5-pr.feat-upgrade-jogging-to-v2.404.6f841e7",
4
4
  "description": "React UI toolkit for building applications on top of the Wandelbots platform",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -70,7 +70,7 @@
70
70
  "@types/react": "^19.1.8",
71
71
  "@types/three": "^0.174.0",
72
72
  "@vitejs/plugin-react": "^4.3.4",
73
- "@wandelbots/nova-js": "3.3.0",
73
+ "@wandelbots/nova-js": "3.3.1",
74
74
  "add": "^2.0.6",
75
75
  "eslint-plugin-storybook": "^10.0.1",
76
76
  "glob": "^11.0.1",
@@ -1,6 +1,10 @@
1
1
  import { AxiosError } from "axios"
2
2
  import { tryStringifyJson } from "./converters"
3
3
 
4
+ // Please note: These helper functions also exist in nova.js
5
+ // (with slightly different formatting), and will be unified
6
+ // at some point in the future.
7
+
4
8
  export function delay(ms: number) {
5
9
  return new Promise((resolve) => setTimeout(resolve, ms))
6
10
  }
@@ -0,0 +1,120 @@
1
+ import { NovaClient } from "@wandelbots/nova-js/v2"
2
+ import { expect, test, vi } from "vitest"
3
+ import { delay } from "../components/utils/errorHandling"
4
+ import { JoggerConnection } from "./JoggerConnection"
5
+ import { jointValuesEqual } from "./motionStateUpdate"
6
+
7
+ // Notes:
8
+ // - In mock mode, no joint comparison takes place (always successful)
9
+ // - To test with real (virtual or physical) instance, set an INSTANCE_URL
10
+
11
+ const INSTANCE_URL = undefined // This could be read from ENV in future
12
+ const MOCK = !INSTANCE_URL
13
+
14
+ test("jog a robot somewhat", async () => {
15
+ const nova = new NovaClient({
16
+ instanceUrl: MOCK ? "https://mock.example.com" : INSTANCE_URL,
17
+ })
18
+
19
+ // Find a virtual robot we can jog
20
+ const controllerNames = await nova.api.controller.listRobotControllers()
21
+ const firstControllerName = controllerNames[0]
22
+
23
+ if (!firstControllerName) {
24
+ throw new Error("No robot controllers found on instance")
25
+ }
26
+
27
+ const controllerConfig =
28
+ await nova.api.controller.getRobotController(firstControllerName)
29
+ const controllerState =
30
+ await nova.api.controller.getCurrentRobotControllerState(
31
+ firstControllerName,
32
+ )
33
+ console.log("verify, got controller config and state", {
34
+ controllerConfig,
35
+ controllerState,
36
+ })
37
+
38
+ if (!controllerConfig || !controllerState) {
39
+ throw new Error(
40
+ `Could not get controller config and state for ${firstControllerName}`,
41
+ )
42
+ }
43
+
44
+ if (controllerConfig.configuration.kind !== "VirtualController") {
45
+ throw new Error(
46
+ `Controller ${firstControllerName} is not a VirtualController, it's a ${controllerConfig.configuration.kind}`,
47
+ )
48
+ }
49
+
50
+ if (controllerState.last_error?.[0]) {
51
+ throw new Error(
52
+ `Controller ${firstControllerName} has error: ${controllerState.last_error[0]}`,
53
+ )
54
+ }
55
+
56
+ const virtualMotionGroup = controllerState.motion_groups[0]
57
+
58
+ if (!virtualMotionGroup) {
59
+ throw new Error(
60
+ `Could not find a joggable motion group. Saw controller: ${firstControllerName}`,
61
+ )
62
+ }
63
+
64
+ const jogger = await JoggerConnection.open(
65
+ nova,
66
+ virtualMotionGroup.motion_group,
67
+ )
68
+
69
+ function getJoints() {
70
+ return jogger.motionStream.rapidlyChangingMotionState.joint_position
71
+ }
72
+
73
+ let joints = getJoints()
74
+
75
+ await jogger.setJoggingMode("jogging")
76
+
77
+ await jogger.rotateJoints({
78
+ joint: 0,
79
+ direction: "+",
80
+ velocityRadsPerSec: 0.1,
81
+ })
82
+
83
+ await delay(500)
84
+ await jogger.stop()
85
+
86
+ if (!MOCK) {
87
+ // Only verify joint movement in non-mock mode
88
+ await expect.poll(() => getJoints()[0]).toBeGreaterThan(joints[0] + 0.01)
89
+ expect(getJoints()[1]).toBeCloseTo(joints[1])
90
+ }
91
+
92
+ joints = getJoints()
93
+
94
+ await jogger.rotateJoints({
95
+ joint: 0,
96
+ direction: "-",
97
+ velocityRadsPerSec: 0.1,
98
+ })
99
+ await delay(500)
100
+ await jogger.stop()
101
+
102
+ await expect.poll(() => getJoints()[0]).toBeLessThan(joints[0] + 0.01)
103
+ expect(getJoints()[1]).toBeCloseTo(joints[1])
104
+
105
+ if (MOCK) {
106
+ return
107
+ }
108
+
109
+ // Wait for motion to stop
110
+ await vi.waitUntil(
111
+ async () => {
112
+ const joints = getJoints()
113
+ await jogger.motionStream.motionStateSocket.nextMessage()
114
+ return jointValuesEqual(joints, getJoints(), 0.0001)
115
+ },
116
+ {
117
+ timeout: 3000,
118
+ },
119
+ )
120
+ })