@wandelbots/nova-js 2.1.4 → 3.0.0

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 (40) hide show
  1. package/README.md +29 -1
  2. package/dist/{chunk-6WCKJOFL.js → chunk-4FP7NTKS.js} +51 -1
  3. package/dist/chunk-4FP7NTKS.js.map +1 -0
  4. package/dist/{chunk-V3NJLR6P.js → chunk-DOFCSS2H.js} +1 -51
  5. package/dist/chunk-DOFCSS2H.js.map +1 -0
  6. package/dist/index.js +8 -8
  7. package/dist/lib/v1/index.js +6 -6
  8. package/dist/lib/v2/NovaCellAPIClient.d.ts +9 -11
  9. package/dist/lib/v2/NovaCellAPIClient.d.ts.map +1 -1
  10. package/dist/lib/v2/NovaClient.d.ts +0 -8
  11. package/dist/lib/v2/NovaClient.d.ts.map +1 -1
  12. package/dist/lib/v2/index.cjs +28 -771
  13. package/dist/lib/v2/index.cjs.map +1 -1
  14. package/dist/lib/v2/index.d.ts +0 -4
  15. package/dist/lib/v2/index.d.ts.map +1 -1
  16. package/dist/lib/v2/index.js +32 -764
  17. package/dist/lib/v2/index.js.map +1 -1
  18. package/dist/lib/v2/mock/MockNovaInstance.d.ts.map +1 -1
  19. package/package.json +2 -2
  20. package/src/lib/v2/NovaCellAPIClient.ts +22 -22
  21. package/src/lib/v2/NovaClient.ts +0 -28
  22. package/src/lib/v2/index.ts +0 -4
  23. package/src/lib/v2/mock/MockNovaInstance.ts +9 -32
  24. package/dist/chunk-6WCKJOFL.js.map +0 -1
  25. package/dist/chunk-V3NJLR6P.js.map +0 -1
  26. package/dist/lib/v2/ConnectedMotionGroup.d.ts +0 -41
  27. package/dist/lib/v2/ConnectedMotionGroup.d.ts.map +0 -1
  28. package/dist/lib/v2/JoggerConnection.d.ts +0 -53
  29. package/dist/lib/v2/JoggerConnection.d.ts.map +0 -1
  30. package/dist/lib/v2/MotionStreamConnection.d.ts +0 -25
  31. package/dist/lib/v2/MotionStreamConnection.d.ts.map +0 -1
  32. package/dist/lib/v2/ProgramStateConnection.d.ts +0 -53
  33. package/dist/lib/v2/ProgramStateConnection.d.ts.map +0 -1
  34. package/dist/lib/v2/motionStateUpdate.d.ts +0 -4
  35. package/dist/lib/v2/motionStateUpdate.d.ts.map +0 -1
  36. package/src/lib/v2/ConnectedMotionGroup.ts +0 -216
  37. package/src/lib/v2/JoggerConnection.ts +0 -207
  38. package/src/lib/v2/MotionStreamConnection.ts +0 -201
  39. package/src/lib/v2/ProgramStateConnection.ts +0 -249
  40. package/src/lib/v2/motionStateUpdate.ts +0 -55
@@ -1,249 +0,0 @@
1
- import { AxiosError } from "axios"
2
- import { makeAutoObservable, runInAction } from "mobx"
3
- import { AutoReconnectingWebsocket } from "../AutoReconnectingWebsocket"
4
- import { tryParseJson } from "../converters"
5
- import type { MotionStreamConnection } from "./MotionStreamConnection"
6
- import type { NovaClient } from "./NovaClient"
7
-
8
- export type ProgramRunnerLogEntry = {
9
- timestamp: number
10
- message: string
11
- level?: "warn" | "error"
12
- }
13
-
14
- export enum ProgramState {
15
- NotStarted = "not started",
16
- Running = "running",
17
- Stopped = "stopped",
18
- Failed = "failed",
19
- Completed = "completed",
20
- }
21
-
22
- export type CurrentProgram = {
23
- id?: string
24
- wandelscript?: string
25
- state?: ProgramState
26
- }
27
-
28
- type ProgramStateMessage = {
29
- type: string
30
- runner: {
31
- id: string
32
- state: ProgramState
33
- start_time?: number | null
34
- execution_time?: number | null
35
- }
36
- }
37
-
38
- /**
39
- * Interface for running Wandelscript programs on the Nova instance and
40
- * tracking their progress and output
41
- */
42
- export class ProgramStateConnection {
43
- currentProgram: CurrentProgram = {}
44
- logs: ProgramRunnerLogEntry[] = []
45
-
46
- executionState = "idle" as "idle" | "starting" | "executing" | "stopping"
47
- currentlyExecutingProgramRunnerId = null as string | null
48
-
49
- programStateSocket: AutoReconnectingWebsocket
50
-
51
- constructor(readonly nova: NovaClient) {
52
- makeAutoObservable(this, {}, { autoBind: true })
53
-
54
- this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`)
55
-
56
- this.programStateSocket.addEventListener("message", (ev) => {
57
- const msg = tryParseJson(ev.data)
58
-
59
- if (!msg) {
60
- console.error("Failed to parse program state message", ev.data)
61
- return
62
- }
63
- if (msg.type === "update") {
64
- this.handleProgramStateMessage(msg)
65
- }
66
- })
67
- }
68
-
69
- /** Handle a program state update from the backend */
70
- async handleProgramStateMessage(msg: ProgramStateMessage) {
71
- const { runner } = msg
72
-
73
- // Ignoring other programs for now
74
- // TODO - show if execution state is busy from another source
75
- if (runner.id !== this.currentlyExecutingProgramRunnerId) return
76
-
77
- if (runner.state === ProgramState.Failed) {
78
- try {
79
- const runnerState = await this.nova.api.program.getProgramRun(runner.id)
80
-
81
- // TODO - wandelengine should send print statements in real time over
82
- // websocket as well, rather than at the end
83
- const stdout = (runnerState as any).stdout
84
- if (stdout) {
85
- this.log(stdout)
86
- }
87
- this.logError(
88
- `Program runner ${runner.id} failed with error: ${runnerState.error}\n${runnerState.traceback}`,
89
- )
90
- } catch (err) {
91
- this.logError(
92
- `Failed to retrieve results for program ${runner.id}: ${err}`,
93
- )
94
- }
95
-
96
- this.currentProgram.state = ProgramState.Failed
97
-
98
- this.gotoIdleState()
99
- } else if (runner.state === ProgramState.Stopped) {
100
- try {
101
- const runnerState = await this.nova.api.program.getProgramRun(runner.id)
102
-
103
- const stdout = (runnerState as any).stdout
104
- if (stdout) {
105
- this.log(stdout)
106
- }
107
-
108
- this.currentProgram.state = ProgramState.Stopped
109
- this.log(`Program runner ${runner.id} stopped`)
110
- } catch (err) {
111
- this.logError(
112
- `Failed to retrieve results for program ${runner.id}: ${err}`,
113
- )
114
- }
115
-
116
- this.gotoIdleState()
117
- } else if (runner.state === ProgramState.Completed) {
118
- try {
119
- const runnerState = await this.nova.api.program.getProgramRun(runner.id)
120
-
121
- const stdout = (runnerState as any).stdout
122
- if (stdout) {
123
- this.log(stdout)
124
- }
125
- this.log(
126
- `Program runner ${runner.id} finished successfully in ${runner.execution_time?.toFixed(2)} seconds`,
127
- )
128
-
129
- this.currentProgram.state = ProgramState.Completed
130
- } catch (err) {
131
- this.logError(
132
- `Failed to retrieve results for program ${runner.id}: ${err}`,
133
- )
134
- }
135
-
136
- this.gotoIdleState()
137
- } else if (runner.state === ProgramState.Running) {
138
- this.currentProgram.state = ProgramState.Running
139
- this.log(`Program runner ${runner.id} now running`)
140
- } else if (runner.state !== ProgramState.NotStarted) {
141
- console.error(runner)
142
- this.logError(
143
- `Program runner ${runner.id} entered unexpected state: ${runner.state}`,
144
- )
145
- this.currentProgram.state = ProgramState.NotStarted
146
- this.gotoIdleState()
147
- }
148
- }
149
-
150
- /** Call when a program is no longer executing */
151
- gotoIdleState() {
152
- runInAction(() => {
153
- this.executionState = "idle"
154
- })
155
- this.currentlyExecutingProgramRunnerId = null
156
- }
157
-
158
- async executeProgram(
159
- wandelscript: string,
160
- initial_state?: Object,
161
- activeRobot?: MotionStreamConnection,
162
- ) {
163
- this.currentProgram = {
164
- wandelscript: wandelscript,
165
- state: ProgramState.NotStarted,
166
- }
167
-
168
- const { currentProgram: openProgram } = this
169
- if (!openProgram) return
170
- runInAction(() => {
171
- this.executionState = "starting"
172
- })
173
-
174
- // WOS-1539: Wandelengine parser currently breaks if there are empty lines with indentation
175
- const trimmedCode = openProgram.wandelscript!.replaceAll(/^\s*$/gm, "")
176
-
177
- try {
178
- const programRunnerRef = await this.nova.api.program.createProgramRun(
179
- {
180
- code: trimmedCode,
181
- initial_state: initial_state,
182
- default_robot: activeRobot?.wandelscriptIdentifier,
183
- } as any,
184
- {
185
- headers: {
186
- "Content-Type": "application/json",
187
- },
188
- },
189
- )
190
-
191
- this.log(`Created program runner ${programRunnerRef.id}"`)
192
- runInAction(() => {
193
- this.executionState = "executing"
194
- })
195
- this.currentlyExecutingProgramRunnerId = programRunnerRef.id
196
- } catch (error) {
197
- if (error instanceof AxiosError && error.response && error.request) {
198
- this.logError(
199
- `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`,
200
- )
201
- } else {
202
- this.logError(JSON.stringify(error))
203
- }
204
- runInAction(() => {
205
- this.executionState = "idle"
206
- })
207
- }
208
- }
209
-
210
- async stopProgram() {
211
- if (!this.currentlyExecutingProgramRunnerId) return
212
- runInAction(() => {
213
- this.executionState = "stopping"
214
- })
215
-
216
- try {
217
- await this.nova.api.program.stopProgramRun(
218
- this.currentlyExecutingProgramRunnerId,
219
- )
220
- } catch (err) {
221
- // Reactivate the stop button so user can try again
222
- runInAction(() => {
223
- this.executionState = "executing"
224
- })
225
- throw err
226
- }
227
- }
228
-
229
- reset() {
230
- this.currentProgram = {}
231
- }
232
-
233
- log(message: string) {
234
- console.log(message)
235
- this.logs.push({
236
- timestamp: Date.now(),
237
- message,
238
- })
239
- }
240
-
241
- logError(message: string) {
242
- console.log(message)
243
- this.logs.push({
244
- timestamp: Date.now(),
245
- message,
246
- level: "error",
247
- })
248
- }
249
- }
@@ -1,55 +0,0 @@
1
- import type { TcpPose } from "@wandelbots/nova-api/v2"
2
-
3
- export function jointValuesEqual(
4
- oldJointValues: number[],
5
- newJointValues: number[],
6
- changeDeltaThreshold: number,
7
- ): boolean {
8
- if (newJointValues.length !== oldJointValues.length) {
9
- return true
10
- }
11
-
12
- for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {
13
- if (
14
- Math.abs(newJointValues[jointIndex]! - oldJointValues[jointIndex]!) >
15
- changeDeltaThreshold
16
- ) {
17
- return false
18
- }
19
- }
20
-
21
- return true
22
- }
23
-
24
- export function tcpPoseEqual(
25
- oldTcp: TcpPose | undefined,
26
- newTcp: TcpPose | undefined,
27
- changeDeltaThreshold: number,
28
- ): boolean {
29
- // undefined -> defined (+reverse) transition
30
- if ((oldTcp === undefined && newTcp) || (oldTcp && newTcp === undefined)) {
31
- return false
32
- }
33
-
34
- // the typechecker cannot resolve states to "!= undefined" if "&&" is used
35
- if (oldTcp === undefined || newTcp === undefined) {
36
- return true
37
- }
38
-
39
- let changedDelta = 0
40
- changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0])
41
- changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1])
42
- changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2])
43
- changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0])
44
- changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1])
45
- changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2])
46
-
47
- if (changedDelta > changeDeltaThreshold) {
48
- return false
49
- }
50
-
51
- return (
52
- oldTcp.coordinate_system === newTcp.coordinate_system &&
53
- oldTcp.tcp === newTcp.tcp
54
- )
55
- }